diff --git a/ActiveAnimation.cs b/ActiveAnimation.cs new file mode 100644 index 00000000..69e84663 --- /dev/null +++ b/ActiveAnimation.cs @@ -0,0 +1,354 @@ +using AnimationOrTween; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Internal/Active Animation")] +public class ActiveAnimation : MonoBehaviour +{ + public static ActiveAnimation current; + + public List onFinished = new List(); + + [HideInInspector] + public GameObject eventReceiver; + + [HideInInspector] + public string callWhenFinished; + + private Animation mAnim; + + private Direction mLastDirection; + + private Direction mDisableDirection; + + private bool mNotify; + + private Animator mAnimator; + + private string mClip = string.Empty; + + private float playbackTime => Mathf.Clamp01(mAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime); + + public bool isPlaying + { + get + { + if (mAnim == null) + { + if (mAnimator != null) + { + if (mLastDirection == Direction.Reverse) + { + if (playbackTime == 0f) + { + return false; + } + } + else if (playbackTime == 1f) + { + return false; + } + return true; + } + return false; + } + foreach (AnimationState item in mAnim) + { + if (mAnim.IsPlaying(item.name)) + { + if (mLastDirection == Direction.Forward) + { + if (item.time < item.length) + { + return true; + } + } + else + { + if (mLastDirection != Direction.Reverse) + { + return true; + } + if (item.time > 0f) + { + return true; + } + } + } + } + return false; + } + } + + public void Finish() + { + if (mAnim != null) + { + foreach (AnimationState item in mAnim) + { + if (mLastDirection == Direction.Forward) + { + item.time = item.length; + } + else if (mLastDirection == Direction.Reverse) + { + item.time = 0f; + } + } + mAnim.Sample(); + } + else if (mAnimator != null) + { + mAnimator.Play(mClip, 0, (mLastDirection != Direction.Forward) ? 0f : 1f); + } + } + + public void Reset() + { + if (mAnim != null) + { + foreach (AnimationState item in mAnim) + { + if (mLastDirection == Direction.Reverse) + { + item.time = item.length; + } + else if (mLastDirection == Direction.Forward) + { + item.time = 0f; + } + } + } + else if (mAnimator != null) + { + mAnimator.Play(mClip, 0, (mLastDirection != Direction.Reverse) ? 0f : 1f); + } + } + + private void Start() + { + if (eventReceiver != null && EventDelegate.IsValid(onFinished)) + { + eventReceiver = null; + callWhenFinished = null; + } + } + + private void Update() + { + float deltaTime = RealTime.deltaTime; + if (deltaTime != 0f) + { + if (mAnimator != null) + { + mAnimator.Update((mLastDirection != Direction.Reverse) ? deltaTime : (0f - deltaTime)); + if (isPlaying) + { + return; + } + mAnimator.enabled = false; + base.enabled = false; + } + else + { + if (!(mAnim != null)) + { + base.enabled = false; + return; + } + bool flag = false; + foreach (AnimationState item in mAnim) + { + if (mAnim.IsPlaying(item.name)) + { + float num = item.speed * deltaTime; + item.time += num; + if (num < 0f) + { + if (item.time > 0f) + { + flag = true; + } + else + { + item.time = 0f; + } + } + else if (item.time < item.length) + { + flag = true; + } + else + { + item.time = item.length; + } + } + } + mAnim.Sample(); + if (flag) + { + return; + } + base.enabled = false; + } + if (mNotify) + { + mNotify = false; + if (current == null) + { + current = this; + EventDelegate.Execute(onFinished); + if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished)) + { + eventReceiver.SendMessage(callWhenFinished, SendMessageOptions.DontRequireReceiver); + } + current = null; + } + if (mDisableDirection != 0 && mLastDirection == mDisableDirection) + { + NGUITools.SetActive(base.gameObject, state: false); + } + } + } + } + + private void Play(string clipName, Direction playDirection) + { + if (playDirection == Direction.Toggle) + { + playDirection = ((mLastDirection != Direction.Forward) ? Direction.Forward : Direction.Reverse); + } + if (mAnim != null) + { + base.enabled = true; + mAnim.enabled = false; + if (string.IsNullOrEmpty(clipName)) + { + if (!mAnim.isPlaying) + { + mAnim.Play(); + } + } + else if (!mAnim.IsPlaying(clipName)) + { + mAnim.Play(clipName); + } + foreach (AnimationState item in mAnim) + { + if (string.IsNullOrEmpty(clipName) || item.name == clipName) + { + float num = Mathf.Abs(item.speed); + item.speed = num * (float)playDirection; + if (playDirection == Direction.Reverse && item.time == 0f) + { + item.time = item.length; + } + else if (playDirection == Direction.Forward && item.time == item.length) + { + item.time = 0f; + } + } + } + mLastDirection = playDirection; + mNotify = true; + mAnim.Sample(); + } + else if (mAnimator != null) + { + if (base.enabled && isPlaying && mClip == clipName) + { + mLastDirection = playDirection; + } + else + { + base.enabled = true; + mNotify = true; + mLastDirection = playDirection; + mClip = clipName; + mAnimator.Play(mClip, 0, (playDirection != Direction.Forward) ? 1f : 0f); + } + } + } + + public static ActiveAnimation Play(Animation anim, string clipName, Direction playDirection, EnableCondition enableBeforePlay, DisableCondition disableCondition) + { + if (!NGUITools.GetActive(anim.gameObject)) + { + if (enableBeforePlay != EnableCondition.EnableThenPlay) + { + return null; + } + NGUITools.SetActive(anim.gameObject, state: true); + UIPanel[] componentsInChildren = anim.gameObject.GetComponentsInChildren(); + int i = 0; + for (int num = componentsInChildren.Length; i < num; i++) + { + componentsInChildren[i].Refresh(); + } + } + ActiveAnimation activeAnimation = anim.GetComponent(); + if (activeAnimation == null) + { + activeAnimation = anim.gameObject.AddComponent(); + } + activeAnimation.mAnim = anim; + activeAnimation.mDisableDirection = (Direction)disableCondition; + activeAnimation.onFinished.Clear(); + activeAnimation.Play(clipName, playDirection); + if (activeAnimation.mAnim != null) + { + activeAnimation.mAnim.Sample(); + } + else if (activeAnimation.mAnimator != null) + { + activeAnimation.mAnimator.Update(0f); + } + return activeAnimation; + } + + public static ActiveAnimation Play(Animation anim, string clipName, Direction playDirection) + { + return Play(anim, clipName, playDirection, EnableCondition.DoNothing, DisableCondition.DoNotDisable); + } + + public static ActiveAnimation Play(Animation anim, Direction playDirection) + { + return Play(anim, null, playDirection, EnableCondition.DoNothing, DisableCondition.DoNotDisable); + } + + public static ActiveAnimation Play(Animator anim, string clipName, Direction playDirection, EnableCondition enableBeforePlay, DisableCondition disableCondition) + { + if (enableBeforePlay != EnableCondition.IgnoreDisabledState && !NGUITools.GetActive(anim.gameObject)) + { + if (enableBeforePlay != EnableCondition.EnableThenPlay) + { + return null; + } + NGUITools.SetActive(anim.gameObject, state: true); + UIPanel[] componentsInChildren = anim.gameObject.GetComponentsInChildren(); + int i = 0; + for (int num = componentsInChildren.Length; i < num; i++) + { + componentsInChildren[i].Refresh(); + } + } + ActiveAnimation activeAnimation = anim.GetComponent(); + if (activeAnimation == null) + { + activeAnimation = anim.gameObject.AddComponent(); + } + activeAnimation.mAnimator = anim; + activeAnimation.mDisableDirection = (Direction)disableCondition; + activeAnimation.onFinished.Clear(); + activeAnimation.Play(clipName, playDirection); + if (activeAnimation.mAnim != null) + { + activeAnimation.mAnim.Sample(); + } + else if (activeAnimation.mAnimator != null) + { + activeAnimation.mAnimator.Update(0f); + } + return activeAnimation; + } +} diff --git a/AnimatedAlpha.cs b/AnimatedAlpha.cs new file mode 100644 index 00000000..f9233f1c --- /dev/null +++ b/AnimatedAlpha.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +[ExecuteInEditMode] +public class AnimatedAlpha : MonoBehaviour +{ + [Range(0f, 1f)] + public float alpha = 1f; + + private UIWidget mWidget; + + private UIPanel mPanel; + + private void OnEnable() + { + mWidget = GetComponent(); + mPanel = GetComponent(); + LateUpdate(); + } + + private void LateUpdate() + { + if (mWidget != null) + { + mWidget.alpha = alpha; + } + if (mPanel != null) + { + mPanel.alpha = alpha; + } + } +} diff --git a/AnimatedColor.cs b/AnimatedColor.cs new file mode 100644 index 00000000..d1494432 --- /dev/null +++ b/AnimatedColor.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +[ExecuteInEditMode] +[RequireComponent(typeof(UIWidget))] +public class AnimatedColor : MonoBehaviour +{ + public Color color = Color.white; + + private UIWidget mWidget; + + private void OnEnable() + { + mWidget = GetComponent(); + LateUpdate(); + } + + private void LateUpdate() + { + mWidget.color = color; + } +} diff --git a/AnimatedWidget.cs b/AnimatedWidget.cs new file mode 100644 index 00000000..73eb6bcf --- /dev/null +++ b/AnimatedWidget.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +[ExecuteInEditMode] +public class AnimatedWidget : MonoBehaviour +{ + public float width = 1f; + + public float height = 1f; + + private UIWidget mWidget; + + private void OnEnable() + { + mWidget = GetComponent(); + LateUpdate(); + } + + private void LateUpdate() + { + if (mWidget != null) + { + mWidget.width = Mathf.RoundToInt(width); + mWidget.height = Mathf.RoundToInt(height); + } + } +} diff --git a/AnimationOrTween/Direction.cs b/AnimationOrTween/Direction.cs new file mode 100644 index 00000000..cb84480b --- /dev/null +++ b/AnimationOrTween/Direction.cs @@ -0,0 +1,9 @@ +namespace AnimationOrTween +{ + public enum Direction + { + Reverse = -1, + Toggle, + Forward + } +} diff --git a/AnimationOrTween/DisableCondition.cs b/AnimationOrTween/DisableCondition.cs new file mode 100644 index 00000000..ec3c8e48 --- /dev/null +++ b/AnimationOrTween/DisableCondition.cs @@ -0,0 +1,9 @@ +namespace AnimationOrTween +{ + public enum DisableCondition + { + DisableAfterReverse = -1, + DoNotDisable, + DisableAfterForward + } +} diff --git a/AnimationOrTween/EnableCondition.cs b/AnimationOrTween/EnableCondition.cs new file mode 100644 index 00000000..624e1c8f --- /dev/null +++ b/AnimationOrTween/EnableCondition.cs @@ -0,0 +1,9 @@ +namespace AnimationOrTween +{ + public enum EnableCondition + { + DoNothing, + EnableThenPlay, + IgnoreDisabledState + } +} diff --git a/AnimationOrTween/Trigger.cs b/AnimationOrTween/Trigger.cs new file mode 100644 index 00000000..dc00acde --- /dev/null +++ b/AnimationOrTween/Trigger.cs @@ -0,0 +1,20 @@ +namespace AnimationOrTween +{ + public enum Trigger + { + OnClick, + OnHover, + OnPress, + OnHoverTrue, + OnHoverFalse, + OnPressTrue, + OnPressFalse, + OnActivate, + OnActivateTrue, + OnActivateFalse, + OnDoubleClick, + OnSelect, + OnSelectTrue, + OnSelectFalse + } +} diff --git a/AntlrTest/bgitestLexer.cs b/AntlrTest/bgitestLexer.cs new file mode 100644 index 00000000..d2fda832 --- /dev/null +++ b/AntlrTest/bgitestLexer.cs @@ -0,0 +1,1381 @@ +using Antlr.Runtime; +using System; +using System.CodeDom.Compiler; + +namespace AntlrTest +{ + [CLSCompliant(false)] + [GeneratedCode("ANTLR", "3.5.0.1")] + public class bgitestLexer : Lexer + { + private class DFA9 : DFA + { + private const string DFA9_eotS = "\u0002\uffff\u0005\a\u0001\uffff\u0001&\u0001\uffff\u0001(\u0004\uffff\u0001*\u0001,\u0001.\v\uffff\u00010\u00013\u00016\u0004\a\u0001;\u0001\a\u0011\uffff\u0004\a\u0001\uffff\u0002\a\u0001C\u0001D\u0001E\u0001\a\u0001G\u0003\uffff\u0001\a\u0001\uffff\u0001\a\u0001J\u0001\uffff"; + + private const string DFA9_eofS = "K\uffff"; + + private const string DFA9_minS = "\u0001\t\u0001\uffff\u0001A\u0001U\u0001R\u0001l\u0001f\u0001\uffff\u00010\u0001\uffff\u0001*\u0004\uffff\u0001=\u0001|\u0001&\v\uffff\u0002=\u0001<\u0002L\u0001U\u0001s\u00010\u0001c\u0011\uffff\u0001S\u0001L\u0001E\u0001e\u0001\uffff\u0001l\u0001E\u00030\u0001u\u00010\u0003\uffff\u0001d\u0001\uffff\u0001e\u00010\u0001\uffff"; + + private const string DFA9_maxS = "\u0001}\u0001\uffff\u0001A\u0001U\u0001R\u0001l\u0001n\u0001\uffff\u00019\u0001\uffff\u0001/\u0004\uffff\u0001=\u0001|\u0001&\v\uffff\u0001=\u0001>\u0001=\u0002L\u0001U\u0001s\u0001z\u0001c\u0011\uffff\u0001S\u0001L\u0001E\u0001e\u0001\uffff\u0001l\u0001E\u0003z\u0001u\u0001z\u0003\uffff\u0001d\u0001\uffff\u0001e\u0001z\u0001\uffff"; + + private const string DFA9_acceptS = "\u0001\uffff\u0001\u0001\u0005\uffff\u0001\b\u0001\uffff\u0001\t\u0001\uffff\u0001\v\u0001\f\u0001\r\u0001\u000e\u0003\uffff\u0001\u0014\u0001\u0015\u0001\u0016\u0001\u0017\u0001\u0018\u0001\u0019\u0001\u001a\u0001\u001b\u0001\u001c\u0001\u001e\u0001 \t\uffff\u0001\u001d\u0001\n\u0001\u001f\u0001#\u0001\u000f\u0001\u0012\u0001\u0010\u0001\u0013\u0001\u0011\u0001!\u0001\"\u0001'\u0001)\u0001$\u0001&\u0001(\u0001%\u0004\uffff\u0001\u0006\a\uffff\u0001\u0003\u0001\u0004\u0001\u0005\u0001\uffff\u0001\u0002\u0002\uffff\u0001\a"; + + private const string DFA9_specialS = "K\uffff}>"; + + private static readonly string[] DFA9_transitionS; + + private static readonly short[] DFA9_eot; + + private static readonly short[] DFA9_eof; + + private static readonly char[] DFA9_min; + + private static readonly char[] DFA9_max; + + private static readonly short[] DFA9_accept; + + private static readonly short[] DFA9_special; + + private static readonly short[][] DFA9_transition; + + public override string Description => "1:1: Tokens : ( T__58 | T__59 | T__60 | T__61 | T__62 | T__63 | T__64 | ID | INT | COMMENT | WS | STRING | CHAR | COMMA | NOT | BWOR | BWAND | OR | AND | RPAREN | LPAREN | HASH | SEMICOLON | RSQ | LSQ | LCURL | RCURL | PLUS | MINUS | TIMES | DIVIDE | MOD | EQ | ASSIGN | NEQ | GTHAN | LTHAN | LEQ | GEQ | SHIFT_LEFT | SHIFT_RIGHT );"; + + public DFA9(BaseRecognizer recognizer) + { + base.recognizer = recognizer; + decisionNumber = 9; + eot = DFA9_eot; + eof = DFA9_eof; + min = DFA9_min; + max = DFA9_max; + accept = DFA9_accept; + special = DFA9_special; + transition = DFA9_transition; + } + + static DFA9() + { + DFA9_transitionS = new string[75] + { + "\u0002\v\u0002\uffff\u0001\v\u0012\uffff\u0001\v\u0001\u000f\u0001\f\u0001\u0014\u0001\uffff\u0001\u001c\u0001\u0011\u0001\r\u0001\u0013\u0001\u0012\u0001\u001b\u0001\u001a\u0001\u000e\u0001\b\u0001\u0001\u0001\n\n\t\u0001\uffff\u0001\u0015\u0001\u001f\u0001\u001d\u0001\u001e\u0002\uffff\u0005\a\u0001\u0002\a\a\u0001\u0003\u0005\a\u0001\u0004\u0006\a\u0001\u0017\u0001\uffff\u0001\u0016\u0001\uffff\u0001\a\u0001\uffff\u0004\a\u0001\u0005\u0003\a\u0001\u0006\u0011\a\u0001\u0018\u0001\u0010\u0001\u0019", + string.Empty, + "\u0001 ", + "\u0001!", + "\u0001\"", + "\u0001#", + "\u0001$\a\uffff\u0001%", + string.Empty, + "\n\t", + string.Empty, + "\u0001'\u0004\uffff\u0001'", + string.Empty, + string.Empty, + string.Empty, + string.Empty, + "\u0001)", + "\u0001+", + "\u0001-", + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + "\u0001/", + "\u00011\u00012", + "\u00015\u00014", + "\u00017", + "\u00018", + "\u00019", + "\u0001:", + "\n\a\a\uffff\u001a\a\u0004\uffff\u0001\a\u0001\uffff\u001a\a", + "\u0001<", + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + "\u0001=", + "\u0001>", + "\u0001?", + "\u0001@", + string.Empty, + "\u0001A", + "\u0001B", + "\n\a\a\uffff\u001a\a\u0004\uffff\u0001\a\u0001\uffff\u001a\a", + "\n\a\a\uffff\u001a\a\u0004\uffff\u0001\a\u0001\uffff\u001a\a", + "\n\a\a\uffff\u001a\a\u0004\uffff\u0001\a\u0001\uffff\u001a\a", + "\u0001F", + "\n\a\a\uffff\u001a\a\u0004\uffff\u0001\a\u0001\uffff\u001a\a", + string.Empty, + string.Empty, + string.Empty, + "\u0001H", + string.Empty, + "\u0001I", + "\n\a\a\uffff\u001a\a\u0004\uffff\u0001\a\u0001\uffff\u001a\a", + string.Empty + }; + DFA9_eot = DFA.UnpackEncodedString("\u0002\uffff\u0005\a\u0001\uffff\u0001&\u0001\uffff\u0001(\u0004\uffff\u0001*\u0001,\u0001.\v\uffff\u00010\u00013\u00016\u0004\a\u0001;\u0001\a\u0011\uffff\u0004\a\u0001\uffff\u0002\a\u0001C\u0001D\u0001E\u0001\a\u0001G\u0003\uffff\u0001\a\u0001\uffff\u0001\a\u0001J\u0001\uffff"); + DFA9_eof = DFA.UnpackEncodedString("K\uffff"); + DFA9_min = DFA.UnpackEncodedStringToUnsignedChars("\u0001\t\u0001\uffff\u0001A\u0001U\u0001R\u0001l\u0001f\u0001\uffff\u00010\u0001\uffff\u0001*\u0004\uffff\u0001=\u0001|\u0001&\v\uffff\u0002=\u0001<\u0002L\u0001U\u0001s\u00010\u0001c\u0011\uffff\u0001S\u0001L\u0001E\u0001e\u0001\uffff\u0001l\u0001E\u00030\u0001u\u00010\u0003\uffff\u0001d\u0001\uffff\u0001e\u00010\u0001\uffff"); + DFA9_max = DFA.UnpackEncodedStringToUnsignedChars("\u0001}\u0001\uffff\u0001A\u0001U\u0001R\u0001l\u0001n\u0001\uffff\u00019\u0001\uffff\u0001/\u0004\uffff\u0001=\u0001|\u0001&\v\uffff\u0001=\u0001>\u0001=\u0002L\u0001U\u0001s\u0001z\u0001c\u0011\uffff\u0001S\u0001L\u0001E\u0001e\u0001\uffff\u0001l\u0001E\u0003z\u0001u\u0001z\u0003\uffff\u0001d\u0001\uffff\u0001e\u0001z\u0001\uffff"); + DFA9_accept = DFA.UnpackEncodedString("\u0001\uffff\u0001\u0001\u0005\uffff\u0001\b\u0001\uffff\u0001\t\u0001\uffff\u0001\v\u0001\f\u0001\r\u0001\u000e\u0003\uffff\u0001\u0014\u0001\u0015\u0001\u0016\u0001\u0017\u0001\u0018\u0001\u0019\u0001\u001a\u0001\u001b\u0001\u001c\u0001\u001e\u0001 \t\uffff\u0001\u001d\u0001\n\u0001\u001f\u0001#\u0001\u000f\u0001\u0012\u0001\u0010\u0001\u0013\u0001\u0011\u0001!\u0001\"\u0001'\u0001)\u0001$\u0001&\u0001(\u0001%\u0004\uffff\u0001\u0006\a\uffff\u0001\u0003\u0001\u0004\u0001\u0005\u0001\uffff\u0001\u0002\u0002\uffff\u0001\a"); + DFA9_special = DFA.UnpackEncodedString("K\uffff}>"); + int num = DFA9_transitionS.Length; + DFA9_transition = new short[num][]; + for (int i = 0; i < num; i++) + { + DFA9_transition[i] = DFA.UnpackEncodedString(DFA9_transitionS[i]); + } + } + + public override void Error(NoViableAltException nvae) + { + } + } + + public const int EOF = -1; + + public const int AND = 4; + + public const int ASSIGN = 5; + + public const int BLOCK = 6; + + public const int BWAND = 7; + + public const int BWOR = 8; + + public const int CHAR = 9; + + public const int COMMA = 10; + + public const int COMMENT = 11; + + public const int DIVIDE = 12; + + public const int ELSE = 13; + + public const int EQ = 14; + + public const int FALSE = 15; + + public const int GEQ = 16; + + public const int GTHAN = 17; + + public const int HASH = 18; + + public const int ID = 19; + + public const int IF = 20; + + public const int INCLUDE = 21; + + public const int INDEX = 22; + + public const int INT = 23; + + public const int LCURL = 24; + + public const int LEQ = 25; + + public const int LPAREN = 26; + + public const int LSQ = 27; + + public const int LTHAN = 28; + + public const int MEMBER = 29; + + public const int MINUS = 30; + + public const int MOD = 31; + + public const int NEQ = 32; + + public const int NOT = 33; + + public const int OPERATION = 34; + + public const int OR = 35; + + public const int PARAMETERS = 36; + + public const int PLUS = 37; + + public const int RCURL = 38; + + public const int RPAREN = 39; + + public const int RSQ = 40; + + public const int SEMICOLON = 41; + + public const int SHIFT_LEFT = 42; + + public const int SHIFT_RIGHT = 43; + + public const int STRING = 44; + + public const int THEN = 45; + + public const int TIMES = 46; + + public const int TRUE = 47; + + public const int TYPEBOOL = 48; + + public const int TYPEFUNCTION = 49; + + public const int TYPEINT = 50; + + public const int TYPEMATH = 51; + + public const int TYPENULL = 52; + + public const int TYPESTRING = 53; + + public const int TYPEVARIABLE = 54; + + public const int VAR = 55; + + public const int VARDECL = 56; + + public const int WS = 57; + + public const int T__58 = 58; + + public const int T__59 = 59; + + public const int T__60 = 60; + + public const int T__61 = 61; + + public const int T__62 = 62; + + public const int T__63 = 63; + + public const int T__64 = 64; + + private DFA9 dfa9; + + public override string GrammarFileName => "D:\\Projects\\d2bvsdd\\Assets\\Scripts\\Editor\\BGICompiler\\Grammar\\bgitest.g"; + + public bgitestLexer() + { + } + + public bgitestLexer(ICharStream input) + : this(input, new RecognizerSharedState()) + { + } + + public bgitestLexer(ICharStream input, RecognizerSharedState state) + : base(input, state) + { + } + + [GrammarRule("T__58")] + private void mT__58() + { + try + { + int type = 58; + int channel = 0; + Match(46); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("T__59")] + private void mT__59() + { + try + { + int type = 59; + int channel = 0; + Match("FALSE"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("T__60")] + private void mT__60() + { + try + { + int type = 60; + int channel = 0; + Match("NULL"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("T__61")] + private void mT__61() + { + try + { + int type = 61; + int channel = 0; + Match("TRUE"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("T__62")] + private void mT__62() + { + try + { + int type = 62; + int channel = 0; + Match("else"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("T__63")] + private void mT__63() + { + try + { + int type = 63; + int channel = 0; + Match("if"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("T__64")] + private void mT__64() + { + try + { + int type = 64; + int channel = 0; + Match("include"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("ID")] + private void mID() + { + try + { + int type = 19; + int channel = 0; + if ((input.LA(1) < 65 || input.LA(1) > 90) && input.LA(1) != 95 && (input.LA(1) < 97 || input.LA(1) > 122)) + { + MismatchedSetException ex = new MismatchedSetException(null, input); + Recover(ex); + throw ex; + } + input.Consume(); + try + { + while (true) + { + int num = 2; + try + { + int num2 = input.LA(1); + if ((num2 >= 48 && num2 <= 57) || (num2 >= 65 && num2 <= 90) || num2 == 95 || (num2 >= 97 && num2 <= 122)) + { + num = 1; + } + } + finally + { + } + int num3 = num; + if (num3 != 1) + { + break; + } + input.Consume(); + } + } + finally + { + } + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("INT")] + private void mINT() + { + try + { + int type = 23; + int channel = 0; + int num = 2; + try + { + try + { + int num2 = input.LA(1); + if (num2 == 45) + { + num = 1; + } + } + finally + { + } + int num3 = num; + if (num3 == 1) + { + Match(45); + } + } + finally + { + } + int num4 = 0; + try + { + while (true) + { + int num5 = 2; + try + { + int num6 = input.LA(1); + if (num6 >= 48 && num6 <= 57) + { + num5 = 1; + } + } + finally + { + } + int num3 = num5; + if (num3 != 1) + { + break; + } + input.Consume(); + num4++; + } + if (num4 < 1) + { + EarlyExitException ex = new EarlyExitException(3, input); + throw ex; + } + } + finally + { + } + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("COMMENT")] + private void mCOMMENT() + { + try + { + int type = 11; + int channel = 0; + int num = 2; + try + { + int num2 = input.LA(1); + if (num2 != 47) + { + NoViableAltException ex = new NoViableAltException(string.Empty, 7, 0, input, 1); + throw ex; + } + switch (input.LA(2)) + { + case 47: + num = 1; + break; + case 42: + num = 2; + break; + default: + { + NoViableAltException ex2 = new NoViableAltException(string.Empty, 7, 1, input, 2); + throw ex2; + } + } + } + finally + { + } + switch (num) + { + case 1: + { + Match("//"); + try + { + while (true) + { + int num7 = 2; + try + { + int num8 = input.LA(1); + if ((num8 >= 0 && num8 <= 9) || (num8 >= 11 && num8 <= 12) || (num8 >= 14 && num8 <= 65535)) + { + num7 = 1; + } + } + finally + { + } + int num6 = num7; + if (num6 != 1) + { + break; + } + input.Consume(); + } + } + finally + { + } + int num9 = 2; + try + { + try + { + int num10 = input.LA(1); + if (num10 == 13) + { + num9 = 1; + } + } + finally + { + } + int num6 = num9; + if (num6 == 1) + { + Match(13); + } + } + finally + { + } + Match(10); + Skip(); + break; + } + case 2: + Match("/*"); + try + { + while (true) + { + int num3 = 2; + try + { + int num4 = input.LA(1); + if (num4 == 42) + { + int num5 = input.LA(2); + if (num5 == 47) + { + num3 = 2; + } + else if ((num5 >= 0 && num5 <= 46) || (num5 >= 48 && num5 <= 65535)) + { + num3 = 1; + } + } + else if ((num4 >= 0 && num4 <= 41) || (num4 >= 43 && num4 <= 65535)) + { + num3 = 1; + } + } + finally + { + } + int num6 = num3; + if (num6 != 1) + { + break; + } + MatchAny(); + } + } + finally + { + } + Match("*/"); + Skip(); + break; + } + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("WS")] + private void mWS() + { + try + { + int type = 57; + int channel = 0; + if ((input.LA(1) < 9 || input.LA(1) > 10) && input.LA(1) != 13 && input.LA(1) != 32) + { + MismatchedSetException ex = new MismatchedSetException(null, input); + Recover(ex); + throw ex; + } + input.Consume(); + Skip(); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("STRING")] + private void mSTRING() + { + try + { + int type = 44; + int channel = 0; + Match(34); + try + { + while (true) + { + int num = 3; + try + { + int num2 = input.LA(1); + if (num2 == 92) + { + int num3 = input.LA(2); + if (num3 == 34) + { + int num4 = input.LA(3); + num = ((num4 >= 0 && num4 <= 65535) ? 1 : 2); + } + else if ((num3 >= 0 && num3 <= 33) || (num3 >= 35 && num3 <= 65535)) + { + num = 2; + } + } + else if ((num2 >= 0 && num2 <= 33) || (num2 >= 35 && num2 <= 91) || (num2 >= 93 && num2 <= 65535)) + { + num = 2; + } + } + finally + { + } + switch (num) + { + case 1: + Match("\\\""); + continue; + case 2: + input.Consume(); + continue; + } + break; + } + } + finally + { + } + Match(34); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("CHAR")] + private void mCHAR() + { + try + { + int type = 9; + int channel = 0; + Match(39); + if ((input.LA(1) < 0 || input.LA(1) > 38) && (input.LA(1) < 40 || input.LA(1) > 91) && (input.LA(1) < 93 || input.LA(1) > 65535)) + { + MismatchedSetException ex = new MismatchedSetException(null, input); + Recover(ex); + throw ex; + } + input.Consume(); + Match(39); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("COMMA")] + private void mCOMMA() + { + try + { + int type = 10; + int channel = 0; + Match(44); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("NOT")] + private void mNOT() + { + try + { + int type = 33; + int channel = 0; + Match(33); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("BWOR")] + private void mBWOR() + { + try + { + int type = 8; + int channel = 0; + Match(124); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("BWAND")] + private void mBWAND() + { + try + { + int type = 7; + int channel = 0; + Match(38); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("OR")] + private void mOR() + { + try + { + int type = 35; + int channel = 0; + Match("||"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("AND")] + private void mAND() + { + try + { + int type = 4; + int channel = 0; + Match("&&"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("RPAREN")] + private void mRPAREN() + { + try + { + int type = 39; + int channel = 0; + Match(41); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("LPAREN")] + private void mLPAREN() + { + try + { + int type = 26; + int channel = 0; + Match(40); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("HASH")] + private void mHASH() + { + try + { + int type = 18; + int channel = 0; + Match(35); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("SEMICOLON")] + private void mSEMICOLON() + { + try + { + int type = 41; + int channel = 0; + Match(59); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("RSQ")] + private void mRSQ() + { + try + { + int type = 40; + int channel = 0; + Match(93); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("LSQ")] + private void mLSQ() + { + try + { + int type = 27; + int channel = 0; + Match(91); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("LCURL")] + private void mLCURL() + { + try + { + int type = 24; + int channel = 0; + Match(123); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("RCURL")] + private void mRCURL() + { + try + { + int type = 38; + int channel = 0; + Match(125); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("PLUS")] + private void mPLUS() + { + try + { + int type = 37; + int channel = 0; + Match(43); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("MINUS")] + private void mMINUS() + { + try + { + int type = 30; + int channel = 0; + Match(45); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("TIMES")] + private void mTIMES() + { + try + { + int type = 46; + int channel = 0; + Match(42); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("DIVIDE")] + private void mDIVIDE() + { + try + { + int type = 12; + int channel = 0; + Match(47); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("MOD")] + private void mMOD() + { + try + { + int type = 31; + int channel = 0; + Match(37); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("EQ")] + private void mEQ() + { + try + { + int type = 14; + int channel = 0; + Match("=="); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("ASSIGN")] + private void mASSIGN() + { + try + { + int type = 5; + int channel = 0; + Match(61); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("NEQ")] + private void mNEQ() + { + try + { + int type = 32; + int channel = 0; + Match("!="); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("GTHAN")] + private void mGTHAN() + { + try + { + int type = 17; + int channel = 0; + Match(62); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("LTHAN")] + private void mLTHAN() + { + try + { + int type = 28; + int channel = 0; + Match(60); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("LEQ")] + private void mLEQ() + { + try + { + int type = 25; + int channel = 0; + Match("<="); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("GEQ")] + private void mGEQ() + { + try + { + int type = 16; + int channel = 0; + Match(">="); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("SHIFT_LEFT")] + private void mSHIFT_LEFT() + { + try + { + int type = 42; + int channel = 0; + Match("<<"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + [GrammarRule("SHIFT_RIGHT")] + private void mSHIFT_RIGHT() + { + try + { + int type = 43; + int channel = 0; + Match(">>"); + state.type = type; + state.channel = channel; + } + finally + { + } + } + + public override void mTokens() + { + int num = 41; + try + { + num = dfa9.Predict(input); + } + catch (NoViableAltException) + { + throw; + IL_001d:; + } + finally + { + } + switch (num) + { + case 1: + mT__58(); + break; + case 2: + mT__59(); + break; + case 3: + mT__60(); + break; + case 4: + mT__61(); + break; + case 5: + mT__62(); + break; + case 6: + mT__63(); + break; + case 7: + mT__64(); + break; + case 8: + mID(); + break; + case 9: + mINT(); + break; + case 10: + mCOMMENT(); + break; + case 11: + mWS(); + break; + case 12: + mSTRING(); + break; + case 13: + mCHAR(); + break; + case 14: + mCOMMA(); + break; + case 15: + mNOT(); + break; + case 16: + mBWOR(); + break; + case 17: + mBWAND(); + break; + case 18: + mOR(); + break; + case 19: + mAND(); + break; + case 20: + mRPAREN(); + break; + case 21: + mLPAREN(); + break; + case 22: + mHASH(); + break; + case 23: + mSEMICOLON(); + break; + case 24: + mRSQ(); + break; + case 25: + mLSQ(); + break; + case 26: + mLCURL(); + break; + case 27: + mRCURL(); + break; + case 28: + mPLUS(); + break; + case 29: + mMINUS(); + break; + case 30: + mTIMES(); + break; + case 31: + mDIVIDE(); + break; + case 32: + mMOD(); + break; + case 33: + mEQ(); + break; + case 34: + mASSIGN(); + break; + case 35: + mNEQ(); + break; + case 36: + mGTHAN(); + break; + case 37: + mLTHAN(); + break; + case 38: + mLEQ(); + break; + case 39: + mGEQ(); + break; + case 40: + mSHIFT_LEFT(); + break; + case 41: + mSHIFT_RIGHT(); + break; + } + } + + protected override void InitDFAs() + { + base.InitDFAs(); + dfa9 = new DFA9(this); + } + } +} diff --git a/AntlrTest/bgitestParser.cs b/AntlrTest/bgitestParser.cs new file mode 100644 index 00000000..1c29e782 --- /dev/null +++ b/AntlrTest/bgitestParser.cs @@ -0,0 +1,3380 @@ +using Antlr.Runtime; +using Antlr.Runtime.Tree; +using System; +using System.CodeDom.Compiler; + +namespace AntlrTest +{ + [CLSCompliant(false)] + [GeneratedCode("ANTLR", "3.5.0.1")] + public class bgitestParser : Parser + { + private static class Follow + { + public static readonly BitSet _directive_in_program143 = new BitSet(new ulong[1] + { + 786434uL + }); + + public static readonly BitSet _block_in_program145 = new BitSet(new ulong[1] + { + 786434uL + }); + + public static readonly BitSet _HASH_in_directive158 = new BitSet(new ulong[2] + { + 0uL, + 1uL + }); + + public static readonly BitSet _64_in_directive160 = new BitSet(new ulong[1] + { + 17592186044416uL + }); + + public static readonly BitSet _STRING_in_directive162 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _ID_in_block176 = new BitSet(new ulong[1] + { + 524288uL + }); + + public static readonly BitSet _ID_in_block180 = new BitSet(new ulong[1] + { + 67108864uL + }); + + public static readonly BitSet _LPAREN_in_block182 = new BitSet(new ulong[1] + { + 549755813888uL + }); + + public static readonly BitSet _RPAREN_in_block184 = new BitSet(new ulong[1] + { + 16777216uL + }); + + public static readonly BitSet _LCURL_in_block186 = new BitSet(new ulong[1] + { + 9223372311733207040uL + }); + + public static readonly BitSet _operations_in_block188 = new BitSet(new ulong[1] + { + 274877906944uL + }); + + public static readonly BitSet _RCURL_in_block191 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _operation_in_operations215 = new BitSet(new ulong[1] + { + 9223372036855300098uL + }); + + public static readonly BitSet _declaration_in_operation229 = new BitSet(new ulong[1] + { + 2199023255552uL + }); + + public static readonly BitSet _SEMICOLON_in_operation231 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _if_in_operation238 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _function_in_operation244 = new BitSet(new ulong[1] + { + 2199023255552uL + }); + + public static readonly BitSet _SEMICOLON_in_operation246 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _assignment_in_operation253 = new BitSet(new ulong[1] + { + 2199023255552uL + }); + + public static readonly BitSet _SEMICOLON_in_operation255 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _ID_in_declaration267 = new BitSet(new ulong[1] + { + 524288uL + }); + + public static readonly BitSet _variable_in_declaration269 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _ID_in_function290 = new BitSet(new ulong[1] + { + 67108864uL + }); + + public static readonly BitSet _LPAREN_in_function292 = new BitSet(new ulong[1] + { + 4035243408141844480uL + }); + + public static readonly BitSet _parameters_in_function294 = new BitSet(new ulong[1] + { + 549755813888uL + }); + + public static readonly BitSet _RPAREN_in_function297 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _variable_in_assignment319 = new BitSet(new ulong[1] + { + 32uL + }); + + public static readonly BitSet _ASSIGN_in_assignment321 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _obj_in_assignment323 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _obj_in_parameters345 = new BitSet(new ulong[1] + { + 1026uL + }); + + public static readonly BitSet _COMMA_in_parameters348 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _obj_in_parameters350 = new BitSet(new ulong[1] + { + 1026uL + }); + + public static readonly BitSet _ID_in_variable375 = new BitSet(new ulong[1] + { + 288230376285929474uL + }); + + public static readonly BitSet _LSQ_in_variable378 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _value_in_variable382 = new BitSet(new ulong[1] + { + 1099511627776uL + }); + + public static readonly BitSet _RSQ_in_variable384 = new BitSet(new ulong[1] + { + 288230376151711746uL + }); + + public static readonly BitSet _58_in_variable389 = new BitSet(new ulong[1] + { + 524288uL + }); + + public static readonly BitSet _variable_in_variable393 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _op_compare_in_obj431 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _value_in_obj437 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _INT_in_value448 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _STRING_in_value462 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _60_in_value476 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _61_in_value488 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _59_in_value502 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _variable_in_value516 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _function_in_value530 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _LPAREN_in_value544 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_compare_in_value546 = new BitSet(new ulong[1] + { + 549755813888uL + }); + + public static readonly BitSet _RPAREN_in_value548 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _value_in_op_mult567 = new BitSet(new ulong[1] + { + 70368744181762uL + }); + + public static readonly BitSet _TIMES_in_op_mult574 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _value_in_op_mult577 = new BitSet(new ulong[1] + { + 70368744181762uL + }); + + public static readonly BitSet _DIVIDE_in_op_mult585 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _value_in_op_mult588 = new BitSet(new ulong[1] + { + 70368744181762uL + }); + + public static readonly BitSet _op_mult_in_op_add605 = new BitSet(new ulong[1] + { + 138512695298uL + }); + + public static readonly BitSet _PLUS_in_op_add612 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_mult_in_op_add615 = new BitSet(new ulong[1] + { + 138512695298uL + }); + + public static readonly BitSet _MINUS_in_op_add623 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_mult_in_op_add626 = new BitSet(new ulong[1] + { + 138512695298uL + }); + + public static readonly BitSet _op_add_in_op_compare643 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _AND_in_op_compare650 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_add_in_op_compare653 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _OR_in_op_compare661 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_add_in_op_compare664 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _LEQ_in_op_compare672 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_add_in_op_compare675 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _GEQ_in_op_compare683 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_add_in_op_compare686 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _LTHAN_in_op_compare694 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_add_in_op_compare697 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _GTHAN_in_op_compare705 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_add_in_op_compare708 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _EQ_in_op_compare716 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _op_add_in_op_compare719 = new BitSet(new ulong[1] + { + 34661941266uL + }); + + public static readonly BitSet _63_in_if737 = new BitSet(new ulong[1] + { + 67108864uL + }); + + public static readonly BitSet _LPAREN_in_if739 = new BitSet(new ulong[1] + { + 4035242858386030592uL + }); + + public static readonly BitSet _obj_in_if741 = new BitSet(new ulong[1] + { + 549755813888uL + }); + + public static readonly BitSet _RPAREN_in_if743 = new BitSet(new ulong[1] + { + 9223372036872077312uL + }); + + public static readonly BitSet _LCURL_in_if747 = new BitSet(new ulong[1] + { + 9223372311733207040uL + }); + + public static readonly BitSet _operations_in_if751 = new BitSet(new ulong[1] + { + 274877906944uL + }); + + public static readonly BitSet _RCURL_in_if753 = new BitSet(new ulong[1] + { + 4611686018427387906uL + }); + + public static readonly BitSet _operation_in_if760 = new BitSet(new ulong[1] + { + 4611686018427387906uL + }); + + public static readonly BitSet _62_in_if764 = new BitSet(new ulong[1] + { + 9223372036872077312uL + }); + + public static readonly BitSet _LCURL_in_if768 = new BitSet(new ulong[1] + { + 9223372311733207040uL + }); + + public static readonly BitSet _operations_in_if772 = new BitSet(new ulong[1] + { + 274877906944uL + }); + + public static readonly BitSet _RCURL_in_if774 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _operation_in_if781 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _operations_in_synpred3_bgitest188 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _parameters_in_synpred8_bgitest294 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _op_compare_in_synpred13_bgitest431 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _62_in_synpred34_bgitest764 = new BitSet(new ulong[1] + { + 9223372036872077312uL + }); + + public static readonly BitSet _LCURL_in_synpred34_bgitest768 = new BitSet(new ulong[1] + { + 9223372311733207040uL + }); + + public static readonly BitSet _operations_in_synpred34_bgitest772 = new BitSet(new ulong[1] + { + 274877906944uL + }); + + public static readonly BitSet _RCURL_in_synpred34_bgitest774 = new BitSet(new ulong[1] + { + 2uL + }); + + public static readonly BitSet _operation_in_synpred34_bgitest781 = new BitSet(new ulong[1] + { + 2uL + }); + } + + public const int EOF = -1; + + public const int AND = 4; + + public const int ASSIGN = 5; + + public const int BLOCK = 6; + + public const int BWAND = 7; + + public const int BWOR = 8; + + public const int CHAR = 9; + + public const int COMMA = 10; + + public const int COMMENT = 11; + + public const int DIVIDE = 12; + + public const int ELSE = 13; + + public const int EQ = 14; + + public const int FALSE = 15; + + public const int GEQ = 16; + + public const int GTHAN = 17; + + public const int HASH = 18; + + public const int ID = 19; + + public const int IF = 20; + + public const int INCLUDE = 21; + + public const int INDEX = 22; + + public const int INT = 23; + + public const int LCURL = 24; + + public const int LEQ = 25; + + public const int LPAREN = 26; + + public const int LSQ = 27; + + public const int LTHAN = 28; + + public const int MEMBER = 29; + + public const int MINUS = 30; + + public const int MOD = 31; + + public const int NEQ = 32; + + public const int NOT = 33; + + public const int OPERATION = 34; + + public const int OR = 35; + + public const int PARAMETERS = 36; + + public const int PLUS = 37; + + public const int RCURL = 38; + + public const int RPAREN = 39; + + public const int RSQ = 40; + + public const int SEMICOLON = 41; + + public const int SHIFT_LEFT = 42; + + public const int SHIFT_RIGHT = 43; + + public const int STRING = 44; + + public const int THEN = 45; + + public const int TIMES = 46; + + public const int TRUE = 47; + + public const int TYPEBOOL = 48; + + public const int TYPEFUNCTION = 49; + + public const int TYPEINT = 50; + + public const int TYPEMATH = 51; + + public const int TYPENULL = 52; + + public const int TYPESTRING = 53; + + public const int TYPEVARIABLE = 54; + + public const int VAR = 55; + + public const int VARDECL = 56; + + public const int WS = 57; + + public const int T__58 = 58; + + public const int T__59 = 59; + + public const int T__60 = 60; + + public const int T__61 = 61; + + public const int T__62 = 62; + + public const int T__63 = 63; + + public const int T__64 = 64; + + internal static readonly string[] tokenNames = new string[65] + { + "", + "", + "", + "", + "AND", + "ASSIGN", + "BLOCK", + "BWAND", + "BWOR", + "CHAR", + "COMMA", + "COMMENT", + "DIVIDE", + "ELSE", + "EQ", + "FALSE", + "GEQ", + "GTHAN", + "HASH", + "ID", + "IF", + "INCLUDE", + "INDEX", + "INT", + "LCURL", + "LEQ", + "LPAREN", + "LSQ", + "LTHAN", + "MEMBER", + "MINUS", + "MOD", + "NEQ", + "NOT", + "OPERATION", + "OR", + "PARAMETERS", + "PLUS", + "RCURL", + "RPAREN", + "RSQ", + "SEMICOLON", + "SHIFT_LEFT", + "SHIFT_RIGHT", + "STRING", + "THEN", + "TIMES", + "TRUE", + "TYPEBOOL", + "TYPEFUNCTION", + "TYPEINT", + "TYPEMATH", + "TYPENULL", + "TYPESTRING", + "TYPEVARIABLE", + "VAR", + "VARDECL", + "WS", + "'.'", + "'FALSE'", + "'NULL'", + "'TRUE'", + "'else'", + "'if'", + "'include'" + }; + + private ITreeAdaptor adaptor; + + public ITreeAdaptor TreeAdaptor + { + get + { + return adaptor; + } + set + { + adaptor = value; + } + } + + public override string[] TokenNames => tokenNames; + + public override string GrammarFileName => "D:\\Projects\\d2bvsdd\\Assets\\Scripts\\Editor\\BGICompiler\\Grammar\\bgitest.g"; + + public bgitestParser(ITokenStream input) + : this(input, new RecognizerSharedState()) + { + } + + public bgitestParser(ITokenStream input, RecognizerSharedState state) + : base(input, state) + { + ITreeAdaptor treeAdaptor = null; + TreeAdaptor = (treeAdaptor ?? new CommonTreeAdaptor()); + } + + [GrammarRule("program")] + public AstParserRuleReturnScope program() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + try + { + try + { + commonTree = (CommonTree)adaptor.Nil(); + try + { + while (true) + { + int num = 3; + try + { + switch (input.LA(1)) + { + case 18: + num = 1; + break; + case 19: + num = 2; + break; + } + } + finally + { + } + switch (num) + { + case 1: + PushFollow(Follow._directive_in_program143); + astParserRuleReturnScope2 = directive(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope2.Tree); + } + continue; + case 2: + PushFollow(Follow._block_in_program145); + astParserRuleReturnScope3 = block(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope3.Tree); + } + continue; + } + break; + } + } + finally + { + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("directive")] + private AstParserRuleReturnScope directive() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token HASH"); + RewriteRuleTokenStream rewriteRuleTokenStream2 = new RewriteRuleTokenStream(adaptor, "token 64"); + RewriteRuleTokenStream rewriteRuleTokenStream3 = new RewriteRuleTokenStream(adaptor, "token STRING"); + try + { + try + { + token = (IToken)Match(input, 18, Follow._HASH_in_directive158); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + token2 = (IToken)Match(input, 64, Follow._64_in_directive160); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream2.Add(token2); + } + token3 = (IToken)Match(input, 44, Follow._STRING_in_directive162); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream3.Add(token3); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + commonTree = (astParserRuleReturnScope.Tree = null); + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("block")] + private AstParserRuleReturnScope block() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + IToken token4 = null; + IToken token5 = null; + IToken token6 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + CommonTree commonTree5 = null; + CommonTree commonTree6 = null; + CommonTree commonTree7 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token ID"); + RewriteRuleTokenStream rewriteRuleTokenStream2 = new RewriteRuleTokenStream(adaptor, "token LPAREN"); + RewriteRuleTokenStream rewriteRuleTokenStream3 = new RewriteRuleTokenStream(adaptor, "token RPAREN"); + RewriteRuleTokenStream rewriteRuleTokenStream4 = new RewriteRuleTokenStream(adaptor, "token LCURL"); + RewriteRuleTokenStream rewriteRuleTokenStream5 = new RewriteRuleTokenStream(adaptor, "token RCURL"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule operations"); + try + { + try + { + token2 = (IToken)Match(input, 19, Follow._ID_in_block176); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token2); + } + token = (IToken)Match(input, 19, Follow._ID_in_block180); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + token3 = (IToken)Match(input, 26, Follow._LPAREN_in_block182); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream2.Add(token3); + } + token4 = (IToken)Match(input, 39, Follow._RPAREN_in_block184); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream3.Add(token4); + } + token5 = (IToken)Match(input, 24, Follow._LCURL_in_block186); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream4.Add(token5); + } + int num = 2; + try + { + try + { + switch (input.LA(1)) + { + case 19: + case 63: + num = 1; + break; + case 38: + { + int num2 = input.LA(2); + if (EvaluatePredicate(synpred3_bgitest_fragment)) + { + num = 1; + } + break; + } + } + } + finally + { + } + int num3 = num; + if (num3 == 1) + { + PushFollow(Follow._operations_in_block188); + astParserRuleReturnScope2 = operations(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope2.Tree); + } + } + } + finally + { + } + token6 = (IToken)Match(input, 38, Follow._RCURL_in_block191); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream5.Add(token6); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleTokenStream rewriteRuleTokenStream6 = new RewriteRuleTokenStream(adaptor, "token id1", token); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(6, "BLOCK"), oldRoot); + adaptor.AddChild(oldRoot, rewriteRuleTokenStream6.NextNode()); + if (rewriteRuleSubtreeStream.HasNext) + { + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream.NextTree()); + } + rewriteRuleSubtreeStream.Reset(); + adaptor.AddChild(commonTree, oldRoot); + astParserRuleReturnScope.Tree = commonTree; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("operations")] + private AstParserRuleReturnScope operations() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + try + { + try + { + commonTree = (CommonTree)adaptor.Nil(); + try + { + while (true) + { + int num = 2; + try + { + int num2 = input.LA(1); + if (num2 == 19 || num2 == 63) + { + num = 1; + } + } + finally + { + } + int num3 = num; + if (num3 != 1) + { + break; + } + PushFollow(Follow._operation_in_operations215); + astParserRuleReturnScope2 = operation(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope2.Tree); + } + } + } + finally + { + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("operation")] + private AstParserRuleReturnScope operation() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + AstParserRuleReturnScope astParserRuleReturnScope4 = null; + AstParserRuleReturnScope astParserRuleReturnScope5 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + try + { + try + { + int num = 4; + try + { + switch (input.LA(1)) + { + case 19: + switch (input.LA(2)) + { + case 26: + num = 3; + break; + case 19: + num = 1; + break; + case 5: + case 27: + case 58: + num = 4; + break; + default: + if (state.backtracking <= 0) + { + NoViableAltException ex2 = new NoViableAltException(string.Empty, 4, 1, input, 2); + throw ex2; + } + state.failed = true; + return astParserRuleReturnScope; + } + break; + case 63: + num = 2; + break; + default: + if (state.backtracking <= 0) + { + NoViableAltException ex = new NoViableAltException(string.Empty, 4, 0, input, 1); + throw ex; + } + state.failed = true; + return astParserRuleReturnScope; + } + } + finally + { + } + switch (num) + { + case 1: + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._declaration_in_operation229); + astParserRuleReturnScope2 = declaration(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope2.Tree); + } + token = (IToken)Match(input, 41, Follow._SEMICOLON_in_operation231); + if (state.failed) + { + return astParserRuleReturnScope; + } + break; + case 2: + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._if_in_operation238); + astParserRuleReturnScope3 = @if(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope3.Tree); + } + break; + case 3: + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._function_in_operation244); + astParserRuleReturnScope4 = function(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope4.Tree); + } + token2 = (IToken)Match(input, 41, Follow._SEMICOLON_in_operation246); + if (state.failed) + { + return astParserRuleReturnScope; + } + break; + case 4: + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._assignment_in_operation253); + astParserRuleReturnScope5 = assignment(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope5.Tree); + } + token3 = (IToken)Match(input, 41, Follow._SEMICOLON_in_operation255); + if (state.failed) + { + return astParserRuleReturnScope; + } + break; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex3) + { + ReportError(ex3); + Recover(input, ex3); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex3); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("declaration")] + private AstParserRuleReturnScope declaration() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + CommonTree commonTree2 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token ID"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule variable"); + try + { + try + { + token = (IToken)Match(input, 19, Follow._ID_in_declaration267); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + PushFollow(Follow._variable_in_declaration269); + astParserRuleReturnScope2 = variable(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope2.Tree); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(56, "VARDECL"), oldRoot); + adaptor.AddChild(oldRoot, rewriteRuleTokenStream.NextNode()); + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream.NextTree()); + adaptor.AddChild(commonTree, oldRoot); + astParserRuleReturnScope.Tree = commonTree; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("function")] + private AstParserRuleReturnScope function() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token ID"); + RewriteRuleTokenStream rewriteRuleTokenStream2 = new RewriteRuleTokenStream(adaptor, "token LPAREN"); + RewriteRuleTokenStream rewriteRuleTokenStream3 = new RewriteRuleTokenStream(adaptor, "token RPAREN"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule parameters"); + try + { + try + { + token = (IToken)Match(input, 19, Follow._ID_in_function290); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + token2 = (IToken)Match(input, 26, Follow._LPAREN_in_function292); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream2.Add(token2); + } + int num = 2; + try + { + try + { + int num2 = input.LA(1); + if (num2 == 19 || num2 == 23 || num2 == 26 || num2 == 44 || (num2 >= 59 && num2 <= 61)) + { + num = 1; + } + else if (num2 == 39) + { + int num3 = input.LA(2); + if (EvaluatePredicate(synpred8_bgitest_fragment)) + { + num = 1; + } + } + } + finally + { + } + int num4 = num; + if (num4 == 1) + { + PushFollow(Follow._parameters_in_function294); + astParserRuleReturnScope2 = parameters(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope2.Tree); + } + } + } + finally + { + } + token3 = (IToken)Match(input, 39, Follow._RPAREN_in_function297); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream3.Add(token3); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(34, "OPERATION"), oldRoot); + adaptor.AddChild(oldRoot, rewriteRuleTokenStream.NextNode()); + if (rewriteRuleSubtreeStream.HasNext) + { + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream.NextTree()); + } + rewriteRuleSubtreeStream.Reset(); + adaptor.AddChild(commonTree, oldRoot); + astParserRuleReturnScope.Tree = commonTree; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("assignment")] + private AstParserRuleReturnScope assignment() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + CommonTree commonTree2 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token ASSIGN"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule variable"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule obj"); + try + { + try + { + PushFollow(Follow._variable_in_assignment319); + astParserRuleReturnScope2 = variable(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope2.Tree); + } + token = (IToken)Match(input, 5, Follow._ASSIGN_in_assignment321); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + PushFollow(Follow._obj_in_assignment323); + astParserRuleReturnScope3 = obj(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream2.Add(astParserRuleReturnScope3.Tree); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream3 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(5, "ASSIGN"), oldRoot); + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream.NextTree()); + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream2.NextTree()); + adaptor.AddChild(commonTree, oldRoot); + astParserRuleReturnScope.Tree = commonTree; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("parameters")] + private AstParserRuleReturnScope parameters() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + CommonTree commonTree2 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token COMMA"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule obj"); + try + { + try + { + int num = 2; + try + { + try + { + int num2 = input.LA(1); + if (num2 == 19 || num2 == 23 || num2 == 26 || num2 == 44 || (num2 >= 59 && num2 <= 61)) + { + num = 1; + } + } + finally + { + } + int num3 = num; + if (num3 == 1) + { + PushFollow(Follow._obj_in_parameters345); + astParserRuleReturnScope2 = obj(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope2.Tree); + } + try + { + while (true) + { + int num4 = 2; + try + { + int num5 = input.LA(1); + if (num5 == 10) + { + num4 = 1; + } + } + finally + { + } + int num6 = num4; + if (num6 != 1) + { + break; + } + token = (IToken)Match(input, 10, Follow._COMMA_in_parameters348); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + PushFollow(Follow._obj_in_parameters350); + astParserRuleReturnScope3 = obj(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope3.Tree); + } + } + } + finally + { + } + } + } + finally + { + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + if (rewriteRuleSubtreeStream.HasNext) + { + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(36, "PARAMETERS"), oldRoot); + while (rewriteRuleSubtreeStream.HasNext) + { + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream.NextTree()); + } + rewriteRuleSubtreeStream.Reset(); + adaptor.AddChild(commonTree, oldRoot); + } + rewriteRuleSubtreeStream.Reset(); + astParserRuleReturnScope.Tree = commonTree; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("variable")] + private AstParserRuleReturnScope variable() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + IToken token4 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + CommonTree commonTree5 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token ID"); + RewriteRuleTokenStream rewriteRuleTokenStream2 = new RewriteRuleTokenStream(adaptor, "token LSQ"); + RewriteRuleTokenStream rewriteRuleTokenStream3 = new RewriteRuleTokenStream(adaptor, "token RSQ"); + RewriteRuleTokenStream rewriteRuleTokenStream4 = new RewriteRuleTokenStream(adaptor, "token 58"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule value"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule variable"); + try + { + try + { + token = (IToken)Match(input, 19, Follow._ID_in_variable375); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + int num = 2; + try + { + try + { + int num2 = input.LA(1); + if (num2 == 27) + { + num = 1; + } + } + finally + { + } + int num3 = num; + if (num3 == 1) + { + token2 = (IToken)Match(input, 27, Follow._LSQ_in_variable378); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream2.Add(token2); + } + PushFollow(Follow._value_in_variable382); + astParserRuleReturnScope2 = value(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope2.Tree); + } + token3 = (IToken)Match(input, 40, Follow._RSQ_in_variable384); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream3.Add(token3); + } + } + } + finally + { + } + int num4 = 2; + try + { + try + { + int num5 = input.LA(1); + if (num5 == 58) + { + num4 = 1; + } + } + finally + { + } + int num3 = num4; + if (num3 == 1) + { + token4 = (IToken)Match(input, 58, Follow._58_in_variable389); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream4.Add(token4); + } + PushFollow(Follow._variable_in_variable393); + astParserRuleReturnScope3 = variable(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream2.Add(astParserRuleReturnScope3.Tree); + } + } + } + finally + { + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream3 = new RewriteRuleSubtreeStream(adaptor, "rule id", (astParserRuleReturnScope2 == null) ? null : astParserRuleReturnScope2.Tree); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream4 = new RewriteRuleSubtreeStream(adaptor, "rule mem", (astParserRuleReturnScope3 == null) ? null : astParserRuleReturnScope3.Tree); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream5 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(55, "VAR"), oldRoot); + adaptor.AddChild(oldRoot, rewriteRuleTokenStream.NextNode()); + if (rewriteRuleSubtreeStream3.HasNext) + { + CommonTree oldRoot2 = (CommonTree)adaptor.Nil(); + oldRoot2 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(22, "INDEX"), oldRoot2); + adaptor.AddChild(oldRoot2, rewriteRuleSubtreeStream3.NextTree()); + adaptor.AddChild(oldRoot, oldRoot2); + } + rewriteRuleSubtreeStream3.Reset(); + if (rewriteRuleSubtreeStream4.HasNext) + { + CommonTree oldRoot3 = (CommonTree)adaptor.Nil(); + oldRoot3 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(29, "MEMBER"), oldRoot3); + adaptor.AddChild(oldRoot3, rewriteRuleSubtreeStream4.NextTree()); + adaptor.AddChild(oldRoot, oldRoot3); + } + rewriteRuleSubtreeStream4.Reset(); + adaptor.AddChild(commonTree, oldRoot); + astParserRuleReturnScope.Tree = commonTree; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("obj")] + private AstParserRuleReturnScope obj() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + try + { + try + { + int num = 2; + try + { + switch (input.LA(1)) + { + case 23: + { + int num5 = input.LA(2); + num = (EvaluatePredicate(synpred13_bgitest_fragment) ? 1 : 2); + break; + } + case 44: + { + int num2 = input.LA(2); + num = (EvaluatePredicate(synpred13_bgitest_fragment) ? 1 : 2); + break; + } + case 60: + { + int num6 = input.LA(2); + num = (EvaluatePredicate(synpred13_bgitest_fragment) ? 1 : 2); + break; + } + case 61: + { + int num8 = input.LA(2); + num = (EvaluatePredicate(synpred13_bgitest_fragment) ? 1 : 2); + break; + } + case 59: + { + int num3 = input.LA(2); + num = (EvaluatePredicate(synpred13_bgitest_fragment) ? 1 : 2); + break; + } + case 19: + { + int num7 = input.LA(2); + num = (EvaluatePredicate(synpred13_bgitest_fragment) ? 1 : 2); + break; + } + case 26: + { + int num4 = input.LA(2); + num = (EvaluatePredicate(synpred13_bgitest_fragment) ? 1 : 2); + break; + } + default: + if (state.backtracking <= 0) + { + NoViableAltException ex = new NoViableAltException(string.Empty, 10, 0, input, 1); + throw ex; + } + state.failed = true; + return astParserRuleReturnScope; + } + } + finally + { + } + switch (num) + { + case 1: + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._op_compare_in_obj431); + astParserRuleReturnScope2 = op_compare(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope2.Tree); + } + break; + case 2: + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._value_in_obj437); + astParserRuleReturnScope3 = value(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope3.Tree); + } + break; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex2) + { + ReportError(ex2); + Recover(input, ex2); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex2); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("value")] + private AstParserRuleReturnScope value() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + IToken token4 = null; + IToken token5 = null; + IToken token6 = null; + IToken token7 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + AstParserRuleReturnScope astParserRuleReturnScope4 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + CommonTree commonTree5 = null; + CommonTree commonTree6 = null; + CommonTree commonTree7 = null; + CommonTree commonTree8 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token INT"); + RewriteRuleTokenStream rewriteRuleTokenStream2 = new RewriteRuleTokenStream(adaptor, "token STRING"); + RewriteRuleTokenStream rewriteRuleTokenStream3 = new RewriteRuleTokenStream(adaptor, "token 60"); + RewriteRuleTokenStream rewriteRuleTokenStream4 = new RewriteRuleTokenStream(adaptor, "token 61"); + RewriteRuleTokenStream rewriteRuleTokenStream5 = new RewriteRuleTokenStream(adaptor, "token 59"); + RewriteRuleTokenStream rewriteRuleTokenStream6 = new RewriteRuleTokenStream(adaptor, "token LPAREN"); + RewriteRuleTokenStream rewriteRuleTokenStream7 = new RewriteRuleTokenStream(adaptor, "token RPAREN"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule variable"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule function"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream3 = new RewriteRuleSubtreeStream(adaptor, "rule op_compare"); + try + { + try + { + int num = 8; + try + { + switch (input.LA(1)) + { + case 23: + num = 1; + break; + case 44: + num = 2; + break; + case 60: + num = 3; + break; + case 61: + num = 4; + break; + case 59: + num = 5; + break; + case 19: + { + int num2 = input.LA(2); + switch (num2) + { + case 26: + num = 7; + break; + default: + if (num2 != 25 && (num2 < 27 || num2 > 28) && num2 != 30 && num2 != 35 && num2 != 37 && (num2 < 39 || num2 > 41) && num2 != 46 && num2 != 58) + { + if (state.backtracking <= 0) + { + NoViableAltException ex2 = new NoViableAltException(string.Empty, 11, 6, input, 2); + throw ex2; + } + state.failed = true; + return astParserRuleReturnScope; + } + goto case -1; + case -1: + case 4: + case 10: + case 12: + case 14: + case 16: + case 17: + num = 6; + break; + } + break; + } + case 26: + num = 8; + break; + default: + if (state.backtracking <= 0) + { + NoViableAltException ex = new NoViableAltException(string.Empty, 11, 0, input, 1); + throw ex; + } + state.failed = true; + return astParserRuleReturnScope; + } + } + finally + { + } + switch (num) + { + case 1: + token = (IToken)Match(input, 23, Follow._INT_in_value448); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream5 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot2 = (CommonTree)adaptor.Nil(); + oldRoot2 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(50, "TYPEINT"), oldRoot2); + adaptor.AddChild(oldRoot2, rewriteRuleTokenStream.NextNode()); + adaptor.AddChild(commonTree, oldRoot2); + astParserRuleReturnScope.Tree = commonTree; + } + break; + case 2: + token2 = (IToken)Match(input, 44, Follow._STRING_in_value462); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream2.Add(token2); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream10 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot7 = (CommonTree)adaptor.Nil(); + oldRoot7 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(53, "TYPESTRING"), oldRoot7); + adaptor.AddChild(oldRoot7, rewriteRuleTokenStream2.NextNode()); + adaptor.AddChild(commonTree, oldRoot7); + astParserRuleReturnScope.Tree = commonTree; + } + break; + case 3: + token3 = (IToken)Match(input, 60, Follow._60_in_value476); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream3.Add(token3); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream11 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot8 = (CommonTree)adaptor.Nil(); + oldRoot8 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(52, "TYPENULL"), oldRoot8); + adaptor.AddChild(commonTree, oldRoot8); + astParserRuleReturnScope.Tree = commonTree; + } + break; + case 4: + token4 = (IToken)Match(input, 61, Follow._61_in_value488); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream4.Add(token4); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream9 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot6 = (CommonTree)adaptor.Nil(); + oldRoot6 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(48, "TYPEBOOL"), oldRoot6); + adaptor.AddChild(oldRoot6, (CommonTree)adaptor.Create(47, "TRUE")); + adaptor.AddChild(commonTree, oldRoot6); + astParserRuleReturnScope.Tree = commonTree; + } + break; + case 5: + token5 = (IToken)Match(input, 59, Follow._59_in_value502); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream5.Add(token5); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream7 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot4 = (CommonTree)adaptor.Nil(); + oldRoot4 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(48, "TYPEBOOL"), oldRoot4); + adaptor.AddChild(oldRoot4, (CommonTree)adaptor.Create(15, "FALSE")); + adaptor.AddChild(commonTree, oldRoot4); + astParserRuleReturnScope.Tree = commonTree; + } + break; + case 6: + PushFollow(Follow._variable_in_value516); + astParserRuleReturnScope2 = variable(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope2.Tree); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream6 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot3 = (CommonTree)adaptor.Nil(); + oldRoot3 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(54, "TYPEVARIABLE"), oldRoot3); + adaptor.AddChild(oldRoot3, rewriteRuleSubtreeStream.NextTree()); + adaptor.AddChild(commonTree, oldRoot3); + astParserRuleReturnScope.Tree = commonTree; + } + break; + case 7: + PushFollow(Follow._function_in_value530); + astParserRuleReturnScope3 = function(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream2.Add(astParserRuleReturnScope3.Tree); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream8 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot5 = (CommonTree)adaptor.Nil(); + oldRoot5 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(49, "TYPEFUNCTION"), oldRoot5); + adaptor.AddChild(oldRoot5, rewriteRuleSubtreeStream2.NextTree()); + adaptor.AddChild(commonTree, oldRoot5); + astParserRuleReturnScope.Tree = commonTree; + } + break; + case 8: + token6 = (IToken)Match(input, 26, Follow._LPAREN_in_value544); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream6.Add(token6); + } + PushFollow(Follow._op_compare_in_value546); + astParserRuleReturnScope4 = op_compare(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream3.Add(astParserRuleReturnScope4.Tree); + } + token7 = (IToken)Match(input, 39, Follow._RPAREN_in_value548); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream7.Add(token7); + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream4 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(51, "TYPEMATH"), oldRoot); + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream3.NextTree()); + adaptor.AddChild(commonTree, oldRoot); + astParserRuleReturnScope.Tree = commonTree; + } + break; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex3) + { + ReportError(ex3); + Recover(input, ex3); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex3); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("op_mult")] + private AstParserRuleReturnScope op_mult() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + AstParserRuleReturnScope astParserRuleReturnScope4 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + try + { + try + { + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._value_in_op_mult567); + astParserRuleReturnScope2 = value(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope2.Tree); + } + try + { + while (true) + { + int num = 3; + try + { + switch (input.LA(1)) + { + case 46: + num = 1; + break; + case 12: + num = 2; + break; + } + } + finally + { + } + switch (num) + { + case 1: + token = (IToken)Match(input, 46, Follow._TIMES_in_op_mult574); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree2 = (CommonTree)adaptor.Create(token); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree2, commonTree); + } + PushFollow(Follow._value_in_op_mult577); + astParserRuleReturnScope3 = value(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope3.Tree); + } + continue; + case 2: + token2 = (IToken)Match(input, 12, Follow._DIVIDE_in_op_mult585); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree3 = (CommonTree)adaptor.Create(token2); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree3, commonTree); + } + PushFollow(Follow._value_in_op_mult588); + astParserRuleReturnScope4 = value(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope4.Tree); + } + continue; + } + break; + } + } + finally + { + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("op_add")] + private AstParserRuleReturnScope op_add() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + AstParserRuleReturnScope astParserRuleReturnScope4 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + try + { + try + { + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._op_mult_in_op_add605); + astParserRuleReturnScope2 = op_mult(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope2.Tree); + } + try + { + while (true) + { + int num = 3; + try + { + switch (input.LA(1)) + { + case 37: + num = 1; + break; + case 30: + num = 2; + break; + } + } + finally + { + } + switch (num) + { + case 1: + token = (IToken)Match(input, 37, Follow._PLUS_in_op_add612); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree2 = (CommonTree)adaptor.Create(token); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree2, commonTree); + } + PushFollow(Follow._op_mult_in_op_add615); + astParserRuleReturnScope3 = op_mult(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope3.Tree); + } + continue; + case 2: + token2 = (IToken)Match(input, 30, Follow._MINUS_in_op_add623); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree3 = (CommonTree)adaptor.Create(token2); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree3, commonTree); + } + PushFollow(Follow._op_mult_in_op_add626); + astParserRuleReturnScope4 = op_mult(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope4.Tree); + } + continue; + } + break; + } + } + finally + { + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("op_compare")] + private AstParserRuleReturnScope op_compare() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + IToken token4 = null; + IToken token5 = null; + IToken token6 = null; + IToken token7 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + AstParserRuleReturnScope astParserRuleReturnScope4 = null; + AstParserRuleReturnScope astParserRuleReturnScope5 = null; + AstParserRuleReturnScope astParserRuleReturnScope6 = null; + AstParserRuleReturnScope astParserRuleReturnScope7 = null; + AstParserRuleReturnScope astParserRuleReturnScope8 = null; + AstParserRuleReturnScope astParserRuleReturnScope9 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + CommonTree commonTree5 = null; + CommonTree commonTree6 = null; + CommonTree commonTree7 = null; + CommonTree commonTree8 = null; + try + { + try + { + commonTree = (CommonTree)adaptor.Nil(); + PushFollow(Follow._op_add_in_op_compare643); + astParserRuleReturnScope2 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope2.Tree); + } + try + { + while (true) + { + int num = 8; + try + { + switch (input.LA(1)) + { + case 4: + num = 1; + break; + case 35: + num = 2; + break; + case 25: + num = 3; + break; + case 16: + num = 4; + break; + case 28: + num = 5; + break; + case 17: + num = 6; + break; + case 14: + num = 7; + break; + } + } + finally + { + } + switch (num) + { + case 1: + token = (IToken)Match(input, 4, Follow._AND_in_op_compare650); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree2 = (CommonTree)adaptor.Create(token); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree2, commonTree); + } + PushFollow(Follow._op_add_in_op_compare653); + astParserRuleReturnScope3 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope3.Tree); + } + continue; + case 2: + token2 = (IToken)Match(input, 35, Follow._OR_in_op_compare661); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree3 = (CommonTree)adaptor.Create(token2); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree3, commonTree); + } + PushFollow(Follow._op_add_in_op_compare664); + astParserRuleReturnScope4 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope4.Tree); + } + continue; + case 3: + token3 = (IToken)Match(input, 25, Follow._LEQ_in_op_compare672); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree4 = (CommonTree)adaptor.Create(token3); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree4, commonTree); + } + PushFollow(Follow._op_add_in_op_compare675); + astParserRuleReturnScope5 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope5.Tree); + } + continue; + case 4: + token4 = (IToken)Match(input, 16, Follow._GEQ_in_op_compare683); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree5 = (CommonTree)adaptor.Create(token4); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree5, commonTree); + } + PushFollow(Follow._op_add_in_op_compare686); + astParserRuleReturnScope6 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope6.Tree); + } + continue; + case 5: + token5 = (IToken)Match(input, 28, Follow._LTHAN_in_op_compare694); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree6 = (CommonTree)adaptor.Create(token5); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree6, commonTree); + } + PushFollow(Follow._op_add_in_op_compare697); + astParserRuleReturnScope7 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope7.Tree); + } + continue; + case 6: + token6 = (IToken)Match(input, 17, Follow._GTHAN_in_op_compare705); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree7 = (CommonTree)adaptor.Create(token6); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree7, commonTree); + } + PushFollow(Follow._op_add_in_op_compare708); + astParserRuleReturnScope8 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope8.Tree); + } + continue; + case 7: + token7 = (IToken)Match(input, 14, Follow._EQ_in_op_compare716); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + commonTree8 = (CommonTree)adaptor.Create(token7); + commonTree = (CommonTree)adaptor.BecomeRoot(commonTree8, commonTree); + } + PushFollow(Follow._op_add_in_op_compare719); + astParserRuleReturnScope9 = op_add(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + adaptor.AddChild(commonTree, astParserRuleReturnScope9.Tree); + } + continue; + } + break; + } + } + finally + { + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex) + { + ReportError(ex); + Recover(input, ex); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + [GrammarRule("if")] + private AstParserRuleReturnScope @if() + { + AstParserRuleReturnScope astParserRuleReturnScope = new AstParserRuleReturnScope(); + astParserRuleReturnScope.Start = input.LT(1); + CommonTree commonTree = null; + IToken token = null; + IToken token2 = null; + IToken token3 = null; + IToken token4 = null; + IToken token5 = null; + IToken token6 = null; + IToken token7 = null; + IToken token8 = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + AstParserRuleReturnScope astParserRuleReturnScope3 = null; + AstParserRuleReturnScope astParserRuleReturnScope4 = null; + AstParserRuleReturnScope astParserRuleReturnScope5 = null; + AstParserRuleReturnScope astParserRuleReturnScope6 = null; + CommonTree commonTree2 = null; + CommonTree commonTree3 = null; + CommonTree commonTree4 = null; + CommonTree commonTree5 = null; + CommonTree commonTree6 = null; + CommonTree commonTree7 = null; + CommonTree commonTree8 = null; + CommonTree commonTree9 = null; + RewriteRuleTokenStream rewriteRuleTokenStream = new RewriteRuleTokenStream(adaptor, "token 63"); + RewriteRuleTokenStream rewriteRuleTokenStream2 = new RewriteRuleTokenStream(adaptor, "token LPAREN"); + RewriteRuleTokenStream rewriteRuleTokenStream3 = new RewriteRuleTokenStream(adaptor, "token RPAREN"); + RewriteRuleTokenStream rewriteRuleTokenStream4 = new RewriteRuleTokenStream(adaptor, "token LCURL"); + RewriteRuleTokenStream rewriteRuleTokenStream5 = new RewriteRuleTokenStream(adaptor, "token RCURL"); + RewriteRuleTokenStream rewriteRuleTokenStream6 = new RewriteRuleTokenStream(adaptor, "token 62"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream = new RewriteRuleSubtreeStream(adaptor, "rule obj"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream2 = new RewriteRuleSubtreeStream(adaptor, "rule operations"); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream3 = new RewriteRuleSubtreeStream(adaptor, "rule operation"); + try + { + try + { + token = (IToken)Match(input, 63, Follow._63_in_if737); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream.Add(token); + } + token2 = (IToken)Match(input, 26, Follow._LPAREN_in_if739); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream2.Add(token2); + } + PushFollow(Follow._obj_in_if741); + astParserRuleReturnScope6 = obj(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream.Add(astParserRuleReturnScope6.Tree); + } + token3 = (IToken)Match(input, 39, Follow._RPAREN_in_if743); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream3.Add(token3); + } + int num = 2; + try + { + try + { + switch (input.LA(1)) + { + case 24: + num = 1; + break; + case 19: + case 63: + num = 2; + break; + default: + if (state.backtracking <= 0) + { + NoViableAltException ex = new NoViableAltException(string.Empty, 15, 0, input, 1); + throw ex; + } + state.failed = true; + return astParserRuleReturnScope; + } + } + finally + { + } + switch (num) + { + case 1: + token4 = (IToken)Match(input, 24, Follow._LCURL_in_if747); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream4.Add(token4); + } + PushFollow(Follow._operations_in_if751); + astParserRuleReturnScope2 = operations(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream2.Add(astParserRuleReturnScope2.Tree); + } + token5 = (IToken)Match(input, 38, Follow._RCURL_in_if753); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream5.Add(token5); + } + break; + case 2: + PushFollow(Follow._operation_in_if760); + astParserRuleReturnScope3 = operation(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream3.Add(astParserRuleReturnScope3.Tree); + } + break; + } + } + finally + { + } + int num2 = 2; + try + { + try + { + int num3 = input.LA(1); + if (num3 == 62) + { + int num4 = input.LA(2); + if (EvaluatePredicate(synpred34_bgitest_fragment)) + { + num2 = 1; + } + } + } + finally + { + } + int num5 = num2; + if (num5 == 1) + { + token6 = (IToken)Match(input, 62, Follow._62_in_if764); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream6.Add(token6); + } + int num6 = 2; + try + { + try + { + switch (input.LA(1)) + { + case 24: + num6 = 1; + break; + case 19: + case 63: + num6 = 2; + break; + default: + if (state.backtracking <= 0) + { + NoViableAltException ex2 = new NoViableAltException(string.Empty, 16, 0, input, 1); + throw ex2; + } + state.failed = true; + return astParserRuleReturnScope; + } + } + finally + { + } + switch (num6) + { + case 1: + token7 = (IToken)Match(input, 24, Follow._LCURL_in_if768); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream4.Add(token7); + } + PushFollow(Follow._operations_in_if772); + astParserRuleReturnScope4 = operations(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream2.Add(astParserRuleReturnScope4.Tree); + } + token8 = (IToken)Match(input, 38, Follow._RCURL_in_if774); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleTokenStream5.Add(token8); + } + break; + case 2: + PushFollow(Follow._operation_in_if781); + astParserRuleReturnScope5 = operation(); + PopFollow(); + if (state.failed) + { + return astParserRuleReturnScope; + } + if (state.backtracking == 0) + { + rewriteRuleSubtreeStream3.Add(astParserRuleReturnScope5.Tree); + } + break; + } + } + finally + { + } + } + } + finally + { + } + if (state.backtracking == 0) + { + astParserRuleReturnScope.Tree = commonTree; + RewriteRuleSubtreeStream rewriteRuleSubtreeStream4 = new RewriteRuleSubtreeStream(adaptor, "rule ops1", (astParserRuleReturnScope2 == null) ? null : astParserRuleReturnScope2.Tree); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream5 = new RewriteRuleSubtreeStream(adaptor, "rule op1", (astParserRuleReturnScope3 == null) ? null : astParserRuleReturnScope3.Tree); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream6 = new RewriteRuleSubtreeStream(adaptor, "rule ops2", (astParserRuleReturnScope4 == null) ? null : astParserRuleReturnScope4.Tree); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream7 = new RewriteRuleSubtreeStream(adaptor, "rule op2", (astParserRuleReturnScope5 == null) ? null : astParserRuleReturnScope5.Tree); + RewriteRuleSubtreeStream rewriteRuleSubtreeStream8 = new RewriteRuleSubtreeStream(adaptor, "rule retval", (astParserRuleReturnScope == null) ? null : astParserRuleReturnScope.Tree); + commonTree = (CommonTree)adaptor.Nil(); + CommonTree oldRoot = (CommonTree)adaptor.Nil(); + oldRoot = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(20, "IF"), oldRoot); + adaptor.AddChild(oldRoot, rewriteRuleSubtreeStream.NextTree()); + CommonTree oldRoot2 = (CommonTree)adaptor.Nil(); + oldRoot2 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(45, "THEN"), oldRoot2); + if (rewriteRuleSubtreeStream4.HasNext) + { + adaptor.AddChild(oldRoot2, rewriteRuleSubtreeStream4.NextTree()); + } + rewriteRuleSubtreeStream4.Reset(); + if (rewriteRuleSubtreeStream5.HasNext) + { + adaptor.AddChild(oldRoot2, rewriteRuleSubtreeStream5.NextTree()); + } + rewriteRuleSubtreeStream5.Reset(); + adaptor.AddChild(oldRoot, oldRoot2); + CommonTree oldRoot3 = (CommonTree)adaptor.Nil(); + oldRoot3 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(13, "ELSE"), oldRoot3); + if (rewriteRuleSubtreeStream6.HasNext) + { + adaptor.AddChild(oldRoot3, rewriteRuleSubtreeStream6.NextTree()); + } + rewriteRuleSubtreeStream6.Reset(); + if (rewriteRuleSubtreeStream7.HasNext) + { + adaptor.AddChild(oldRoot3, rewriteRuleSubtreeStream7.NextTree()); + } + rewriteRuleSubtreeStream7.Reset(); + adaptor.AddChild(oldRoot, oldRoot3); + adaptor.AddChild(commonTree, oldRoot); + astParserRuleReturnScope.Tree = commonTree; + } + astParserRuleReturnScope.Stop = input.LT(-1); + if (state.backtracking != 0) + { + return astParserRuleReturnScope; + } + astParserRuleReturnScope.Tree = (CommonTree)adaptor.RulePostProcessing(commonTree); + adaptor.SetTokenBoundaries(astParserRuleReturnScope.Tree, astParserRuleReturnScope.Start, astParserRuleReturnScope.Stop); + return astParserRuleReturnScope; + } + catch (RecognitionException ex3) + { + ReportError(ex3); + Recover(input, ex3); + astParserRuleReturnScope.Tree = (CommonTree)adaptor.ErrorNode(input, astParserRuleReturnScope.Start, input.LT(-1), ex3); + return astParserRuleReturnScope; + } + finally + { + } + } + finally + { + } + } + + private void synpred3_bgitest_fragment() + { + try + { + PushFollow(Follow._operations_in_synpred3_bgitest188); + operations(); + PopFollow(); + if (!state.failed) + { + } + } + finally + { + } + } + + private void synpred8_bgitest_fragment() + { + try + { + PushFollow(Follow._parameters_in_synpred8_bgitest294); + parameters(); + PopFollow(); + if (!state.failed) + { + } + } + finally + { + } + } + + private void synpred13_bgitest_fragment() + { + try + { + PushFollow(Follow._op_compare_in_synpred13_bgitest431); + op_compare(); + PopFollow(); + if (!state.failed) + { + } + } + finally + { + } + } + + private void synpred34_bgitest_fragment() + { + AstParserRuleReturnScope astParserRuleReturnScope = null; + AstParserRuleReturnScope astParserRuleReturnScope2 = null; + try + { + Match(input, 62, Follow._62_in_synpred34_bgitest764); + if (!state.failed) + { + int num = 2; + try + { + try + { + switch (input.LA(1)) + { + case 24: + num = 1; + break; + case 19: + case 63: + num = 2; + break; + default: + if (state.backtracking <= 0) + { + NoViableAltException ex = new NoViableAltException(string.Empty, 19, 0, input, 1); + throw ex; + } + state.failed = true; + return; + } + } + finally + { + } + switch (num) + { + case 1: + Match(input, 24, Follow._LCURL_in_synpred34_bgitest768); + if (!state.failed) + { + PushFollow(Follow._operations_in_synpred34_bgitest772); + astParserRuleReturnScope = operations(); + PopFollow(); + if (!state.failed) + { + Match(input, 38, Follow._RCURL_in_synpred34_bgitest774); + if (!state.failed) + { + } + } + } + break; + case 2: + PushFollow(Follow._operation_in_synpred34_bgitest781); + astParserRuleReturnScope2 = operation(); + PopFollow(); + if (!state.failed) + { + } + break; + } + } + finally + { + } + } + } + finally + { + } + } + + private bool EvaluatePredicate(Action fragment) + { + bool result = false; + state.backtracking++; + try + { + int marker = input.Mark(); + try + { + fragment(); + } + catch (RecognitionException arg) + { + Console.Error.WriteLine("impossible: " + arg); + } + result = !state.failed; + input.Rewind(marker); + } + finally + { + } + state.backtracking--; + state.failed = false; + return result; + } + } +} diff --git a/Assembly-CSharp.csproj b/Assembly-CSharp.csproj new file mode 100644 index 00000000..0acee1e2 --- /dev/null +++ b/Assembly-CSharp.csproj @@ -0,0 +1,547 @@ + + + + {0BA774AA-B2B4-468C-B002-CAA0652C466E} + Debug + AnyCPU + Library + 7.1 + Assembly-CSharp + v2.0 + 4 + True + + + AnyCPU + + + bin\Debug\ + true + full + false + + + bin\Release\ + true + pdbonly + true + + + + DLLs\UnityEngine.dll + + + DLLs\System.dll + + + DLLs\System.Core.dll + + + DLLs\System.Xml.dll + + + DLLs\Antlr3.Runtime.dll + + + DLLs\NVorbis.dll + + + DLLs\Assembly-CSharp-firstpass.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Assembly-CSharp.sln b/Assembly-CSharp.sln new file mode 100644 index 00000000..ba50290f --- /dev/null +++ b/Assembly-CSharp.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2042 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{0BA774AA-B2B4-468C-B002-CAA0652C466E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0BA774AA-B2B4-468C-B002-CAA0652C466E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BA774AA-B2B4-468C-B002-CAA0652C466E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BA774AA-B2B4-468C-B002-CAA0652C466E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BA774AA-B2B4-468C-B002-CAA0652C466E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DCD9BAA9-8CFB-45CF-8BEB-363E9C89A2C8} + EndGlobalSection +EndGlobal diff --git a/Assets.Scripts.Core.AssetManagement/AssetManager.cs b/Assets.Scripts.Core.AssetManagement/AssetManager.cs new file mode 100644 index 00000000..3ee50553 --- /dev/null +++ b/Assets.Scripts.Core.AssetManagement/AssetManager.cs @@ -0,0 +1,256 @@ +using Assets.Scripts.Core.Audio; +using BGICompiler.Compiler; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.Core.AssetManagement +{ + public class AssetManager + { + private static AssetManager _instance; + + public bool UseNewArt = true; + + private Texture2D windowTexture; + + private string assetPath = Application.streamingAssetsPath; + + private List scriptList = new List(); + + public static AssetManager Instance => _instance ?? (_instance = GameSystem.Instance.AssetManager); + + public void CompileFolder(string srcDir, string destDir) + { + string[] files = Directory.GetFiles(srcDir, "*.txt"); + string[] files2 = Directory.GetFiles(destDir, "*.mg"); + List list = new List(); + string[] array = files; + foreach (string text in array) + { + string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); + if (fileNameWithoutExtension != null) + { + list.Add(fileNameWithoutExtension); + string text2 = text; + string text3 = Path.Combine(destDir, fileNameWithoutExtension) + ".mg"; + if (File.Exists(text3)) + { + if (File.GetLastWriteTime(text2) <= File.GetLastWriteTime(text3)) + { + continue; + } + Debug.Log($"Script {text3} last compiled {File.GetLastWriteTime(text3)} (source {text2} updated on {File.GetLastWriteTime(text2)})"); + } + Debug.Log("Compiling file " + text2); + try + { + new BGItoMG(text2, text3); + } + catch (Exception arg) + { + Debug.LogError($"Failed to compile script {fileNameWithoutExtension}!\r\n{arg}"); + } + } + } + string[] array2 = files2; + foreach (string path in array2) + { + string fileNameWithoutExtension2 = Path.GetFileNameWithoutExtension(path); + if (!list.Contains(fileNameWithoutExtension2)) + { + Debug.Log("Compiled script " + fileNameWithoutExtension2 + " has no matching script file. Removing..."); + File.Delete(path); + } + } + } + + public void CompileIfNeeded() + { + string path = Path.Combine(assetPath, "Scripts"); + string text = Path.Combine(assetPath, "Update"); + string text2 = Path.Combine(assetPath, "CompiledScripts"); + string destDir = Path.Combine(assetPath, "CompiledUpdateScripts"); + string[] files = Directory.GetFiles(path, "*.txt"); + string[] files2 = Directory.GetFiles(text, "*.txt"); + Debug.Log("Checking update scripts for updates..."); + CompileFolder(text, destDir); + string[] files3 = Directory.GetFiles(Path.Combine(assetPath, "CompiledScripts")); + string[] files4 = Directory.GetFiles(Path.Combine(assetPath, "CompiledUpdateScripts")); + string[] array = files3; + foreach (string path2 in array) + { + if (!(Path.GetExtension(path2) != ".mg")) + { + string fileName = Path.GetFileName(path2); + if (!scriptList.Contains(fileName)) + { + scriptList.Add(fileName); + } + } + } + string[] array2 = files4; + foreach (string path3 in array2) + { + if (!(Path.GetExtension(path3) != ".mg")) + { + string fileName2 = Path.GetFileName(path3); + if (!scriptList.Contains(fileName2)) + { + scriptList.Add(fileName2); + } + } + } + } + + private string GetArchiveNameByAudioType(Assets.Scripts.Core.Audio.AudioType audioType) + { + switch (audioType) + { + case Assets.Scripts.Core.Audio.AudioType.BGM: + return "BGM"; + case Assets.Scripts.Core.Audio.AudioType.Voice: + return "voice"; + case Assets.Scripts.Core.Audio.AudioType.SE: + return "SE"; + case Assets.Scripts.Core.Audio.AudioType.System: + return "SE"; + default: + throw new InvalidEnumArgumentException("GetArchiveNameByAudioType: Invalid audiotype " + audioType); + } + } + + private static int ReadLittleEndianInt32(byte[] bytes) + { + byte[] array = new byte[4]; + for (int i = 0; i < 4; i++) + { + array[3 - i] = bytes[i]; + } + return BitConverter.ToInt32(array, 0); + } + + public Texture2D LoadScreenshot(string filename) + { + string savePath = MGHelper.GetSavePath(); + string path = Path.Combine(savePath, filename.ToLower()); + if (File.Exists(path)) + { + try + { + byte[] array = File.ReadAllBytes(path); + byte[] array2 = new byte[4]; + Buffer.BlockCopy(array, 16, array2, 0, 4); + int width = ReadLittleEndianInt32(array2); + Buffer.BlockCopy(array, 20, array2, 0, 4); + int height = ReadLittleEndianInt32(array2); + Texture2D texture2D = new Texture2D(width, height, TextureFormat.ARGB32, mipmap: false); + texture2D.LoadImage(array); + texture2D.filterMode = FilterMode.Bilinear; + texture2D.wrapMode = TextureWrapMode.Clamp; + return texture2D; + IL_008d: + Texture2D result; + return result; + } + catch (Exception) + { + return LoadTexture("no_data"); + IL_00a5: + Texture2D result; + return result; + } + } + return LoadTexture("no_data"); + } + + public Texture2D LoadTexture(string textureName) + { + if (textureName == "windo_filter" && windowTexture != null) + { + return windowTexture; + } + string path = Path.Combine(assetPath, "CG/" + textureName.ToLower() + "_j.png"); + string path2 = Path.Combine(assetPath, "CGAlt/" + textureName.ToLower() + "_j.png"); + string text = Path.Combine(assetPath, "CG/" + textureName.ToLower() + ".png"); + string path3 = Path.Combine(assetPath, "CGAlt/" + textureName.ToLower() + ".png"); + byte[] array = new byte[0]; + bool flag = false; + if (!GameSystem.Instance.UseEnglishText) + { + if (UseNewArt && File.Exists(path2)) + { + array = File.ReadAllBytes(path2); + flag = true; + } + else if (File.Exists(path)) + { + array = File.ReadAllBytes(path); + flag = true; + } + } + if (!flag) + { + if (UseNewArt && File.Exists(path3)) + { + array = File.ReadAllBytes(path3); + } + else + { + if (!File.Exists(text)) + { + Logger.LogWarning("Could not find texture asset " + text); + return null; + } + array = File.ReadAllBytes(text); + } + } + if (array == null || array.Length == 0) + { + throw new Exception("Failed loading texture " + textureName.ToLower()); + } + byte[] array2 = new byte[4]; + Buffer.BlockCopy(array, 16, array2, 0, 4); + int width = ReadLittleEndianInt32(array2); + Buffer.BlockCopy(array, 20, array2, 0, 4); + int height = ReadLittleEndianInt32(array2); + Texture2D texture2D = new Texture2D(width, height, TextureFormat.ARGB32, mipmap: true); + texture2D.mipMapBias = -0.5f; + texture2D.LoadImage(array); + texture2D.filterMode = FilterMode.Bilinear; + texture2D.wrapMode = TextureWrapMode.Clamp; + texture2D.name = textureName; + if (textureName == "windo_filter") + { + windowTexture = texture2D; + } + return texture2D; + } + + public byte[] GetAudioFile(string filename, Assets.Scripts.Core.Audio.AudioType type) + { + string archiveNameByAudioType = GetArchiveNameByAudioType(type); + string path = Path.Combine(assetPath, archiveNameByAudioType + "/" + filename.ToLower()); + return File.ReadAllBytes(path); + } + + public byte[] GetScriptData(string filename) + { + string path = Path.Combine(assetPath, "CompiledUpdateScripts/" + filename.ToLower()); + if (File.Exists(path)) + { + Debug.Log("Loading script " + filename + " from update folder."); + return File.ReadAllBytes(path); + } + path = Path.Combine(assetPath, "CompiledScripts/" + filename.ToLower()); + return File.ReadAllBytes(path); + } + + public string[] GetAvailableScriptNames() + { + return scriptList.ToArray(); + } + } +} diff --git a/Assets.Scripts.Core.AssetManagement/PacArchive.cs b/Assets.Scripts.Core.AssetManagement/PacArchive.cs new file mode 100644 index 00000000..022c35f5 --- /dev/null +++ b/Assets.Scripts.Core.AssetManagement/PacArchive.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; + +namespace Assets.Scripts.Core.AssetManagement +{ + public class PacArchive + { + public string Name; + + private string path; + + public Dictionary EntityList = new Dictionary(); + + public PacArchive(string filename) + { + Name = filename; + path = Path.Combine(MGHelper.GetDataPath(), filename); + try + { + using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + using (BinaryReader binaryReader = new BinaryReader(fileStream)) + { + string a = new string(binaryReader.ReadChars(4)); + if (a != "MGPK") + { + throw new FileLoadException("File is not a valid pac file."); + } + int num = binaryReader.ReadInt32(); + if (num != 1) + { + throw new FileLoadException("Cannot read from pac archive! Incorrect archive version."); + } + int num2 = binaryReader.ReadInt32(); + for (int i = 0; i < num2; i++) + { + fileStream.Seek(12 + 48 * i, SeekOrigin.Begin); + string text = binaryReader.ReadString(); + fileStream.Seek(12 + 48 * i + 32, SeekOrigin.Begin); + int offset = binaryReader.ReadInt32(); + int size = binaryReader.ReadInt32(); + PacEntity value = new PacEntity(text.ToLower(), offset, size); + EntityList.Add(text.ToLower(), value); + } + } + } + } + catch (Exception arg) + { + Logger.LogError($"Failed to open PacArchive {filename}!\nException: {arg}"); + } + } + + public byte[] GetPacFile(string filename, bool encode, bool compress) + { + Debug.Log(filename); + EntityList.TryGetValue(filename.ToLower(), out PacEntity value); + if (value == null) + { + Logger.LogError("Could not find archive " + filename + " in pac file " + Name); + return new byte[0]; + } + byte[] array; + using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + using (BinaryReader binaryReader = new BinaryReader(fileStream)) + { + fileStream.Seek(value.Offset, SeekOrigin.Begin); + array = binaryReader.ReadBytes(value.Size); + } + } + Debug.Log($"GetPacFile {filename} size {array.Length}"); + if (encode) + { + MGHelper.KeyEncode(array); + } + if (compress) + { + return CLZF2.Decompress(array); + } + return array; + } + + public string[] GetPacFileList() + { + return EntityList.Keys.ToArray(); + } + } +} diff --git a/Assets.Scripts.Core.AssetManagement/PacEntity.cs b/Assets.Scripts.Core.AssetManagement/PacEntity.cs new file mode 100644 index 00000000..4fa535ea --- /dev/null +++ b/Assets.Scripts.Core.AssetManagement/PacEntity.cs @@ -0,0 +1,23 @@ +namespace Assets.Scripts.Core.AssetManagement +{ + public class PacEntity + { + public string Name; + + public int Offset; + + public int Size; + + public PacEntity(string name, int offset, int size) + { + Name = name.Trim().ToLower(); + Offset = offset; + Size = size; + } + + public override string ToString() + { + return string.Format("(NameLength: {3}, Name: {0} Offset: {1} Size: {2})", Name, Offset, Size, Name.Length); + } + } +} diff --git a/Assets.Scripts.Core.Audio/AudioController.cs b/Assets.Scripts.Core.Audio/AudioController.cs new file mode 100644 index 00000000..4a0c55c8 --- /dev/null +++ b/Assets.Scripts.Core.Audio/AudioController.cs @@ -0,0 +1,514 @@ +using Assets.Scripts.Core.Buriko; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.Core.Audio +{ + public class AudioController + { + private const int BGMLayers = 6; + + private const int VoiceLayers = 8; + + private const int SoundLayers = 8; + + private const int SystemLayers = 2; + + private static AudioController _instance; + + public float GlobalVolume = 0.5f; + + public float BGMVolume = 1f; + + public float VoiceVolume = 1f; + + public float SoundVolume = 1f; + + public float SystemVolume = 1f; + + private readonly Dictionary channelDictionary = new Dictionary(); + + private Dictionary> currentAudio = new Dictionary>(); + + private GameObject audioParent; + + private byte[] tempSavedAudio; + + public static AudioController Instance => _instance ?? (_instance = GameSystem.Instance.AudioController); + + public AudioController() + { + GameSystem.Instance.AudioController = this; + currentAudio.Add(AudioType.BGM, new Dictionary()); + currentAudio.Add(AudioType.Voice, new Dictionary()); + audioParent = new GameObject("AudioLayers"); + int num = 0; + for (int i = 0; i < 6; i++) + { + GameObject gameObject = new GameObject("BGM Channel " + i.ToString("D2")); + AudioLayer audioLayer = gameObject.AddComponent(); + gameObject.transform.parent = audioParent.transform; + audioLayer.Prepare(num); + channelDictionary.Add(num, audioLayer); + num++; + } + for (int j = 0; j < 8; j++) + { + GameObject gameObject2 = new GameObject("Voice Channel " + j.ToString("D2")); + AudioLayer audioLayer2 = gameObject2.AddComponent(); + gameObject2.transform.parent = audioParent.transform; + audioLayer2.Prepare(num); + channelDictionary.Add(num, audioLayer2); + num++; + } + for (int k = 0; k < 8; k++) + { + GameObject gameObject3 = new GameObject("SE Channel " + k.ToString("D2")); + AudioLayer audioLayer3 = gameObject3.AddComponent(); + gameObject3.transform.parent = audioParent.transform; + audioLayer3.Prepare(num); + channelDictionary.Add(num, audioLayer3); + num++; + } + for (int l = 0; l < 2; l++) + { + GameObject gameObject4 = new GameObject("System Channel " + l.ToString("D2")); + AudioLayer audioLayer4 = gameObject4.AddComponent(); + gameObject4.transform.parent = audioParent.transform; + audioLayer4.Prepare(num); + channelDictionary.Add(num, audioLayer4); + num++; + } + AudioConfiguration configuration = AudioSettings.GetConfiguration(); + configuration.sampleRate = 44100; + AudioSettings.Reset(configuration); + } + + public void SerializeCurrentAudio(MemoryStream ms) + { + BsonWriter bsonWriter = new BsonWriter(ms); + bsonWriter.CloseOutput = false; + using (BsonWriter jsonWriter = bsonWriter) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.Serialize(jsonWriter, currentAudio); + } + } + + public void DeSerializeCurrentAudio(MemoryStream ms) + { + StopAllAudio(); + BsonReader bsonReader = new BsonReader(ms); + bsonReader.CloseInput = false; + using (BsonReader reader = bsonReader) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + currentAudio = jsonSerializer.Deserialize>>(reader); + } + Dictionary dictionary = currentAudio[AudioType.BGM]; + for (int i = 0; i < 6; i++) + { + if (dictionary.ContainsKey(i)) + { + AudioInfo audioInfo = dictionary[i]; + PlayAudio(audioInfo.Filename, AudioType.BGM, i, audioInfo.Volume, 0f); + } + } + Dictionary dictionary2 = currentAudio[AudioType.Voice]; + for (int j = 0; j < 8; j++) + { + if (dictionary2.ContainsKey(j)) + { + AudioInfo audioInfo2 = dictionary2[j]; + PlayAudio(audioInfo2.Filename, AudioType.Voice, j, audioInfo2.Volume, 0f); + } + } + tempSavedAudio = null; + } + + private void SerializeTemp() + { + MemoryStream memoryStream = new MemoryStream(); + SerializeCurrentAudio(memoryStream); + tempSavedAudio = memoryStream.ToArray(); + } + + private void RestoreTemp() + { + if (tempSavedAudio != null) + { + MemoryStream ms = new MemoryStream(tempSavedAudio); + DeSerializeCurrentAudio(ms); + } + } + + public void SaveRestoreTempAudio() + { + if (tempSavedAudio == null) + { + SerializeTemp(); + } + else + { + StopAllAudio(); + RestoreTemp(); + SerializeTemp(); + } + } + + public void ClearTempAudio() + { + tempSavedAudio = null; + } + + public AudioInfo GetVoiceQueue(int channel) + { + if (currentAudio[AudioType.Voice].ContainsKey(channel)) + { + return currentAudio[AudioType.Voice][channel]; + } + return null; + } + + public void ClearVoiceQueue() + { + currentAudio[AudioType.Voice].Clear(); + } + + public bool IsVoicePlaying(int channel) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, channel)]; + return audioLayer.IsPlaying(); + } + + public void AddVoiceFinishCallback(int channel, AudioFinishCallback callback) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, channel)]; + audioLayer.RegisterCallback(callback); + } + + public float GetRemainingSEPlayTime(int channel) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.SE, channel)]; + return audioLayer.GetRemainingPlayTime(); + } + + public float GetRemainingVoicePlayTime(int channel) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, channel)]; + return audioLayer.GetRemainingPlayTime(); + } + + public void ChangeVolumeOfBGM(int channel, float volume, float time) + { + int channelByTypeChannel = GetChannelByTypeChannel(AudioType.BGM, channel); + float time2 = time / 1000f; + AudioLayer audioLayer = channelDictionary[channelByTypeChannel]; + if (currentAudio[AudioType.BGM].ContainsKey(channel)) + { + currentAudio[AudioType.BGM][channel].Volume = volume; + } + else + { + Debug.LogWarning("ChangeVolumeOfBGM could not find existing currentAudio for channel!"); + } + audioLayer.StartVolumeFade(volume, time2); + } + + public void FadeOutBGM(int channel, int time, bool waitForFade) + { + float num = (float)time / 1000f; + int channelByTypeChannel = GetChannelByTypeChannel(AudioType.BGM, channel); + AudioLayer audioLayer = channelDictionary[channelByTypeChannel]; + audioLayer.FadeOut(num); + if (waitForFade) + { + GameSystem.Instance.AddWait(new Wait(num, WaitTypes.WaitForAudio, audioLayer.StopAudio)); + } + if (currentAudio[AudioType.BGM].ContainsKey(channel)) + { + currentAudio[AudioType.BGM].Remove(channel); + } + } + + public void StopBGM(int channel) + { + AudioLayer audioLayer = channelDictionary[channel]; + audioLayer.StopAudio(); + if (currentAudio[AudioType.BGM].ContainsKey(channel)) + { + currentAudio[AudioType.BGM].Remove(channel); + } + } + + public void FadeOutMultiBGM(int channelstart, int channelend, int time, bool waitForFade) + { + for (int i = channelstart; i <= channelend; i++) + { + FadeOutBGM(i, time, waitForFade); + } + } + + public void PlaySE(string filename, int channel, float volume, float pan) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.SE, channel)]; + if (audioLayer.IsPlaying()) + { + audioLayer.StopAudio(); + } + audioLayer.PlayAudio(filename, AudioType.SE, volume); + } + + public void StopSE(int channel) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.SE, channel)]; + audioLayer.StopAudio(); + } + + public void FadeOutSE(int channel, float time, bool waitForFade) + { + float num = time / 1000f; + int channelByTypeChannel = GetChannelByTypeChannel(AudioType.SE, channel); + AudioLayer audioLayer = channelDictionary[channelByTypeChannel]; + audioLayer.FadeOut(num); + if (waitForFade) + { + GameSystem.Instance.AddWait(new Wait(num, WaitTypes.WaitForAudio, audioLayer.StopAudio)); + } + } + + public void PlayVoice(string filename, int channel, float volume) + { + string text = filename.Substring(0, 4); + bool flag = false; + switch (text) + { + case "chie": + flag = BurikoMemory.Instance.GetGlobalFlag("GVChie").BoolValue(); + break; + case "eiji": + flag = BurikoMemory.Instance.GetGlobalFlag("GVEiji").BoolValue(); + break; + case "kana": + flag = BurikoMemory.Instance.GetGlobalFlag("GVKana").BoolValue(); + break; + case "kira": + flag = BurikoMemory.Instance.GetGlobalFlag("GVKira").BoolValue(); + break; + case "mast": + flag = BurikoMemory.Instance.GetGlobalFlag("GVMast").BoolValue(); + break; + case "mura": + flag = BurikoMemory.Instance.GetGlobalFlag("GVMura").BoolValue(); + break; + case "riho": + flag = BurikoMemory.Instance.GetGlobalFlag("GVRiho").BoolValue(); + break; + case "rmn_": + flag = BurikoMemory.Instance.GetGlobalFlag("GVRmn_").BoolValue(); + break; + case "sari": + flag = BurikoMemory.Instance.GetGlobalFlag("GVSari").BoolValue(); + break; + case "tika": + flag = BurikoMemory.Instance.GetGlobalFlag("GVTika").BoolValue(); + break; + case "yayo": + flag = BurikoMemory.Instance.GetGlobalFlag("GVYayo").BoolValue(); + break; + default: + flag = BurikoMemory.Instance.GetGlobalFlag("GVOther").BoolValue(); + break; + } + if (!flag) + { + AudioLayer audio = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, channel)]; + if (currentAudio[AudioType.Voice].ContainsKey(channel)) + { + currentAudio[AudioType.Voice].Remove(channel); + } + currentAudio[AudioType.Voice].Add(channel, new AudioInfo(volume, filename)); + if (audio.IsPlaying()) + { + audio.StopAudio(); + } + audio.PlayAudio(filename, AudioType.Voice, volume); + if (GameSystem.Instance.IsAuto) + { + audio.OnLoadCallback(delegate + { + GameSystem.Instance.AddWait(new Wait(audio.GetRemainingPlayTime(), WaitTypes.WaitForVoice, null)); + }); + } + } + } + + public void StopVoice(int channel) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, channel)]; + audioLayer.StopAudio(); + if (currentAudio[AudioType.Voice].ContainsKey(channel)) + { + currentAudio[AudioType.Voice].Remove(channel); + } + } + + public void PlaySystemSound(string filename, int channel = 0) + { + if (GameSystem.Instance.UseSystemSounds) + { + PlayAudio(filename, AudioType.System, channel, 0.7f, 0f); + } + } + + public void StopAllVoice() + { + for (int i = 0; i < 8; i++) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, i)]; + if (audioLayer.IsPlaying()) + { + audioLayer.StopAudio(); + } + } + } + + public void StopAllAudio() + { + for (int i = 0; i < 6; i++) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.BGM, i)]; + if (audioLayer.IsPlaying()) + { + audioLayer.StopAudio(); + } + } + for (int j = 0; j < 8; j++) + { + AudioLayer audioLayer2 = channelDictionary[GetChannelByTypeChannel(AudioType.SE, j)]; + if (audioLayer2.IsPlaying()) + { + audioLayer2.StopAudio(); + } + } + for (int k = 0; k < 8; k++) + { + AudioLayer audioLayer3 = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, k)]; + if (audioLayer3.IsPlaying()) + { + audioLayer3.StopAudio(); + } + } + } + + public void PlayAudio(string filename, AudioType type, int channel, float volume, float fadeintime = 0) + { + float startvolume = volume; + if (fadeintime > 0f) + { + fadeintime /= 1000f; + startvolume = 0f; + } + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(type, channel)]; + if (audioLayer.IsPlaying()) + { + audioLayer.StopAudio(); + } + bool loop = type == AudioType.BGM; + if (type == AudioType.BGM) + { + if (currentAudio[AudioType.BGM].ContainsKey(channel)) + { + currentAudio[AudioType.BGM].Remove(channel); + } + currentAudio[AudioType.BGM].Add(channel, new AudioInfo(volume, filename)); + } + audioLayer.PlayAudio(filename, type, startvolume, loop); + if (fadeintime > 0.05f) + { + audioLayer.StartVolumeFade(volume, fadeintime); + } + } + + private int GetChannelByTypeChannel(AudioType type, int ch) + { + switch (type) + { + case AudioType.BGM: + return ch; + case AudioType.Voice: + return ch + 6; + case AudioType.SE: + return ch + 6 + 8; + case AudioType.System: + return ch + 6 + 8 + 8; + default: + throw new InvalidEnumArgumentException("GetChannelByTypeChannel: Invalid audiotype " + type); + } + } + + public float GetVolumeByType(AudioType type) + { + switch (type) + { + case AudioType.BGM: + return GlobalVolume * BGMVolume; + case AudioType.Voice: + return GlobalVolume * VoiceVolume; + case AudioType.SE: + return GlobalVolume * SoundVolume; + case AudioType.System: + return GlobalVolume * SystemVolume; + default: + Logger.LogWarning("GetVolumeByType called with unidentified audio type: " + type); + return 0f; + } + } + + public int GetPriorityByType(AudioType audioType) + { + switch (audioType) + { + case AudioType.BGM: + return 128; + case AudioType.Voice: + return 64; + case AudioType.SE: + return 32; + case AudioType.System: + return 16; + default: + Logger.LogWarning("GetPriorityByType called with unidentified audio type: " + audioType); + return 1; + } + } + + public void RefreshLayerVolumes() + { + for (int i = 0; i < 6; i++) + { + AudioLayer audioLayer = channelDictionary[GetChannelByTypeChannel(AudioType.BGM, i)]; + audioLayer.SetBaseVolume(BGMVolume * GlobalVolume); + } + for (int j = 0; j < 8; j++) + { + AudioLayer audioLayer2 = channelDictionary[GetChannelByTypeChannel(AudioType.Voice, j)]; + audioLayer2.SetBaseVolume(VoiceVolume * GlobalVolume); + } + for (int k = 0; k < 8; k++) + { + AudioLayer audioLayer3 = channelDictionary[GetChannelByTypeChannel(AudioType.SE, k)]; + audioLayer3.SetBaseVolume(SoundVolume * GlobalVolume); + } + for (int l = 0; l < 2; l++) + { + AudioLayer audioLayer4 = channelDictionary[GetChannelByTypeChannel(AudioType.System, l)]; + audioLayer4.SetBaseVolume(SystemVolume * GlobalVolume); + } + } + } +} diff --git a/Assets.Scripts.Core.Audio/AudioFinishCallback.cs b/Assets.Scripts.Core.Audio/AudioFinishCallback.cs new file mode 100644 index 00000000..2e4ae33e --- /dev/null +++ b/Assets.Scripts.Core.Audio/AudioFinishCallback.cs @@ -0,0 +1,4 @@ +namespace Assets.Scripts.Core.Audio +{ + public delegate void AudioFinishCallback(); +} diff --git a/Assets.Scripts.Core.Audio/AudioInfo.cs b/Assets.Scripts.Core.Audio/AudioInfo.cs new file mode 100644 index 00000000..e05dc935 --- /dev/null +++ b/Assets.Scripts.Core.Audio/AudioInfo.cs @@ -0,0 +1,18 @@ +using System; + +namespace Assets.Scripts.Core.Audio +{ + [Serializable] + public class AudioInfo + { + public float Volume; + + public string Filename; + + public AudioInfo(float volume, string filename) + { + Volume = volume; + Filename = filename; + } + } +} diff --git a/Assets.Scripts.Core.Audio/AudioLayer.cs b/Assets.Scripts.Core.Audio/AudioLayer.cs new file mode 100644 index 00000000..02d8cd4b --- /dev/null +++ b/Assets.Scripts.Core.Audio/AudioLayer.cs @@ -0,0 +1,261 @@ +using Assets.Scripts.Core.AssetManagement; +using NVorbis; +using System; +using System.Collections; +using System.IO; +using System.Threading; +using UnityEngine; + +namespace Assets.Scripts.Core.Audio +{ + internal class AudioLayer : MonoBehaviour + { + private AudioController audioController; + + private AudioSource audioSource; + + private AudioClip audioClip; + + private VorbisReader vorbisReader; + + private AudioFinishCallback finishCallback; + + private OnFinishLoad onFinishLoad; + + private bool isReady; + + private bool isLoop; + + private AudioType audioType; + + private float volume = 0.5f; + + private float subVolume = 1f; + + private long loopPoint; + + private byte[] bytes; + + private float[] chvolume = new float[2] + { + 1f, + 1f + }; + + private Thread loadThread; + + private bool isLoading; + + private bool isLoaded; + + public int pages; + + public void OnAudioFilterRead(float[] data, int ch) + { + if (isReady) + { + int num = vorbisReader.ReadSamples(data, 0, data.Length); + if (num != data.Length && vorbisReader.DecodedPosition >= vorbisReader.TotalSamples && isLoop) + { + vorbisReader.DecodedPosition = loopPoint; + num += vorbisReader.ReadSamples(data, num, data.Length - num); + } + for (int i = 0; i < num; i++) + { + data[i] = data[i] * volume * subVolume * chvolume[i % 2]; + } + } + } + + public void Prepare(int newid) + { + audioController = AudioController.Instance; + } + + public void RegisterCallback(AudioFinishCallback callback) + { + finishCallback = (AudioFinishCallback)Delegate.Combine(finishCallback, callback); + } + + public void SetBaseVolume(float val) + { + volume = val; + } + + public void SetCurrentVolume(float val) + { + subVolume = val; + } + + public void StartVolumeFade(float end, float time) + { + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("from", subVolume, "to", end, "time", time, "onupdate", "SetCurrentVolume", "oncomplete", "SetCurrentVolume", "oncompleteparams", end)); + } + + public void FadeOut(float time) + { + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("from", subVolume, "to", 0, "time", time, "onupdate", "SetCurrentVolume", "oncomplete", "StopAudio")); + } + + public void UpdatePan(float pan) + { + } + + public void StopAudio() + { + if (loadThread != null && loadThread.IsAlive) + { + loadThread.Abort(); + } + isReady = false; + isLoading = false; + isLoaded = false; + if (audioSource != null) + { + audioSource.Stop(); + } + if (vorbisReader != null) + { + vorbisReader.Dispose(); + } + vorbisReader = null; + bytes = null; + iTween.Stop(base.gameObject); + } + + public bool IsPlaying() + { + return vorbisReader != null; + } + + public float GetRemainingPlayTime() + { + if (audioSource.loop) + { + return -1f; + } + long decodedPosition = vorbisReader.DecodedPosition; + long totalSamples = vorbisReader.TotalSamples; + return (float)(totalSamples - decodedPosition) / (float)vorbisReader.SampleRate; + } + + private IEnumerator WaitForLoad() + { + yield return (object)new WaitForFixedUpdate(); + yield return (object)new WaitForFixedUpdate(); + IVorbisStreamStatus[] stats = vorbisReader.Stats; + foreach (IVorbisStreamStatus s in stats) + { + Debug.Log(s.TotalPages); + } + isReady = true; + } + + public void PlayAudio(string filename, AudioType type, float startvolume = 1f, bool loop = false) + { + if (IsPlaying()) + { + StopAudio(); + } + isLoading = true; + isLoaded = false; + loopPoint = 0L; + loadThread = new Thread((ThreadStart)delegate + { + audioType = type; + subVolume = startvolume; + isLoop = loop; + bytes = AssetManager.Instance.GetAudioFile(filename, type); + isLoading = false; + isLoaded = true; + }); + loadThread.Start(); + } + + public void OnLoadCallback(OnFinishLoad callback) + { + if (isReady) + { + callback(); + } + else + { + onFinishLoad = (OnFinishLoad)Delegate.Combine(onFinishLoad, callback); + } + } + + private void OnFinishLoading() + { + if (bytes != null) + { + if (audioSource == null) + { + audioSource = base.gameObject.AddComponent(); + } + if (audioController == null) + { + audioController = AudioController.Instance; + } + vorbisReader = new VorbisReader(new MemoryStream(bytes), closeStreamOnDispose: true); + if (audioClip == null) + { + audioClip = AudioClip.Create("Audio Clip", 1000, vorbisReader.Channels, vorbisReader.SampleRate, _3D: false, stream: true); + } + audioSource.clip = audioClip; + audioSource.loop = isLoop; + audioSource.priority = audioController.GetPriorityByType(audioType); + volume = audioController.GetVolumeByType(audioType) * subVolume; + audioSource.Play(); + isLoop = audioSource.loop; + pages = vorbisReader.Stats[0].TotalPages; + isReady = true; + if (onFinishLoad != null) + { + onFinishLoad(); + } + onFinishLoad = null; + } + } + + private void OnAudioEnd() + { + if (finishCallback != null) + { + finishCallback(); + } + finishCallback = null; + StopAudio(); + } + + private void Start() + { + audioController = AudioController.Instance; + } + + private void Update() + { + if (!isLoading && isLoaded && !isReady) + { + OnFinishLoading(); + } + if (isReady) + { + volume = audioController.GetVolumeByType(audioType); + audioSource.volume = volume * subVolume; + if (vorbisReader.DecodedPosition >= vorbisReader.TotalSamples) + { + if (audioSource.loop) + { + vorbisReader.DecodedPosition = loopPoint; + } + else + { + OnAudioEnd(); + } + } + } + } + } +} diff --git a/Assets.Scripts.Core.Audio/AudioType.cs b/Assets.Scripts.Core.Audio/AudioType.cs new file mode 100644 index 00000000..d884f58f --- /dev/null +++ b/Assets.Scripts.Core.Audio/AudioType.cs @@ -0,0 +1,13 @@ +using System; + +namespace Assets.Scripts.Core.Audio +{ + [Serializable] + public enum AudioType + { + BGM, + Voice, + SE, + System + } +} diff --git a/Assets.Scripts.Core.Audio/OnFinishLoad.cs b/Assets.Scripts.Core.Audio/OnFinishLoad.cs new file mode 100644 index 00000000..99b61778 --- /dev/null +++ b/Assets.Scripts.Core.Audio/OnFinishLoad.cs @@ -0,0 +1,4 @@ +namespace Assets.Scripts.Core.Audio +{ + public delegate void OnFinishLoad(); +} diff --git a/Assets.Scripts.Core.Buriko.Util/BurikoObjectConverter.cs b/Assets.Scripts.Core.Buriko.Util/BurikoObjectConverter.cs new file mode 100644 index 00000000..e00c183b --- /dev/null +++ b/Assets.Scripts.Core.Buriko.Util/BurikoObjectConverter.cs @@ -0,0 +1,34 @@ +using Assets.Scripts.Core.Buriko.VarTypes; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; + +namespace Assets.Scripts.Core.Buriko.Util +{ + public class BurikoObjectConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value is BurikoString) + { + JToken jToken = JToken.FromObject(value); + JObject jObject = (JObject)jToken; + jObject.AddFirst(new JProperty("type", new JArray(new string[1] + { + "BurikoString" + }))); + jToken.WriteTo(writer); + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override bool CanConvert(Type objectType) + { + return true; + } + } +} diff --git a/Assets.Scripts.Core.Buriko.Util/BurikoReference.cs b/Assets.Scripts.Core.Buriko.Util/BurikoReference.cs new file mode 100644 index 00000000..c3f2fea7 --- /dev/null +++ b/Assets.Scripts.Core.Buriko.Util/BurikoReference.cs @@ -0,0 +1,17 @@ +namespace Assets.Scripts.Core.Buriko.Util +{ + public class BurikoReference + { + public string Property; + + public int Member; + + public BurikoReference Reference; + + public BurikoReference(string property, int member) + { + Property = property; + Member = member; + } + } +} diff --git a/Assets.Scripts.Core.Buriko.Util/IBurikoObject.cs b/Assets.Scripts.Core.Buriko.Util/IBurikoObject.cs new file mode 100644 index 00000000..ad1b8540 --- /dev/null +++ b/Assets.Scripts.Core.Buriko.Util/IBurikoObject.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.IO; + +namespace Assets.Scripts.Core.Buriko.Util +{ + public interface IBurikoObject + { + void Create(int members); + + int MemberCount(); + + IEnumerator GetObjects(); + + BurikoVariable GetObject(BurikoReference reference); + + void SetValue(BurikoReference reference, BurikoVariable var); + + string GetObjectType(); + + void Serialize(MemoryStream ms); + + void DeSerialize(MemoryStream ms); + + string StringValue(BurikoReference reference); + + int IntValue(BurikoReference reference); + } +} diff --git a/Assets.Scripts.Core.Buriko.VarTypes/BurikoInt.cs b/Assets.Scripts.Core.Buriko.VarTypes/BurikoInt.cs new file mode 100644 index 00000000..d73f95b1 --- /dev/null +++ b/Assets.Scripts.Core.Buriko.VarTypes/BurikoInt.cs @@ -0,0 +1,99 @@ +using Assets.Scripts.Core.Buriko.Util; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Assets.Scripts.Core.Buriko.VarTypes +{ + [Serializable] + internal class BurikoInt : IBurikoObject + { + public List intlist; + + public void Create(int members) + { + intlist = new List(); + for (int i = 0; i < members; i++) + { + intlist.Add(0); + } + } + + public int MemberCount() + { + return intlist.Count; + } + + public IEnumerator GetObjects() + { + return (from s in intlist + select new BurikoVariable(s)).GetEnumerator(); + } + + public BurikoVariable GetObject(BurikoReference reference) + { + return new BurikoVariable(intlist[reference.Member]); + } + + public void SetValue(BurikoReference reference, BurikoVariable var) + { + if (reference.Member <= 0) + { + intlist[0] = var.IntValue(); + } + else + { + intlist[reference.Member] = var.IntValue(); + } + } + + public string GetObjectType() + { + return "Integer"; + } + + public void Serialize(MemoryStream ms) + { + if (intlist == null) + { + throw new Exception("Cannot serialize while Stringlist is null!"); + } + BsonWriter bsonWriter = new BsonWriter(ms); + bsonWriter.CloseOutput = false; + using (BsonWriter jsonWriter = bsonWriter) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.Serialize(jsonWriter, intlist); + } + } + + public void DeSerialize(MemoryStream ms) + { + BsonReader bsonReader = new BsonReader(ms); + bsonReader.CloseInput = false; + bsonReader.ReadRootValueAsArray = true; + using (BsonReader reader = bsonReader) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + intlist = jsonSerializer.Deserialize>(reader); + } + } + + public string StringValue(BurikoReference reference) + { + throw new NotImplementedException(); + } + + public int IntValue(BurikoReference reference) + { + if (reference.Member <= 0) + { + return intlist[0]; + } + return intlist[reference.Member]; + } + } +} diff --git a/Assets.Scripts.Core.Buriko.VarTypes/BurikoMtnCtrlElement.cs b/Assets.Scripts.Core.Buriko.VarTypes/BurikoMtnCtrlElement.cs new file mode 100644 index 00000000..278211a3 --- /dev/null +++ b/Assets.Scripts.Core.Buriko.VarTypes/BurikoMtnCtrlElement.cs @@ -0,0 +1,162 @@ +using Assets.Scripts.Core.Buriko.Util; +using Assets.Scripts.Core.Scene; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Assets.Scripts.Core.Buriko.VarTypes +{ + internal class BurikoMtnCtrlElement : IBurikoObject + { + public List Elements; + + public void Create(int members) + { + Elements = new List(); + for (int i = 0; i < members; i++) + { + Elements.Add(new MtnCtrlElement()); + } + } + + public int MemberCount() + { + return Elements.Count; + } + + public IEnumerator GetObjects() + { + throw new NotImplementedException(); + } + + public BurikoVariable GetObject(BurikoReference reference) + { + throw new NotImplementedException(); + } + + public void SetValue(BurikoReference reference, BurikoVariable var) + { + int num = reference.Member; + if (num == -1) + { + num = 0; + } + MtnCtrlElement mtnCtrlElement = Elements[num]; + if (reference.Reference == null) + { + BurikoReference burikoReference = var.VariableValue(); + BurikoMtnCtrlElement burikoMtnCtrlElement = BurikoMemory.Instance.GetMemory(burikoReference.Property) as BurikoMtnCtrlElement; + if (burikoMtnCtrlElement == null) + { + throw new Exception("Attempting to set MtnCtrlElement with a variable that is not also a MtnCtrlElement!"); + } + int num2 = burikoReference.Member; + if (num2 == -1) + { + num2 = 0; + } + Elements[num].CopyFrom(burikoMtnCtrlElement.GetElement(num2)); + } + else + { + BurikoReference reference2 = reference.Reference; + switch (reference2.Property) + { + case "lPoints": + mtnCtrlElement.Points = var.IntValue(); + break; + case "lAngle": + mtnCtrlElement.Angle = var.IntValue(); + break; + case "lTransparency": + mtnCtrlElement.Transparancy = var.IntValue(); + break; + case "lStyleOfMovements": + mtnCtrlElement.StyleOfMovement = var.IntValue(); + break; + case "lStyleOfRotating": + mtnCtrlElement.StyleOfRotation = var.IntValue(); + break; + case "lCount": + mtnCtrlElement.Time = var.IntValue(); + break; + case "astvRoute": + { + int member = reference2.Member; + BurikoReference reference3 = reference2.Reference; + switch (reference3.Property) + { + case "lX": + mtnCtrlElement.Route[member].x = (float)var.IntValue(); + break; + case "lY": + mtnCtrlElement.Route[member].y = (float)var.IntValue(); + break; + case "lZ": + mtnCtrlElement.Route[member].z = (float)var.IntValue(); + break; + default: + Logger.LogError("Invalid property of MtnCtrlElement.astvRoute " + reference3.Property); + break; + } + break; + } + default: + Logger.LogError("Invalid property of MtnCtrlElement " + reference2.Property); + break; + } + } + } + + public string GetObjectType() + { + return "MtnCtrlElement"; + } + + public void Serialize(MemoryStream ms) + { + BsonWriter bsonWriter = new BsonWriter(ms); + bsonWriter.CloseOutput = false; + using (BsonWriter bsonWriter2 = bsonWriter) + { + bsonWriter2.CloseOutput = false; + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.Serialize(bsonWriter2, Elements); + } + } + + public void DeSerialize(MemoryStream ms) + { + BsonReader bsonReader = new BsonReader(ms); + bsonReader.CloseInput = false; + bsonReader.ReadRootValueAsArray = true; + using (BsonReader reader = bsonReader) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + Elements = jsonSerializer.Deserialize>(reader); + } + } + + public string StringValue(BurikoReference reference) + { + throw new NotImplementedException(); + } + + public int IntValue(BurikoReference reference) + { + throw new NotImplementedException(); + } + + public MtnCtrlElement GetElement(int id) + { + return Elements[id]; + } + + public MtnCtrlElement[] GetAllElements() + { + return Elements.ToArray(); + } + } +} diff --git a/Assets.Scripts.Core.Buriko.VarTypes/BurikoString.cs b/Assets.Scripts.Core.Buriko.VarTypes/BurikoString.cs new file mode 100644 index 00000000..57c98df2 --- /dev/null +++ b/Assets.Scripts.Core.Buriko.VarTypes/BurikoString.cs @@ -0,0 +1,104 @@ +using Assets.Scripts.Core.Buriko.Util; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Assets.Scripts.Core.Buriko.VarTypes +{ + [Serializable] + internal class BurikoString : IBurikoObject + { + public List Stringlist; + + public void Create(int members) + { + Stringlist = new List(); + for (int i = 0; i < members; i++) + { + Stringlist.Add(string.Empty); + } + } + + public int MemberCount() + { + return Stringlist.Count; + } + + public IEnumerator GetObjects() + { + return (from s in Stringlist + select new BurikoVariable(s)).GetEnumerator(); + } + + public BurikoVariable GetObject(BurikoReference reference) + { + return new BurikoVariable(Stringlist[reference.Member]); + } + + public void SetValue(BurikoReference reference, BurikoVariable var) + { + if (reference.Member <= 0) + { + Stringlist[0] = var.StringValue(); + } + else + { + Stringlist[reference.Member] = var.StringValue(); + } + } + + public string GetObjectType() + { + return "String"; + } + + public void Serialize(MemoryStream ms) + { + if (Stringlist == null) + { + throw new Exception("Cannot serialize while Stringlist is null!"); + } + BsonWriter bsonWriter = new BsonWriter(ms); + bsonWriter.CloseOutput = false; + using (BsonWriter jsonWriter = bsonWriter) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.Serialize(jsonWriter, Stringlist); + } + } + + public void DeSerialize(MemoryStream ms) + { + BsonReader bsonReader = new BsonReader(ms); + bsonReader.CloseInput = false; + bsonReader.ReadRootValueAsArray = true; + using (BsonReader reader = bsonReader) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + Stringlist = jsonSerializer.Deserialize>(reader); + } + } + + public string StringValue(BurikoReference reference) + { + if (reference.Member <= 0) + { + return Stringlist[0]; + } + return Stringlist[reference.Member]; + } + + public int IntValue(BurikoReference reference) + { + throw new NotImplementedException(); + } + + public List GetStringList() + { + return Stringlist; + } + } +} diff --git a/Assets.Scripts.Core.Buriko.VarTypes/BurikoVector.cs b/Assets.Scripts.Core.Buriko.VarTypes/BurikoVector.cs new file mode 100644 index 00000000..deeded5e --- /dev/null +++ b/Assets.Scripts.Core.Buriko.VarTypes/BurikoVector.cs @@ -0,0 +1,135 @@ +using Assets.Scripts.Core.Buriko.Util; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.Core.Buriko.VarTypes +{ + [Serializable] + internal class BurikoVector : IBurikoObject + { + public List Elements; + + public void Create(int members) + { + Elements = new List(); + for (int i = 0; i < members; i++) + { + Elements.Add(Vector3.zero); + } + } + + public int MemberCount() + { + return Elements.Count; + } + + public IEnumerator GetObjects() + { + throw new NotImplementedException(); + } + + public BurikoVariable GetObject(BurikoReference reference) + { + throw new NotImplementedException(); + } + + public void SetValue(BurikoReference reference, BurikoVariable var) + { + int num = reference.Member; + if (num == -1) + { + num = 0; + } + Vector3 value = Elements[num]; + BurikoReference reference2 = reference.Reference; + switch (reference2.Property) + { + case "lX": + value.x = (float)var.IntValue(); + break; + case "lY": + value.y = (float)var.IntValue(); + break; + case "lZ": + value.z = (float)var.IntValue(); + break; + default: + Logger.LogError("Cannot set propertly " + reference2.Property + " on a ST_Vector object!"); + break; + } + Elements[num] = value; + } + + public string GetObjectType() + { + return "Vector"; + } + + public void Serialize(MemoryStream ms) + { + BsonWriter bsonWriter = new BsonWriter(ms); + bsonWriter.CloseOutput = false; + using (BsonWriter bsonWriter2 = bsonWriter) + { + bsonWriter2.CloseOutput = false; + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.Serialize(bsonWriter2, Elements); + } + } + + public void DeSerialize(MemoryStream ms) + { + BsonReader bsonReader = new BsonReader(ms); + bsonReader.CloseInput = false; + bsonReader.ReadRootValueAsArray = true; + using (BsonReader reader = bsonReader) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + Elements = jsonSerializer.Deserialize>(reader); + } + } + + public string StringValue(BurikoReference reference) + { + throw new NotImplementedException(); + } + + public int IntValue(BurikoReference reference) + { + int num = reference.Member; + if (num == -1) + { + num = 0; + } + Vector3 vector = Elements[num]; + BurikoReference reference2 = reference.Reference; + switch (reference2.Property) + { + case "lX": + return (int)vector.x; + case "lY": + return -(int)vector.y; + case "lZ": + return (int)vector.z; + default: + Logger.LogError("Cannot set propertly " + reference2.Property + " on a ST_Vector object!"); + return 0; + } + } + + public Vector3[] GetElements(int count) + { + Vector3[] array = new Vector3[count]; + for (int i = 0; i < count; i++) + { + array[i] = Elements[i]; + Debug.Log(Elements[i]); + } + return array; + } + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoCommands.cs b/Assets.Scripts.Core.Buriko/BurikoCommands.cs new file mode 100644 index 00000000..4197f846 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoCommands.cs @@ -0,0 +1,13 @@ +namespace Assets.Scripts.Core.Buriko +{ + public enum BurikoCommands + { + Return, + LineNum, + Operation, + If, + Declaration, + Assignment, + Jump + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoMathType.cs b/Assets.Scripts.Core.Buriko/BurikoMathType.cs new file mode 100644 index 00000000..1ec50bad --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoMathType.cs @@ -0,0 +1,17 @@ +namespace Assets.Scripts.Core.Buriko +{ + public enum BurikoMathType + { + Equals, + NotEquals, + LessThanOrEquals, + GreaterThanOrEquals, + LessThan, + GreaterThan, + Add, + Subtract, + Multiply, + Divide, + Modulus + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoMemory.cs b/Assets.Scripts.Core.Buriko/BurikoMemory.cs new file mode 100644 index 00000000..84ddeec6 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoMemory.cs @@ -0,0 +1,439 @@ +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Buriko.Util; +using Assets.Scripts.Core.Buriko.VarTypes; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; + +namespace Assets.Scripts.Core.Buriko +{ + internal class BurikoMemory + { + private const int FlagCount = 11; + + private Dictionary memorylist = new Dictionary(); + + private Dictionary variableReference = new Dictionary(); + + private Dictionary flags = new Dictionary(); + + private Dictionary globalFlags = new Dictionary(); + + private Dictionary> readText = new Dictionary>(); + + private List cgflags = new List(); + + private int scopeLevel; + + public static BurikoMemory Instance + { + get; + private set; + } + + public BurikoMemory() + { + memorylist = new Dictionary(); + variableReference.Add("LOCALWORK_NO_RESULT", 0); + variableReference.Add("TipsMode", 1); + variableReference.Add("ChapterNumber", 10); + variableReference.Add("LOnikakushiDay", 30); + variableReference.Add("LTextFade", 31); + variableReference.Add("GFlag_FirstPlay", 0); + variableReference.Add("GFlag_GameClear", 1); + variableReference.Add("GQsaveNum", 2); + variableReference.Add("GOnikakushiDay", 3); + variableReference.Add("GMessageSpeed", 10); + variableReference.Add("GAutoSpeed", 11); + variableReference.Add("GAutoAdvSpeed", 12); + variableReference.Add("GUsePrompts", 13); + variableReference.Add("GSlowSkip", 14); + variableReference.Add("GSkipUnread", 15); + variableReference.Add("GClickDuringAuto", 16); + variableReference.Add("GRightClickMenu", 17); + variableReference.Add("GWindowOpacity", 18); + variableReference.Add("GVoiceVolume", 19); + variableReference.Add("GBGMVolume", 20); + variableReference.Add("GSEVolume", 21); + variableReference.Add("GCutVoiceOnClick", 22); + variableReference.Add("GUseSystemSound", 23); + variableReference.Add("GLanguage", 24); + variableReference.Add("GVChie", 30); + variableReference.Add("GVEiji", 31); + variableReference.Add("GVKana", 32); + variableReference.Add("GVKira", 33); + variableReference.Add("GVMast", 34); + variableReference.Add("GVMura", 35); + variableReference.Add("GVRiho", 36); + variableReference.Add("GVRmn_", 37); + variableReference.Add("GVSari", 38); + variableReference.Add("GVTika", 39); + variableReference.Add("GVYayo", 40); + variableReference.Add("GVOther", 41); + variableReference.Add("GArtStyle", 50); + variableReference.Add("GHideButtons", 51); + SetGlobalFlag("GMessageSpeed", 50); + SetGlobalFlag("GAutoSpeed", 50); + SetGlobalFlag("GAutoAdvSpeed", 50); + SetGlobalFlag("GWindowOpacity", 50); + SetGlobalFlag("GUsePrompts", 1); + SetGlobalFlag("GSlowSkip", 0); + SetGlobalFlag("GSkipUnread", 0); + SetGlobalFlag("GClickDuringAuto", 0); + SetGlobalFlag("GRightClickMenu", 1); + SetGlobalFlag("GVoiceVolume", 75); + SetGlobalFlag("GBGMVolume", 50); + SetGlobalFlag("GSEVolume", 50); + SetGlobalFlag("GCutVoiceOnClick", 0); + SetGlobalFlag("GUseSystemSound", 1); + SetGlobalFlag("GLanguage", 1); + SetGlobalFlag("GVChie", 1); + SetGlobalFlag("GVEiji", 1); + SetGlobalFlag("GVKana", 1); + SetGlobalFlag("GVKira", 1); + SetGlobalFlag("GVMast", 1); + SetGlobalFlag("GVMura", 1); + SetGlobalFlag("GVRiho", 1); + SetGlobalFlag("GVRmn_", 1); + SetGlobalFlag("GVSari", 1); + SetGlobalFlag("GVTika", 1); + SetGlobalFlag("GVYayo", 1); + SetGlobalFlag("GVOther", 1); + SetGlobalFlag("GArtStyle", 1); + SetGlobalFlag("GHideButtons", 0); + SetFlag("LTextFade", 1); + Instance = this; + LoadGlobals(); + } + + private void LoadFlags() + { + for (int i = 0; i < 11; i++) + { + flags.Add(i, 0); + } + } + + public void AddScope() + { + scopeLevel++; + } + + public void DropScope() + { + int count = memorylist.Count; + scopeLevel--; + memorylist = (from a in memorylist + where a.Value.Scope <= scopeLevel + select a).ToDictionary((KeyValuePair a) => a.Key, (KeyValuePair a) => a.Value); + Debug.Log($"Dropping scope changed the number of objects in memory from {count} to {memorylist.Count}"); + } + + public void ResetScope() + { + scopeLevel = 0; + memorylist = (from a in memorylist + where a.Value.Scope <= scopeLevel + select a).ToDictionary((KeyValuePair a) => a.Key, (KeyValuePair a) => a.Value); + } + + public bool SeenCG(string cg) + { + return cgflags.Contains(cg); + } + + public void SetCGFlag(string cg) + { + if (!cgflags.Contains(cg)) + { + cgflags.Add(cg); + } + } + + public void SetFlag(string flagname, int val) + { + if (!variableReference.TryGetValue(flagname, out int value)) + { + throw new Exception("Unable to set flag with the name " + flagname + ", flag not found."); + } + if (!flags.ContainsKey(value)) + { + flags.Add(value, val); + } + else + { + flags[value] = val; + } + } + + public void SetGlobalFlag(string flagname, int val) + { + if (!variableReference.TryGetValue(flagname, out int value)) + { + throw new Exception("Unable to set flag with the name " + flagname + ", flag not found."); + } + if (!globalFlags.ContainsKey(value)) + { + globalFlags.Add(value, val); + } + else + { + globalFlags[value] = val; + } + } + + public bool IsFlag(string name) + { + if (!variableReference.ContainsKey(name)) + { + return false; + } + return true; + } + + public BurikoVariable GetFlag(string flagname) + { + if (!variableReference.TryGetValue(flagname, out int value)) + { + throw new Exception("Unable to get flag with the name " + flagname + ", flag not found."); + } + return new BurikoVariable(flags[value]); + } + + public BurikoVariable GetGlobalFlag(string flagname) + { + if (!variableReference.TryGetValue(flagname, out int value)) + { + throw new Exception("Unable to get global flag with the name " + flagname + ", flag not found."); + } + if (!globalFlags.ContainsKey(value)) + { + return new BurikoVariable(0); + } + return new BurikoVariable(globalFlags[value]); + } + + public void MarkLineAsRead(string scriptname, int line) + { + if (!readText.ContainsKey(scriptname)) + { + readText.Add(scriptname, new List()); + } + List list = readText[scriptname]; + if (!list.Contains(line)) + { + list.Add(line); + } + } + + public bool IsLineRead(string scriptname, int line) + { + if (!readText.ContainsKey(scriptname)) + { + return false; + } + if (readText[scriptname].Contains(line)) + { + return true; + } + return false; + } + + public bool HasReadScript(string scriptname) + { + return readText.ContainsKey(scriptname); + } + + public bool IsMemory(string name) + { + if (!memorylist.ContainsKey(name)) + { + return false; + } + return true; + } + + public IBurikoObject GetMemory(string name) + { + if (!memorylist.TryGetValue(name, out BurikoMemoryEntry value)) + { + throw new Exception("Unable to GetMemory the variable with the name " + name); + } + return value.Obj; + } + + public void AddMemory(string name, IBurikoObject obj) + { + memorylist.Add(name, new BurikoMemoryEntry(scopeLevel, obj)); + } + + public byte[] SaveMemory() + { + using (MemoryStream memoryStream = new MemoryStream()) + { + using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) + { + BsonWriter bsonWriter = new BsonWriter(memoryStream); + bsonWriter.CloseOutput = false; + using (BsonWriter jsonWriter = bsonWriter) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + binaryWriter.Write(memorylist.Count); + foreach (KeyValuePair item in memorylist) + { + binaryWriter.Write(item.Key); + binaryWriter.Write(item.Value.Scope); + binaryWriter.Write(item.Value.Obj.GetObjectType()); + item.Value.Obj.Serialize(memoryStream); + } + jsonSerializer.Serialize(jsonWriter, variableReference); + jsonSerializer.Serialize(jsonWriter, flags); + return memoryStream.ToArray(); + } + } + } + } + + public void LoadMemory(MemoryStream ms) + { + memorylist.Clear(); + flags.Clear(); + BinaryReader binaryReader = new BinaryReader(ms); + JsonSerializer jsonSerializer = new JsonSerializer(); + int num = binaryReader.ReadInt32(); + for (int i = 0; i < num; i++) + { + string key = binaryReader.ReadString(); + int scope = binaryReader.ReadInt32(); + string text = binaryReader.ReadString(); + IBurikoObject burikoObject; + switch (text) + { + case "String": + burikoObject = new BurikoString(); + break; + case "MtnCtrlElement": + burikoObject = new BurikoMtnCtrlElement(); + break; + case "Integer": + burikoObject = new BurikoInt(); + break; + case "Vector": + burikoObject = new BurikoVector(); + break; + default: + throw new InvalidDataException("Cannot populate Buriko Object of type " + text); + } + burikoObject.DeSerialize(ms); + memorylist.Add(key, new BurikoMemoryEntry(scope, burikoObject)); + } + BsonReader bsonReader = new BsonReader(ms); + bsonReader.CloseInput = false; + using (BsonReader reader = bsonReader) + { + variableReference = jsonSerializer.Deserialize>(reader); + } + bsonReader = new BsonReader(ms); + bsonReader.CloseInput = false; + using (BsonReader reader2 = bsonReader) + { + flags = jsonSerializer.Deserialize>(reader2); + } + } + + public void LoadGlobals() + { + string path = Path.Combine(MGHelper.GetSavePath(), "global.dat"); + if (!File.Exists(path)) + { + SetGlobalFlag("GUsePrompts", 1); + } + else + { + byte[] array = File.ReadAllBytes(path); + MGHelper.KeyEncode(array); + byte[] buffer = CLZF2.Decompress(array); + try + { + JsonSerializer jsonSerializer = new JsonSerializer(); + using (MemoryStream stream = new MemoryStream(buffer)) + { + BsonReader bsonReader = new BsonReader(stream); + bsonReader.CloseInput = false; + using (BsonReader reader = bsonReader) + { + globalFlags = jsonSerializer.Deserialize>(reader); + } + bsonReader = new BsonReader(stream); + bsonReader.CloseInput = false; + bsonReader.ReadRootValueAsArray = true; + using (BsonReader reader2 = bsonReader) + { + cgflags = jsonSerializer.Deserialize>(reader2); + } + bsonReader = new BsonReader(stream); + bsonReader.CloseInput = false; + using (BsonReader reader3 = bsonReader) + { + readText = jsonSerializer.Deserialize>>(reader3); + } + } + } + catch (Exception arg) + { + Debug.LogWarning("Failed to load global data! Exception: " + arg); + return; + IL_0128:; + } + try + { + GameSystem.Instance.TextController.TextSpeed = GetGlobalFlag("GMessageSpeed").IntValue(); + GameSystem.Instance.TextController.AutoSpeed = GetGlobalFlag("GAutoSpeed").IntValue(); + GameSystem.Instance.TextController.AutoPageSpeed = GetGlobalFlag("GAutoAdvSpeed").IntValue(); + GameSystem.Instance.MessageWindowOpacity = (float)GetGlobalFlag("GWindowOpacity").IntValue() / 100f; + GameSystem.Instance.UsePrompts = GetGlobalFlag("GUsePrompts").BoolValue(); + GameSystem.Instance.SkipModeDelay = GetGlobalFlag("GSlowSkip").BoolValue(); + GameSystem.Instance.SkipUnreadMessages = GetGlobalFlag("GSkipUnread").BoolValue(); + GameSystem.Instance.ClickDuringAuto = GetGlobalFlag("GClickDuringAuto").BoolValue(); + GameSystem.Instance.RightClickMenu = GetGlobalFlag("GRightClickMenu").BoolValue(); + GameSystem.Instance.AudioController.VoiceVolume = (float)GetGlobalFlag("GVoiceVolume").IntValue() / 100f; + GameSystem.Instance.AudioController.BGMVolume = (float)GetGlobalFlag("GBGMVolume").IntValue() / 100f; + GameSystem.Instance.AudioController.SoundVolume = (float)GetGlobalFlag("GSEVolume").IntValue() / 100f; + GameSystem.Instance.AudioController.SystemVolume = (float)GetGlobalFlag("GSEVolume").IntValue() / 100f; + GameSystem.Instance.StopVoiceOnClick = GetGlobalFlag("GCutVoiceOnClick").BoolValue(); + GameSystem.Instance.UseSystemSounds = GetGlobalFlag("GUseSystemSound").BoolValue(); + GameSystem.Instance.UseEnglishText = GetGlobalFlag("GLanguage").BoolValue(); + AssetManager.Instance.UseNewArt = GetGlobalFlag("GArtStyle").BoolValue(); + GameSystem.Instance.AudioController.RefreshLayerVolumes(); + } + catch (Exception message) + { + Debug.LogWarning(message); + } + } + } + + public void SaveGlobals() + { + byte[] inputBytes; + using (MemoryStream memoryStream = new MemoryStream()) + { + using (BsonWriter jsonWriter = new BsonWriter(memoryStream)) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.Serialize(jsonWriter, globalFlags); + jsonSerializer.Serialize(jsonWriter, cgflags); + jsonSerializer.Serialize(jsonWriter, readText); + inputBytes = memoryStream.ToArray(); + } + } + byte[] array = CLZF2.Compress(inputBytes); + MGHelper.KeyEncode(array); + File.WriteAllBytes(Path.Combine(MGHelper.GetSavePath(), "global.dat"), array); + } + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoMemoryEntry.cs b/Assets.Scripts.Core.Buriko/BurikoMemoryEntry.cs new file mode 100644 index 00000000..5149188e --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoMemoryEntry.cs @@ -0,0 +1,17 @@ +using Assets.Scripts.Core.Buriko.Util; + +namespace Assets.Scripts.Core.Buriko +{ + internal class BurikoMemoryEntry + { + public int Scope; + + public IBurikoObject Obj; + + public BurikoMemoryEntry(int scope, IBurikoObject obj) + { + Scope = scope; + Obj = obj; + } + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoOperations.cs b/Assets.Scripts.Core.Buriko/BurikoOperations.cs new file mode 100644 index 00000000..937a890c --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoOperations.cs @@ -0,0 +1,129 @@ +namespace Assets.Scripts.Core.Buriko +{ + public enum BurikoOperations + { + NullOp = -1, + StoreValueToLocalWork, + LoadValueFromLocalWork, + SetLocalFlag, + SetGlobalFlag, + GetLocalFlag, + GetGlobalFlag, + CallScript, + JumpScript, + CallSection, + JumpSection, + Wait, + WaitForInput, + SetValidityOfSkipping, + SetValidityOfSaving, + SetValidityOfInput, + SetValidityOfUserEffectSpeed, + OutputLine, + OutputLineAll, + ClearMessage, + SetFontOfMessage, + SetSpeedOfMessage, + DisableWindow, + SpringText, + SetStyleOfMessageSwinging, + Select, + PlayBGM, + StopBGM, + ChangeVolumeOfBGM, + FadeOutBGM, + FadeOutMultiBGM, + PlaySE, + StopSE, + FadeOutSE, + WaitToFinishSEPlaying, + PlayVoice, + WaitToFinishVoicePlaying, + PreloadBitmap, + StartShakingOfAllObjects, + TerminateShakingOfAllObjects, + StartShakingOfWindow, + TerminateShakingOfWindow, + StartShakingOfBustshot, + TerminateShakingOfBustshot, + StartShakingOfSprite, + TerminateShakingOfSprite, + ShakeScreen, + ShakeScreenSx, + DrawBG, + FadeBG, + DrawBGWithMask, + DrawScene, + DrawSceneWithMask, + ChangeScene, + FadeScene, + FadeSceneWithMask, + DrawBustshot, + MoveBustshot, + FadeBustshot, + DrawBustshotWithFiltering, + DrawFace, + FadeFace, + ExecutePlannedControl, + DrawSprite, + DrawSpriteWithFiltering, + FadeSprite, + FadeSpriteWithFiltering, + MoveSprite, + MoveSpriteEx, + ControlMotionOfSprite, + GetPositionOfSprite, + EnableHorizontalGradation, + DisableGradation, + EnlargeScreen, + DisableEffector, + EnableBlur, + DisableBlur, + DrawFilm, + FadeFilm, + SetValidityOfFilmToFace, + FadeAllBustshots, + FadeBustshotWithFiltering, + SetDrawingPointOfMessage, + Negative, + EnableJumpingOfReturnIcon, + SetValidityOfWindowDisablingWhenGraphicsControl, + SetValidityOfInterface, + ViewTips, + ViewChapterScreen, + ViewExtras, + ChapterPreview, + SavePoint, + PlaceViewTip, + PlaceViewTip2, + DrawStandgraphic, + DrawBustFace, + PlusStandgraphic1, + PlusStandgraphic2, + PlusStandgraphic3, + FadeAllBustshots2, + FadeAllBustshots3, + BlurOffOn, + TitleScreen, + OpenGallery, + HideGallery, + RevealGallery, + CloseGallery, + SetSkipAll, + SetTextFade, + Break, + LanguagePrompt, + GetAchievement, + CheckTipsAchievements, + SetFontId, + SetCharSpacing, + SetLineSpacing, + SetFontSize, + SetWindowPos, + SetWindowSize, + SetWindowMargins, + SetNameFormat, + SetScreenAspect, + SetGuiPosition + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoSaveManager.cs b/Assets.Scripts.Core.Buriko/BurikoSaveManager.cs new file mode 100644 index 00000000..546ea753 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoSaveManager.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Assets.Scripts.Core.Buriko +{ + public class BurikoSaveManager + { + private readonly Dictionary saveList; + + public BurikoSaveManager() + { + saveList = new Dictionary(); + for (int i = 0; i < 100; i++) + { + string path = Path.Combine(MGHelper.GetSavePath(), string.Format("save{0}.dat", i.ToString("D3"))); + GetSaveData(i, path); + } + for (int j = 0; j < 3; j++) + { + string path2 = Path.Combine(MGHelper.GetSavePath(), string.Format("qsave{0}.dat", j.ToString("D1"))); + GetSaveData(j + 100, path2); + } + } + + public SaveEntry GetSaveInfoInSlot(int slot) + { + if (!saveList.ContainsKey(slot)) + { + return null; + } + return saveList[slot]; + } + + public void DeleteSave(int slot) + { + string path = Path.Combine(MGHelper.GetSavePath(), string.Format("save{0}.dat", slot.ToString("D3"))); + string path2 = Path.Combine(MGHelper.GetSavePath(), string.Format("save{0}.png", slot.ToString("D3"))); + if (File.Exists(path)) + { + File.Delete(path); + } + if (File.Exists(path2)) + { + File.Delete(path2); + } + saveList.Remove(slot); + } + + public bool IsSaveInSlot(int slot) + { + return saveList.ContainsKey(slot); + } + + private void GetSaveData(int slot, string path) + { + if (File.Exists(path)) + { + try + { + SaveEntry saveEntry = new SaveEntry(); + saveEntry.Path = path; + SaveEntry saveEntry2 = saveEntry; + byte[] array = File.ReadAllBytes(path); + MGHelper.KeyEncode(array); + byte[] buffer = CLZF2.Decompress(array); + using (MemoryStream input = new MemoryStream(buffer)) + { + using (BinaryReader binaryReader = new BinaryReader(input)) + { + string a = new string(binaryReader.ReadChars(4)); + if (a != "MGSV") + { + throw new FileLoadException("Save file does not appear to be valid! Invalid header."); + } + int num = binaryReader.ReadInt32(); + if (num != 1) + { + throw new FileLoadException("Save file does not appear to be valid! Invalid version number."); + } + saveEntry2.Time = DateTime.FromBinary(binaryReader.ReadInt64()); + string textJp = binaryReader.ReadString(); + string text = saveEntry2.Text = binaryReader.ReadString(); + saveEntry2.TextJp = textJp; + } + } + if (saveList.ContainsKey(slot)) + { + saveList.Remove(slot); + } + saveList.Add(slot, saveEntry2); + } + catch (Exception ex) + { + Logger.LogWarning("Could not read from save file " + path + "\nException: " + ex); + throw; + IL_013f:; + } + } + } + + public void UpdateSaveSlot(int slot) + { + GetSaveData(path: (slot >= 100) ? Path.Combine(MGHelper.GetSavePath(), string.Format("qsave{0}.dat", (slot - 100).ToString("D1"))) : Path.Combine(MGHelper.GetSavePath(), string.Format("save{0}.dat", slot.ToString("D3"))), slot: slot); + } + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoScriptFile.cs b/Assets.Scripts.Core.Buriko/BurikoScriptFile.cs new file mode 100644 index 00000000..1325cab6 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoScriptFile.cs @@ -0,0 +1,2238 @@ +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko.Util; +using Assets.Scripts.Core.Buriko.VarTypes; +using Assets.Scripts.Core.Scene; +using Assets.Scripts.Core.State; +using Assets.Scripts.UI.Prompt; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.Core.Buriko +{ + public class BurikoScriptFile + { + private readonly GameSystem gameSystem; + + private readonly BurikoScriptSystem scriptSystem; + + public string Filename; + + private Dictionary blockLookup = new Dictionary(); + + private Dictionary lineLookup = new Dictionary(); + + private byte[] dataSegment; + + private MemoryStream dataStream; + + private BinaryReader dataReader; + + private int dataSegmentLength; + + public int LineNum; + + private string opType = string.Empty; + + private int param; + + public bool IsInitialized; + + public int Position => (int)dataStream.Position; + + public BurikoScriptFile(BurikoScriptSystem system, string filename) + { + scriptSystem = system; + gameSystem = GameSystem.Instance; + Filename = filename; + } + + public void InitializeScript() + { + byte[] scriptData = AssetManager.Instance.GetScriptData(Filename); + MemoryStream memoryStream = new MemoryStream(scriptData); + BinaryReader binaryReader = new BinaryReader(memoryStream); + string a = new string(binaryReader.ReadChars(4)); + if (a != "MGSC") + { + throw new FileLoadException("The script file " + Filename + ".mg does not appear to be a valid script!"); + } + int num = binaryReader.ReadInt32(); + if (num != 1) + { + throw new FileLoadException("The script file " + Filename + ".mg is an incompatible script version!"); + } + int num2 = binaryReader.ReadInt32(); + int num3 = binaryReader.ReadInt32(); + dataSegmentLength = binaryReader.ReadInt32(); + for (int i = 0; i < num2; i++) + { + blockLookup.Add(binaryReader.ReadString(), binaryReader.ReadInt32()); + } + for (int j = 0; j < num3; j++) + { + lineLookup.Add(j, binaryReader.ReadInt32()); + } + dataSegment = binaryReader.ReadBytes(dataSegmentLength); + binaryReader.Close(); + memoryStream.Close(); + dataStream = new MemoryStream(dataSegment); + dataReader = new BinaryReader(dataStream); + JumpToBlock("main"); + IsInitialized = true; + LineNum = 0; + } + + public void Uninitialize() + { + if (IsInitialized) + { + blockLookup = new Dictionary(); + lineLookup = new Dictionary(); + dataSegment = null; + if (dataReader != null) + { + dataReader.Close(); + } + if (dataStream != null) + { + dataStream.Close(); + } + dataReader = null; + dataStream = null; + IsInitialized = false; + } + } + + public void JumpToBlock(string blockname) + { + int value = 0; + if (!blockLookup.TryGetValue(blockname, out value)) + { + throw new KeyNotFoundException($"Unable to find a block segment with the name '{blockname}' within the script '{Filename}'."); + } + JumpToPosition(value); + } + + public void JumpToPosition(int newposition) + { + if (newposition > dataSegmentLength) + { + throw new IndexOutOfRangeException($"Attempting to jump to script position {Position} within the script '{Filename}', but the script only has a length of '{dataSegmentLength}."); + } + dataStream.Seek(newposition, SeekOrigin.Begin); + } + + public void JumpToLineNum(int linenum) + { + if (linenum > lineLookup.Count) + { + throw new IndexOutOfRangeException($"Attempting to jump to script line {linenum} within the script '{Filename}', but the script only has a length of '{lineLookup.Count}."); + } + dataStream.Seek(lineLookup[linenum], SeekOrigin.Begin); + LineNum = linenum; + } + + private void SetOperationType(string type) + { + opType = type; + param = 0; + } + + private BurikoVariable ReadVariable() + { + param++; + BurikoVariable result = null; + try + { + result = new BurikoVariable(dataReader); + return result; + } + catch (Exception arg) + { + string message = $"ReadVariable: Operation {opType} Parameter {param} could not be read. Generated exception: {arg}"; + ScriptError(message); + return result; + } + } + + private float D2BGetPosition(int posnum) + { + float result = 0f; + switch (posnum) + { + case 2: + case 4: + result = 180f; + break; + case 3: + result = -180f; + break; + case 6: + result = 220f; + break; + case 7: + result = -220f; + break; + case 9: + result = 100f; + break; + case 10: + result = -100f; + break; + case 11: + result = -300f; + break; + case 12: + result = 300f; + break; + } + return result; + } + + private BurikoVariable OperationStoreValueToLocalWork() + { + SetOperationType("StoreValueToLocalWork"); + string flagname = ReadVariable().VariableName(); + int val = ReadVariable().IntValue(); + BurikoMemory.Instance.SetFlag(flagname, val); + return BurikoVariable.Null; + } + + private BurikoVariable OperationLoadValueFromLocalWork() + { + SetOperationType("LoadValueFromLocalWork"); + string flagname = ReadVariable().VariableName(); + return BurikoMemory.Instance.GetFlag(flagname); + } + + private BurikoVariable OperationCallScript() + { + SetOperationType("CallScript"); + string scriptname = ReadVariable().StringValue(); + scriptSystem.CallScript(scriptname); + return BurikoVariable.Null; + } + + private BurikoVariable OperationJumpScript() + { + SetOperationType("JumpScript"); + string scriptname = ReadVariable().StringValue(); + scriptSystem.JumpToScript(scriptname); + return BurikoVariable.Null; + } + + public BurikoVariable OperationCallSection() + { + SetOperationType("CallSection"); + string blockname = ReadVariable().StringValue(); + scriptSystem.CallBlock(blockname); + return BurikoVariable.Null; + } + + private BurikoVariable OperationJumpSection() + { + SetOperationType("JumpSection"); + string blockname = ReadVariable().StringValue(); + scriptSystem.JumpToBlock(blockname); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetLocalFlag() + { + SetOperationType("SetLocalFlag"); + string flagname = ReadVariable().VariableName(); + int val = ReadVariable().IntValue(); + BurikoMemory.Instance.SetFlag(flagname, val); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetGlobalFlag() + { + SetOperationType("SetGlobalFlag"); + string flagname = ReadVariable().VariableName(); + int val = ReadVariable().IntValue(); + BurikoMemory.Instance.SetGlobalFlag(flagname, val); + return BurikoVariable.Null; + } + + private BurikoVariable OperationGetGlobalFlag() + { + SetOperationType("LoadValueFromLocalWork"); + string flagname = ReadVariable().VariableName(); + return BurikoMemory.Instance.GetGlobalFlag(flagname); + } + + private BurikoVariable OperationWait() + { + SetOperationType("Wait"); + float length = (float)ReadVariable().IntValue() / 1000f; + gameSystem.AddWait(new Wait(length, WaitTypes.WaitForTime, null)); + return BurikoVariable.Null; + } + + private BurikoVariable OperationWaitForInput() + { + SetOperationType("WaitForInput"); + gameSystem.TextController.AddWaitToFinishTyping(); + gameSystem.ExecuteActions(); + gameSystem.AddWait(new Wait(0f, WaitTypes.WaitForInput, null)); + if (gameSystem.IsAuto) + { + gameSystem.TextController.SetAutoTextWait(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetValidityOfInput() + { + SetOperationType("SetValidityOfInput"); + bool canInput = ReadVariable().BoolValue(); + gameSystem.CanInput = canInput; + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetValidityOfSaving() + { + SetOperationType("SetValidityOfSaving"); + bool canSave = ReadVariable().BoolValue(); + gameSystem.CanSave = canSave; + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetValidityOfSkipping() + { + SetOperationType("SetValidityOfSkipping"); + bool canSkip = ReadVariable().BoolValue(); + gameSystem.CanSkip = canSkip; + if (gameSystem.IsSkipping) + { + gameSystem.IsSkipping = false; + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetValidityOfUserEffectSpeed() + { + SetOperationType("SetValidityOfUserEffectSpeed"); + ReadVariable().BoolValue(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationOutputLine() + { + SetOperationType("OutputLine"); + string text = string.Empty; + string text2 = string.Empty; + BurikoVariable burikoVariable = ReadVariable(); + if (burikoVariable.Type != BurikoValueType.Null) + { + text = burikoVariable.StringValue(); + } + string text3 = ReadVariable().StringValue(); + BurikoVariable burikoVariable2 = ReadVariable(); + if (burikoVariable2.Type != BurikoValueType.Null) + { + text2 = burikoVariable2.StringValue(); + } + string text4 = ReadVariable().StringValue(); + int num = ReadVariable().IntValue(); + BurikoTextModes textMode = (BurikoTextModes)num; + text3 = text3.Replace("\\n", "\n"); + gameSystem.TextHistory.RegisterLine(text4, text3, text2, text); + gameSystem.TextController.SetText(text, text3, textMode, 1); + gameSystem.TextController.SetText(text2, text4, textMode, 2); + gameSystem.ExecuteActions(); + scriptSystem.TakeSaveSnapshot(string.Empty); + return BurikoVariable.Null; + } + + private BurikoVariable OperationOutputLineAll() + { + SetOperationType("OutputLineAll"); + string text = string.Empty; + BurikoVariable burikoVariable = ReadVariable(); + if (burikoVariable.Type != BurikoValueType.Null) + { + text = burikoVariable.StringValue(); + } + string text2 = ReadVariable().StringValue(); + BurikoTextModes burikoTextModes = (BurikoTextModes)ReadVariable().IntValue(); + text2 = text2.Replace("\\n", "\n"); + gameSystem.TextHistory.RegisterLine(text2, text2, text, text); + if (burikoTextModes == BurikoTextModes.Normal) + { + gameSystem.TextHistory.PushHistory(); + } + gameSystem.TextController.SetText(text, text2, burikoTextModes, 0); + gameSystem.ExecuteActions(); + scriptSystem.TakeSaveSnapshot(string.Empty); + return BurikoVariable.Null; + } + + private BurikoVariable OperationClearMessage() + { + SetOperationType("ClearMessage"); + gameSystem.TextController.ClearText(); + gameSystem.TextHistory.PushHistory(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetFontOfMessage() + { + SetOperationType("SetFontOfMessage"); + ReadVariable().IntValue(); + ReadVariable().IntValue(); + ReadVariable().IntValue(); + Debug.Log("SetFontOfMessage"); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetSpeedOfMessage() + { + SetOperationType("SetSpeedOfMessage"); + bool flag = ReadVariable().BoolValue(); + int num = ReadVariable().IntValue(); + if (!flag) + { + gameSystem.TextController.OverrideTextSpeed = -1; + } + else + { + gameSystem.TextController.OverrideTextSpeed = 50 * (num / 100); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDisableWindow() + { + SetOperationType("DisableWindow"); + if (gameSystem.IsSkipping) + { + gameSystem.MainUIController.FadeOut(0f, isBlocking: false); + gameSystem.SceneController.FadeFace(0f, isblocking: false); + } + else + { + gameSystem.MainUIController.FadeOut(0.5f, isBlocking: true); + gameSystem.SceneController.FadeFace(0.5f, isblocking: true); + } + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSpringText() + { + ReadVariable().IntValue(); + ReadVariable().IntValue(); + Logger.LogWarning("Operation SpringText not implemented!"); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetStyleOfMessageSwinging() + { + ReadVariable().IntValue(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationPlayBGM() + { + SetOperationType("PlayBGM"); + int channel = ReadVariable().IntValue(); + string filename = ReadVariable().StringValue() + ".ogg"; + int num = ReadVariable().IntValue(); + int num2 = ReadVariable().IntValue(); + float volume = (float)num / 128f; + AudioController.Instance.PlayAudio(filename, Assets.Scripts.Core.Audio.AudioType.BGM, channel, volume, (float)num2); + return BurikoVariable.Null; + } + + private BurikoVariable OperationStopBGM() + { + SetOperationType("StopBGM"); + int channel = ReadVariable().IntValue(); + AudioController.Instance.StopBGM(channel); + return BurikoVariable.Null; + } + + private BurikoVariable OperationChangeVolumeOfBGM() + { + SetOperationType("ChangeVolumeOfBGM"); + int channel = ReadVariable().IntValue(); + float volume = (float)ReadVariable().IntValue() / 128f; + int num = ReadVariable().IntValue(); + AudioController.Instance.ChangeVolumeOfBGM(channel, volume, (float)num); + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeOutBGM() + { + SetOperationType("FadeOutBGM"); + int channel = ReadVariable().IntValue(); + int time = ReadVariable().IntValue(); + bool waitForFade = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + AudioController.Instance.StopBGM(channel); + } + else + { + AudioController.Instance.FadeOutBGM(channel, time, waitForFade); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeOutMultiBGM() + { + SetOperationType("FadeOutMultiBGM"); + int channelstart = ReadVariable().IntValue(); + int channelend = ReadVariable().IntValue(); + int time = ReadVariable().IntValue(); + bool waitForFade = ReadVariable().BoolValue(); + AudioController.Instance.FadeOutMultiBGM(channelstart, channelend, time, waitForFade); + return BurikoVariable.Null; + } + + public BurikoVariable OperationPlaySE() + { + SetOperationType("PlaySE"); + int channel = ReadVariable().IntValue(); + string filename = ReadVariable().StringValue() + ".ogg"; + float volume = (float)ReadVariable().IntValue() / 128f; + float pan = (float)ReadVariable().IntValue() / 128f; + AudioController.Instance.PlaySE(filename, channel, volume, pan); + return BurikoVariable.Null; + } + + public BurikoVariable OperationStopSE() + { + SetOperationType("StopSE"); + int channel = ReadVariable().IntValue(); + AudioController.Instance.StopSE(channel); + return BurikoVariable.Null; + } + + public BurikoVariable OperationFadeOutSE() + { + SetOperationType("FadeOutSE"); + int channel = ReadVariable().IntValue(); + float time = (float)ReadVariable().IntValue() / 1000f; + AudioController.Instance.FadeOutSE(channel, time, waitForFade: false); + return BurikoVariable.Null; + } + + private BurikoVariable OperationPlayVoice() + { + SetOperationType("PlayVoice"); + int channel = ReadVariable().IntValue(); + string filename = ReadVariable().StringValue() + ".ogg"; + float volume = (float)ReadVariable().IntValue() / 128f; + AudioController.Instance.PlayVoice(filename, channel, volume); + return BurikoVariable.Null; + } + + private BurikoVariable OperationWaitToFinishSEPlaying() + { + SetOperationType("WaitToFinishSEPlaying"); + int channel = ReadVariable().IntValue(); + if (gameSystem.IsSkipping) + { + return new BurikoVariable(0); + } + if (gameSystem.AudioController.IsVoicePlaying(channel)) + { + float remainingSEPlayTime = gameSystem.AudioController.GetRemainingSEPlayTime(channel); + gameSystem.AddWait(new Wait(remainingSEPlayTime, WaitTypes.WaitForAudio, null)); + } + return new BurikoVariable(1); + } + + private BurikoVariable OperationWaitToFinishVoicePlaying() + { + SetOperationType("WaitToFinishVoicePlaying"); + int channel = ReadVariable().IntValue(); + if (gameSystem.IsSkipping) + { + return new BurikoVariable(0); + } + if (gameSystem.AudioController.IsVoicePlaying(channel)) + { + float remainingVoicePlayTime = gameSystem.AudioController.GetRemainingVoicePlayTime(channel); + gameSystem.AddWait(new Wait(remainingVoicePlayTime, WaitTypes.WaitForAudio, null)); + } + return new BurikoVariable(1); + } + + private BurikoVariable OperationSelect() + { + int num = ReadVariable().IntValue(); + BurikoReference burikoReference = ReadVariable().VariableValue(); + BurikoString burikoString = BurikoMemory.Instance.GetMemory(burikoReference.Property) as BurikoString; + if (burikoString == null) + { + throw new Exception("Unable to read BurikoString type from variable!"); + } + List stringList = burikoString.GetStringList(); + if (stringList.Count < num) + { + throw new Exception("Can't display options, two few options are present for the amount to be displayed!"); + } + gameSystem.DisplayChoices(stringList, num); + gameSystem.ExecuteActions(); + gameSystem.AddWait(new Wait(1f, WaitTypes.WaitForTime, null)); + return null; + } + + private BurikoVariable OperationPreloadBitmap() + { + SetOperationType("PreloadBitmap"); + ReadVariable().StringValue(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationStartShakingOfWindow() + { + SetOperationType("StartShakingOfWindow"); + float speed = (float)ReadVariable().IntValue() / 1000f; + int level = ReadVariable().IntValue(); + int attenuation = ReadVariable().IntValue(); + int vector = ReadVariable().IntValue(); + int loopcount = ReadVariable().IntValue(); + bool isblocking = ReadVariable().BoolValue(); + gameSystem.MainUIController.ShakeScene(speed, level, attenuation, vector, loopcount, isblocking); + return BurikoVariable.Null; + } + + private BurikoVariable OperationStartShakingOfAllObjects() + { + SetOperationType("StartShakingOfAllObjects"); + float speed = (float)ReadVariable().IntValue() / 1000f; + int level = ReadVariable().IntValue(); + int attenuation = ReadVariable().IntValue(); + int vector = ReadVariable().IntValue(); + int loopcount = ReadVariable().IntValue(); + bool isblocking = ReadVariable().BoolValue(); + gameSystem.SceneController.ShakeScene(speed, level, attenuation, vector, loopcount, isblocking); + return BurikoVariable.Null; + } + + private BurikoVariable OperationStartShakingOfBustshot() + { + SetOperationType("StartShakingOfBustshot"); + int layer = ReadVariable().IntValue(); + float speed = (float)ReadVariable().IntValue() / 1000f; + int level = ReadVariable().IntValue(); + int attenuation = ReadVariable().IntValue(); + int vector = ReadVariable().IntValue(); + int loopcount = ReadVariable().IntValue(); + bool isblocking = ReadVariable().BoolValue(); + gameSystem.SceneController.ShakeBustshot(layer, speed, level, attenuation, vector, loopcount, isblocking); + return BurikoVariable.Null; + } + + private BurikoVariable OperationTerminateShakingOfWindow() + { + SetOperationType("TerminateShakingOfWindow"); + ReadVariable().IntValue(); + ReadVariable().BoolValue(); + gameSystem.MainUIController.StopShake(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationTerminateShakingOfAllObjects() + { + SetOperationType("TerminateShakingOfAllObjects"); + ReadVariable().IntValue(); + ReadVariable().BoolValue(); + gameSystem.SceneController.StopSceneShake(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationTerminateShakingOfBustshot() + { + SetOperationType("TerminateShakingOfBustshot"); + int layer = ReadVariable().IntValue(); + ReadVariable().IntValue(); + ReadVariable().BoolValue(); + gameSystem.SceneController.StopBustshotShake(layer); + return BurikoVariable.Null; + } + + private BurikoVariable OperationShakeScreen() + { + SetOperationType("ShakeScreen"); + int vector = ReadVariable().IntValue(); + int level = ReadVariable().IntValue(); + float num = (float)ReadVariable().IntValue() / 1000f; + int loopcount = ReadVariable().IntValue(); + int attenuation = ReadVariable().IntValue(); + num *= 2f; + gameSystem.MainUIController.ShakeScene(num, level, attenuation, vector, loopcount, isblocking: true); + return BurikoVariable.Null; + } + + private BurikoVariable OperationShakeScreenSx() + { + SetOperationType("ShakeScreenSx"); + int vector = ReadVariable().IntValue(); + int level = ReadVariable().IntValue(); + float speed = 1f; + int loopcount = 30; + int attenuation = 5; + gameSystem.MainUIController.ShakeScene(speed, level, attenuation, vector, loopcount, isblocking: true); + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawBG() + { + SetOperationType("DrawBG"); + string texture = ReadVariable().StringValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.DrawBG(texture, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeBG() + { + SetOperationType("FadeBG"); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.DrawBG("black", wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawScene() + { + SetOperationType("DrawScene"); + string text = ReadVariable().StringValue(); + float time = (float)ReadVariable().IntValue() / 1000f; + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.DrawScene(text, time); + gameSystem.ExecuteActions(); + BurikoMemory.Instance.SetCGFlag(text); + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawSceneWithMask() + { + SetOperationType("DrawSceneWithMask"); + string text = ReadVariable().StringValue(); + string maskname = ReadVariable().StringValue(); + ReadVariable().IntValue(); + ReadVariable().IntValue(); + float time = (float)ReadVariable().IntValue() / 1000f; + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.DrawSceneWithMask(text, maskname, time); + gameSystem.ExecuteActions(); + BurikoMemory.Instance.SetCGFlag(text); + return BurikoVariable.Null; + } + + private BurikoVariable OperationChangeScene() + { + SetOperationType("ChangeScene"); + string text = ReadVariable().StringValue(); + ReadVariable().IntValue(); + float time = (float)ReadVariable().IntValue() / 1000f; + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.DrawScene(text, time); + gameSystem.ExecuteActions(); + BurikoMemory.Instance.SetCGFlag(text); + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeScene() + { + SetOperationType("FadeScene"); + float time = (float)ReadVariable().IntValue() / 1000f; + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.DrawScene("black", time); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeSceneWithMask() + { + SetOperationType("FadeSceneWithMask"); + string maskname = ReadVariable().StringValue(); + ReadVariable().IntValue(); + ReadVariable().IntValue(); + float time = (float)ReadVariable().IntValue() / 1000f; + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.DrawSceneWithMask("black", maskname, time); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawBustshot() + { + SetOperationType("DrawBustshot"); + int num = ReadVariable().IntValue(); + string textureName = ReadVariable().StringValue(); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + int z = ReadVariable().IntValue(); + bool move = ReadVariable().BoolValue(); + int oldx = ReadVariable().IntValue(); + int oldy = ReadVariable().IntValue(); + int oldz = ReadVariable().IntValue(); + ReadVariable().IntValue(); + ReadVariable().IntValue(); + ReadVariable().IntValue(); + int type = ReadVariable().IntValue(); + int num2 = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (num2 == 0) + { + num2 = num; + } + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.DrawBustshot(num, textureName, x, y, z, oldx, oldy, oldz, move, num2, type, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationMoveBustshot() + { + SetOperationType("MoveBustshot"); + int layer = ReadVariable().IntValue(); + string textureName = ReadVariable().StringValue(); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + int z = ReadVariable().IntValue(); + ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.MoveBustshot(layer, textureName, x, y, z, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeBustshot() + { + SetOperationType("FadeBustshot"); + int layer = ReadVariable().IntValue(); + bool flag = ReadVariable().BoolValue(); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + int z = ReadVariable().IntValue(); + int angle = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag2 = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + flag = false; + } + if (flag) + { + gameSystem.SceneController.MoveSprite(layer, x, y, z, angle, 0, 0f, wait, flag2); + } + else + { + gameSystem.SceneController.FadeSprite(layer, wait, flag2); + } + if (flag2) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawBustshotWithFiltering() + { + SetOperationType("DrawBustshotWithFiltering"); + int layer = ReadVariable().IntValue(); + string textureName = ReadVariable().StringValue(); + string mask = ReadVariable().StringValue(); + ReadVariable().IntValue(); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + bool move = ReadVariable().BoolValue(); + int oldx = ReadVariable().IntValue(); + int oldy = ReadVariable().IntValue(); + int oldz = ReadVariable().IntValue(); + int z = ReadVariable().IntValue(); + int originx = ReadVariable().IntValue(); + int priority = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.DrawBustshotWithFiltering(layer, textureName, mask, x, y, z, originx, 0, oldx, oldy, oldz, move, priority, 0, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeBustshotWithFiltering() + { + int layer = ReadVariable().IntValue(); + string mask = ReadVariable().StringValue(); + int style = ReadVariable().IntValue(); + bool flag = ReadVariable().BoolValue(); + int num = ReadVariable().IntValue(); + int num2 = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag2 = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.FadeBustshotWithFiltering(layer, mask, style, wait, flag2); + if (flag2) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawFace() + { + SetOperationType("DrawFace"); + string texture = ReadVariable().StringValue(); + float num = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + num = 0f; + flag = false; + } + gameSystem.SceneController.DrawFace(texture, num, flag); + if (!gameSystem.MessageBoxVisible) + { + gameSystem.MainUIController.FadeIn(num); + } + if (flag || gameSystem.IsSkipping) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeFace() + { + SetOperationType("FadeFace"); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + flag = false; + } + gameSystem.SceneController.FadeFace(wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationExecutePlannedControl() + { + SetOperationType("ExecutePlannedControl"); + if (ReadVariable().BoolValue()) + { + Debug.LogWarning("ExecutePlannedControl called with true wait value, but this option is not implemented!"); + } + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawSprite() + { + SetOperationType("DrawSprite"); + int num = ReadVariable().IntValue(); + string text = ReadVariable().StringValue(); + string text2 = ReadVariable().StringValue(); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + int z = ReadVariable().IntValue(); + int originx = ReadVariable().IntValue(); + int originy = ReadVariable().IntValue(); + int angle = ReadVariable().IntValue(); + ReadVariable().BoolValue(); + ReadVariable().BoolValue(); + int style = ReadVariable().IntValue(); + float alpha = (float)ReadVariable().IntValue() / 256f; + int priority = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.DrawSprite(num, text, text2, x, y, z, originx, originy, angle, style, alpha, priority, wait, flag); + if (text2 != string.Empty) + { + gameSystem.SceneController.SetLayerToDepthMasked(num); + } + if (flag) + { + gameSystem.ExecuteActions(); + } + BurikoMemory.Instance.SetCGFlag(text); + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawSpriteWithFiltering() + { + SetOperationType("DrawSpriteWithFiltering"); + int layer = ReadVariable().IntValue(); + string text = ReadVariable().StringValue(); + string mask = ReadVariable().StringValue(); + int style = ReadVariable().IntValue(); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + ReadVariable().BoolValue(); + ReadVariable().BoolValue(); + ReadVariable().IntValue(); + ReadVariable().IntValue(); + int priority = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.DrawSpriteWithFiltering(layer, text, mask, x, y, style, priority, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + BurikoMemory.Instance.SetCGFlag(text); + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeSprite() + { + SetOperationType("FadeSprite"); + int layer = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.FadeSprite(layer, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeSpriteWithFiltering() + { + SetOperationType("FadeSpriteWithFiltering"); + int layer = ReadVariable().IntValue(); + string mask = ReadVariable().StringValue(); + int style = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.FadeSpriteWithFiltering(layer, mask, style, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationMoveSprite() + { + SetOperationType("MoveSprite"); + int layer = ReadVariable().IntValue(); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + int z = ReadVariable().IntValue(); + int angle = ReadVariable().IntValue(); + float num = (float)ReadVariable().IntValue() / 256f; + int easetype = ReadVariable().IntValue(); + ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.MoveSprite(layer, x, y, z, angle, easetype, 1f - num, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationMoveSpriteEx() + { + SetOperationType("MoveSpriteEx"); + int layer = ReadVariable().IntValue(); + string filename = ReadVariable().StringValue(); + ReadVariable().IntValue(); + int count = ReadVariable().IntValue(); + BurikoReference burikoReference = ReadVariable().VariableValue(); + ReadVariable().IntValue(); + float alpha = (float)ReadVariable().IntValue() / 256f; + ReadVariable().IntValue(); + ReadVariable().IntValue(); + float time = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + BurikoVector burikoVector = BurikoMemory.Instance.GetMemory(burikoReference.Property) as BurikoVector; + if (burikoVector == null) + { + throw new Exception("Can't get ST_Vector object with name of " + burikoReference.Property); + } + gameSystem.SceneController.MoveSpriteEx(layer, filename, burikoVector.GetElements(count), alpha, time, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationControlMotionOfSprite() + { + SetOperationType("ControlMotionOfSprite"); + int layer = ReadVariable().IntValue(); + int num = ReadVariable().IntValue(); + BurikoReference burikoReference = ReadVariable().VariableValue(); + int num2 = ReadVariable().IntValue(); + if (num2 != 0) + { + throw new NotImplementedException("Style of ControlMotionOfSprite set to 1, but this type is not implemented!"); + } + BurikoMtnCtrlElement burikoMtnCtrlElement = BurikoMemory.Instance.GetMemory(burikoReference.Property) as BurikoMtnCtrlElement; + if (burikoMtnCtrlElement == null) + { + throw new Exception("Can't get MtnCtrlElement object with name of " + burikoReference.Property); + } + MtnCtrlElement[] allElements = burikoMtnCtrlElement.GetAllElements(); + if (allElements.Length < num) + { + throw new Exception("ControlMotionOfSprite call specified a larger number of MtnCtrlElements than was provided!"); + } + MtnCtrlElement[] array = new MtnCtrlElement[num]; + for (int i = 0; i < num; i++) + { + array[i] = allElements[i]; + } + gameSystem.SceneController.ControlMotionOfSprite(layer, array, num2); + return BurikoVariable.Null; + } + + public BurikoVariable OperationGetPositionOfSprite() + { + SetOperationType("GetPositionOfSprite"); + BurikoReference burikoReference = ReadVariable().VariableValue(); + int layer = ReadVariable().IntValue(); + Vector3 positionOfLayer = gameSystem.SceneController.GetPositionOfLayer(layer); + BurikoVector burikoVector = BurikoMemory.Instance.GetMemory(burikoReference.Property) as BurikoVector; + if (burikoVector == null) + { + Debug.LogError("OperationGetPositionOfSprite: Input variable is not ST_Vector!"); + } + burikoVector.Elements[0] = positionOfLayer; + return BurikoVariable.Null; + } + + public BurikoVariable OperationEnableHorizontalGradation() + { + SetOperationType("EnableHorizontalGradation"); + int targetpower = ReadVariable().IntValue(); + float length = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + length = 0f; + } + gameSystem.SceneController.CreateHorizontalGradation(targetpower, length, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + public BurikoVariable OperationDisableGradation() + { + SetOperationType("DisableGradation"); + float time = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.HideFilmEffector(time, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationEnlargeScreen() + { + SetOperationType("EnlargeScreen"); + int num = ReadVariable().IntValue(); + int num2 = ReadVariable().IntValue(); + int num3 = ReadVariable().IntValue(); + int num4 = ReadVariable().IntValue(); + ReadVariable().BoolValue(); + float time = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.EnlargeScene((float)num, (float)num2, (float)num3, (float)num4, time, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDisableEffector() + { + SetOperationType("DisableEffector"); + int num = ReadVariable().IntValue(); + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + num = 0; + } + if (num == 0) + { + gameSystem.SceneController.ResetViewportSize(); + } + else + { + gameSystem.SceneController.EnlargeScene(0f, 0f, 800f, 600f, (float)num, flag); + } + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDisableBlur() + { + SetOperationType("DisableBlur"); + float time = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.HideFilmEffector(time, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawFilm() + { + SetOperationType("DrawFilm"); + int effecttype = ReadVariable().IntValue(); + Color targetColor = new Color((float)ReadVariable().IntValue() / 255f, (float)ReadVariable().IntValue() / 255f, (float)ReadVariable().IntValue() / 255f); + int targetpower = ReadVariable().IntValue(); + int style = ReadVariable().IntValue(); + float length = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + length = 0f; + } + gameSystem.SceneController.CreateFilmEffector(effecttype, targetColor, targetpower, style, length, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeFilm() + { + SetOperationType("OperationFadeFilm"); + float time = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + time = 0f; + } + gameSystem.SceneController.HideFilmEffector(time, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + public BurikoVariable OperationSetValidityOfFilmToFace() + { + SetOperationType("SetValidityOfFilmToFace"); + bool flag = ReadVariable().BoolValue(); + gameSystem.SceneController.SetFaceToUpperLayer(!flag); + return BurikoVariable.Null; + } + + private BurikoVariable OperationNegative() + { + SetOperationType("Negative"); + int effecttype = 3; + Color targetColor = new Color(1f, 1f, 1f); + int targetpower = 255; + int style = 0; + float length = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + length = 0f; + } + gameSystem.SceneController.CreateFilmEffector(effecttype, targetColor, targetpower, style, length, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + public BurikoVariable OperationPlaceViewTip() + { + SetOperationType("PlaceViewTip"); + int num = ReadVariable().IntValue(); + string texture = string.Empty; + switch (num) + { + case 0: + texture = "view_riho"; + break; + case 1: + texture = "view_shik"; + break; + case 2: + texture = "view_shoi"; + break; + } + MtnCtrlElement[] array = new MtnCtrlElement[3] + { + new MtnCtrlElement(), + null, + null + }; + array[0].Points = 1; + array[0].Route[0] = new Vector3(213f, 131f, 0f); + array[0].Time = 200; + array[0].Transparancy = 0; + array[1] = new MtnCtrlElement(); + array[1].Points = 1; + array[1].Route[0] = new Vector3(213f, 131f, 0f); + array[1].Time = 4000; + array[1].Transparancy = 0; + array[2] = new MtnCtrlElement(); + array[2].Points = 1; + array[2].Route[0] = new Vector3(213f, 131f, 0f); + array[2].Time = 200; + array[2].Transparancy = 256; + gameSystem.SceneController.DrawSprite(50, texture, null, 213, 131, 0, 0, 0, 0, 0, 1f, 50, 10f, isblocking: false); + gameSystem.SceneController.ControlMotionOfSprite(50, array, 0); + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawStandgraphic() + { + SetOperationType("DrawStandgraphic"); + int num = ReadVariable().IntValue(); + string textureName = ReadVariable().StringValue(); + bool flag = ReadVariable().BoolValue(); + int oldx = ReadVariable().IntValue(); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag2 = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + int num2 = Mathf.RoundToInt(D2BGetPosition(num)); + if (!flag) + { + oldx = num2; + } + gameSystem.SceneController.DrawBustshot(num, textureName, num2, 0, 0, oldx, 0, 0, flag, num, 0, wait, flag2); + if (flag2) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationDrawBustFace() + { + SetOperationType("DrawBustFace"); + int num = ReadVariable().IntValue(); + string text = ReadVariable().StringValue(); + bool flag = ReadVariable().BoolValue(); + int oldx = ReadVariable().IntValue(); + float num2 = 0.2f; + if (gameSystem.IsSkipping) + { + num2 = 0f; + } + int num3 = Mathf.RoundToInt(D2BGetPosition(num)); + if (!flag) + { + oldx = num3; + } + gameSystem.SceneController.DrawBustshot(num, text, num3, 0, 0, oldx, 0, 0, flag, num, 0, num2, isblocking: false); + string texture = "f" + text.Substring(3); + if (gameSystem.IsSkipping) + { + gameSystem.SceneController.DrawFace(texture, 0f, isblocking: false); + } + else + { + gameSystem.SceneController.DrawFace(texture, num2, isblocking: true); + } + if (!gameSystem.MessageBoxVisible) + { + gameSystem.MainUIController.FadeIn(num2); + } + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationPlusStandgraphic1() + { + int num = ReadVariable().IntValue(); + string textureName = ReadVariable().StringValue(); + float wait = 0.2f; + if (gameSystem.IsSkipping) + { + wait = 0f; + } + if (num == 2) + { + gameSystem.SceneController.DrawBustshot(num, textureName, 180, 0, 0, 160, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + if (num == 3) + { + gameSystem.SceneController.DrawBustshot(num, textureName, -180, 0, 0, -160, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationPlusStandgraphic2() + { + SetOperationType("PlusStandgraphic2"); + int num = ReadVariable().IntValue(); + string textureName = ReadVariable().StringValue(); + float wait = 0.2f; + if (gameSystem.IsSkipping) + { + wait = 0f; + } + if (num == 5) + { + gameSystem.SceneController.DrawBustshot(num, textureName, 0, 0, 0, 20, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + if (num == 6) + { + gameSystem.SceneController.DrawBustshot(num, textureName, 220, 0, 0, 200, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + if (num == 7) + { + gameSystem.SceneController.DrawBustshot(num, textureName, -220, 0, 0, -200, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + if (num == 8) + { + gameSystem.SceneController.DrawBustshot(num, textureName, 0, 0, 0, 20, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationPlusStandgraphic3() + { + SetOperationType("PlusStandgraphic3"); + int num = ReadVariable().IntValue(); + string textureName = ReadVariable().StringValue(); + float wait = 0.2f; + if (gameSystem.IsSkipping) + { + wait = 0f; + } + if (num == 5) + { + gameSystem.SceneController.DrawBustshot(5, textureName, 0, 0, 0, -20, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + if (num == 6) + { + gameSystem.SceneController.DrawBustshot(6, textureName, 220, 0, 0, 200, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + if (num == 7) + { + gameSystem.SceneController.DrawBustshot(7, textureName, -220, 0, 0, -200, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + if (num == 8) + { + gameSystem.SceneController.DrawBustshot(8, textureName, 0, 0, 0, -20, 0, 0, /*move:*/ true, num, 0, wait, /*isblocking:*/ false); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeAllBustshots2() + { + SetOperationType("FadeAllBustshots2"); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.FadeSprite(2, wait, isblocking: false); + gameSystem.SceneController.FadeSprite(3, wait, flag); + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeAllBustshots3() + { + SetOperationType("FadeAllBustshots3"); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool isblocking = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + gameSystem.SceneController.FadeSprite(5, wait, isblocking: false); + gameSystem.SceneController.FadeSprite(6, wait, isblocking: false); + gameSystem.SceneController.FadeSprite(7, wait, isblocking: false); + gameSystem.SceneController.FadeSprite(8, wait, isblocking); + return BurikoVariable.Null; + } + + private BurikoVariable OperationFadeAllBustshots() + { + SetOperationType("FadeAllBustshots"); + float wait = (float)ReadVariable().IntValue() / 1000f; + bool flag = ReadVariable().BoolValue(); + if (gameSystem.IsSkipping) + { + wait = 0f; + } + for (int i = 1; i < 20; i++) + { + gameSystem.SceneController.FadeSprite(i, wait, flag); + } + if (flag) + { + gameSystem.ExecuteActions(); + } + return BurikoVariable.Null; + } + + private BurikoVariable OperationBlurOffOn() + { + SetOperationType("BlurOffOn"); + int targetpower = ReadVariable().IntValue() / 2; + float length = (float)ReadVariable().IntValue() / 1000f; + gameSystem.SceneController.HideFilmEffector(0f, isBlocking: false); + gameSystem.SceneController.CreateFilmEffector(12, Color.white, targetpower, 0, length, isBlocking: true); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetDrawingPointOfMessage() + { + SetOperationType("SetDrawingPointOfMessage"); + gameSystem.TextController.SetTextPoint(ReadVariable().IntValue(), ReadVariable().IntValue()); + return BurikoVariable.Null; + } + + private BurikoVariable OperationTitleScreen() + { + SetOperationType("TitleScreen"); + gameSystem.PushStateObject(new StateTitle()); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationOpenGallery() + { + SetOperationType("OperationOpenGallery"); + gameSystem.SwitchToGallery(); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationCloseGallery() + { + SetOperationType("OperationCloseGallery"); + gameSystem.LeaveGalleryScreen(null); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationHideGallery() + { + SetOperationType("OperationHideGallery"); + throw new NotImplementedException("OperationHideGallery"); + } + + private BurikoVariable OperationRevealGallery() + { + SetOperationType("OperationRevealGallery"); + throw new NotImplementedException("OperationRevealGallery"); + } + + private BurikoVariable OperationBreak() + { + SetOperationType("Break"); + Debug.Break(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationViewChapterScreen() + { + SetOperationType("ViewChapterScreen"); + gameSystem.AudioController.SaveRestoreTempAudio(); + gameSystem.PushStateObject(new StateChapterScreen()); + scriptSystem.RestoreTempSnapshot(); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationViewExtras() + { + SetOperationType("ViewExtras"); + gameSystem.PushStateObject(new StateExtraScreen()); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationViewTips() + { + SetOperationType("ViewTips"); + int tipsMode = ReadVariable().IntValue(); + gameSystem.AudioController.FadeOutBGM(0, 500, waitForFade: false); + gameSystem.AudioController.FadeOutBGM(1, 500, waitForFade: false); + gameSystem.AudioController.FadeOutBGM(2, 500, waitForFade: false); + gameSystem.PushStateObject(new StateViewTips(tipsMode)); + return BurikoVariable.Null; + } + + private BurikoVariable OperationChapterPreview() + { + gameSystem.PushStateObject(new StateChapterPreview()); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSavePoint() + { + SetOperationType("SavePoint"); + string text = ReadVariable().StringValue(); + string text2 = ReadVariable().StringValue(); + gameSystem.TextController.SetFullText(text, 0); + gameSystem.TextController.SetFullText(text2, 1); + scriptSystem.TakeSaveSnapshot(string.Empty); + scriptSystem.CopyTempSnapshot(); + gameSystem.ExecuteActions(); + return BurikoVariable.Null; + } + + public BurikoVariable OperationSetTextFade() + { + SetOperationType("SetValidityOfTextFade"); + bool flag = ReadVariable().BoolValue(); + BurikoMemory.Instance.SetFlag("LTextFade", flag ? 1 : 0); + gameSystem.TextController.SetTextFade(flag); + return BurikoVariable.Null; + } + + public BurikoVariable OperationSetValidityOfInterface() + { + SetOperationType("SetValidityOfInterface"); + if (ReadVariable().BoolValue()) + { + gameSystem.ShowUIControls(); + } + else + { + gameSystem.HideUIControls(); + } + return BurikoVariable.Null; + } + + public BurikoVariable OperationEnableJumpingOfReturnIcon() + { + SetOperationType("EnableJumpingOfReturnIcon"); + Debug.LogWarning("Unhandled EnableJumpingOfReturnIcon"); + return BurikoVariable.Null; + } + + public BurikoVariable OperationSetValidityOfWindowDisablingWhenGraphicsControl() + { + SetOperationType("SetValidityOfWindowDisablingWhenGraphicsControl"); + bool flag = ReadVariable().BoolValue(); + Debug.LogWarning("Unhandled operation SetValidityOfWindowDisablingWhenGraphicsControl (value " + flag + ")"); + return BurikoVariable.Null; + } + + public BurikoVariable OperationLanguagePrompt() + { + SetOperationType("LanguagePrompt"); + gameSystem.PushStateObject(new StateDialogPrompt(PromptType.DialogLanguage, delegate + { + BurikoMemory.Instance.SetGlobalFlag("GLanguage", 1); + GameSystem.Instance.UseEnglishText = true; + }, delegate + { + BurikoMemory.Instance.SetGlobalFlag("GLanguage", 0); + GameSystem.Instance.UseEnglishText = false; + })); + return BurikoVariable.Null; + } + + private BurikoVariable OperationGetAchievement() + { + SetOperationType("GetAchievement"); + gameSystem.SteamController.AddAchievement(ReadVariable().StringValue()); + return BurikoVariable.Null; + } + + private BurikoVariable OperationCheckTipsAchievements() + { + SetOperationType("CheckTipsAchievements"); + gameSystem.SteamController.CheckTipsAchievements(); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetFontId() + { + SetOperationType("SetFontId"); + gameSystem.MainUIController.ChangeFontId(ReadVariable().IntValue()); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetCharSpacing() + { + SetOperationType("SetCharSpacing"); + gameSystem.MainUIController.SetCharSpacing(ReadVariable().IntValue()); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetLineSpacing() + { + SetOperationType("SetLineSpacing"); + gameSystem.MainUIController.SetLineSpacing(ReadVariable().IntValue()); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetFontSize() + { + SetOperationType("SetFontSize"); + gameSystem.MainUIController.SetFontSize(ReadVariable().IntValue()); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetWindowPos() + { + SetOperationType("SetWindowPos"); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + gameSystem.MainUIController.SetWindowPos(x, y); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetWindowSize() + { + SetOperationType("SetWindowSize"); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + gameSystem.MainUIController.SetWindowSize(x, y); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetWindowMargins() + { + SetOperationType("SetWindowMargins"); + int left = ReadVariable().IntValue(); + int top = ReadVariable().IntValue(); + int right = ReadVariable().IntValue(); + int bottom = ReadVariable().IntValue(); + gameSystem.MainUIController.SetWindowMargins(left, top, right, bottom); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetNameFormat() + { + SetOperationType("SetNameFormat"); + string nameFormat = ReadVariable().StringValue(); + gameSystem.TextController.NameFormat = nameFormat; + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetScreenAspect() + { + SetOperationType("SetScreenAspect"); + string s = ReadVariable().StringValue(); + float newratio = 1f / float.Parse(s, CultureInfo.InvariantCulture); + gameSystem.UpdateAspectRatio(newratio); + return BurikoVariable.Null; + } + + private BurikoVariable OperationSetGuiPosition() + { + SetOperationType("SetGUIPosition"); + int x = ReadVariable().IntValue(); + int y = ReadVariable().IntValue(); + gameSystem.MainUIController.UpdateGuiPosition(x, y); + return BurikoVariable.Null; + } + + public int GetPositionByLineNumber(int linenum) + { + if (!lineLookup.ContainsKey(linenum)) + { + throw new Exception("Could not load file!"); + } + return lineLookup[linenum]; + } + + private void CommandLineNum() + { + LineNum = dataReader.ReadInt32(); + if (gameSystem.IsSkipping && !gameSystem.IsForceSkip && !BurikoMemory.Instance.IsLineRead(Filename, LineNum) && !gameSystem.SkipUnreadMessages) + { + gameSystem.IsSkipping = false; + } + BurikoMemory.Instance.MarkLineAsRead(Filename, LineNum); + } + + public BurikoVariable ExecuteOperation(BurikoOperations op) + { + switch (op) + { + case BurikoOperations.CallScript: + return OperationCallScript(); + case BurikoOperations.JumpScript: + return OperationJumpScript(); + case BurikoOperations.CallSection: + return OperationCallSection(); + case BurikoOperations.JumpSection: + return OperationJumpSection(); + case BurikoOperations.StoreValueToLocalWork: + return OperationStoreValueToLocalWork(); + case BurikoOperations.LoadValueFromLocalWork: + return OperationLoadValueFromLocalWork(); + case BurikoOperations.SetLocalFlag: + return OperationSetLocalFlag(); + case BurikoOperations.GetLocalFlag: + return OperationLoadValueFromLocalWork(); + case BurikoOperations.SetGlobalFlag: + return OperationSetGlobalFlag(); + case BurikoOperations.GetGlobalFlag: + return OperationGetGlobalFlag(); + case BurikoOperations.Wait: + return OperationWait(); + case BurikoOperations.WaitForInput: + return OperationWaitForInput(); + case BurikoOperations.SetValidityOfInput: + return OperationSetValidityOfInput(); + case BurikoOperations.SetValidityOfSaving: + return OperationSetValidityOfSaving(); + case BurikoOperations.SetValidityOfSkipping: + return OperationSetValidityOfSkipping(); + case BurikoOperations.SetValidityOfUserEffectSpeed: + return OperationSetValidityOfUserEffectSpeed(); + case BurikoOperations.OutputLine: + return OperationOutputLine(); + case BurikoOperations.OutputLineAll: + return OperationOutputLineAll(); + case BurikoOperations.ClearMessage: + return OperationClearMessage(); + case BurikoOperations.SetFontOfMessage: + return OperationSetFontOfMessage(); + case BurikoOperations.SetSpeedOfMessage: + return OperationSetSpeedOfMessage(); + case BurikoOperations.DisableWindow: + return OperationDisableWindow(); + case BurikoOperations.SpringText: + return OperationSpringText(); + case BurikoOperations.SetStyleOfMessageSwinging: + return OperationSetStyleOfMessageSwinging(); + case BurikoOperations.Select: + return OperationSelect(); + case BurikoOperations.PlayBGM: + return OperationPlayBGM(); + case BurikoOperations.StopBGM: + return OperationStopBGM(); + case BurikoOperations.ChangeVolumeOfBGM: + return OperationChangeVolumeOfBGM(); + case BurikoOperations.FadeOutBGM: + return OperationFadeOutBGM(); + case BurikoOperations.FadeOutMultiBGM: + return OperationFadeOutMultiBGM(); + case BurikoOperations.PlaySE: + return OperationPlaySE(); + case BurikoOperations.StopSE: + return OperationStopSE(); + case BurikoOperations.FadeOutSE: + return OperationFadeOutSE(); + case BurikoOperations.PlayVoice: + return OperationPlayVoice(); + case BurikoOperations.WaitToFinishVoicePlaying: + return OperationWaitToFinishVoicePlaying(); + case BurikoOperations.WaitToFinishSEPlaying: + return OperationWaitToFinishSEPlaying(); + case BurikoOperations.PreloadBitmap: + return OperationPreloadBitmap(); + case BurikoOperations.StartShakingOfAllObjects: + return OperationStartShakingOfAllObjects(); + case BurikoOperations.TerminateShakingOfAllObjects: + return OperationTerminateShakingOfAllObjects(); + case BurikoOperations.StartShakingOfWindow: + return OperationStartShakingOfWindow(); + case BurikoOperations.TerminateShakingOfWindow: + return OperationTerminateShakingOfWindow(); + case BurikoOperations.StartShakingOfBustshot: + return OperationStartShakingOfBustshot(); + case BurikoOperations.TerminateShakingOfBustshot: + return OperationTerminateShakingOfBustshot(); + case BurikoOperations.ShakeScreen: + return OperationShakeScreen(); + case BurikoOperations.ShakeScreenSx: + return OperationShakeScreenSx(); + case BurikoOperations.DrawBG: + return OperationDrawBG(); + case BurikoOperations.FadeBG: + return OperationFadeBG(); + case BurikoOperations.DrawScene: + return OperationDrawScene(); + case BurikoOperations.DrawSceneWithMask: + return OperationDrawSceneWithMask(); + case BurikoOperations.ChangeScene: + return OperationChangeScene(); + case BurikoOperations.FadeScene: + return OperationFadeScene(); + case BurikoOperations.FadeSceneWithMask: + return OperationFadeSceneWithMask(); + case BurikoOperations.DrawBustshot: + return OperationDrawBustshot(); + case BurikoOperations.MoveBustshot: + return OperationMoveBustshot(); + case BurikoOperations.FadeBustshot: + return OperationFadeBustshot(); + case BurikoOperations.DrawBustshotWithFiltering: + return OperationDrawBustshotWithFiltering(); + case BurikoOperations.DrawFace: + return OperationDrawFace(); + case BurikoOperations.FadeFace: + return OperationFadeFace(); + case BurikoOperations.ExecutePlannedControl: + return OperationExecutePlannedControl(); + case BurikoOperations.DrawSprite: + return OperationDrawSprite(); + case BurikoOperations.DrawSpriteWithFiltering: + return OperationDrawSpriteWithFiltering(); + case BurikoOperations.FadeSprite: + return OperationFadeSprite(); + case BurikoOperations.FadeSpriteWithFiltering: + return OperationFadeSpriteWithFiltering(); + case BurikoOperations.MoveSprite: + return OperationMoveSprite(); + case BurikoOperations.MoveSpriteEx: + return OperationMoveSpriteEx(); + case BurikoOperations.ControlMotionOfSprite: + return OperationControlMotionOfSprite(); + case BurikoOperations.GetPositionOfSprite: + return OperationGetPositionOfSprite(); + case BurikoOperations.EnableHorizontalGradation: + return OperationEnableHorizontalGradation(); + case BurikoOperations.DisableGradation: + return OperationDisableGradation(); + case BurikoOperations.EnlargeScreen: + return OperationEnlargeScreen(); + case BurikoOperations.DisableEffector: + return OperationDisableEffector(); + case BurikoOperations.DisableBlur: + return OperationDisableBlur(); + case BurikoOperations.DrawFilm: + return OperationDrawFilm(); + case BurikoOperations.FadeFilm: + return OperationFadeFilm(); + case BurikoOperations.SetValidityOfFilmToFace: + return OperationSetValidityOfFilmToFace(); + case BurikoOperations.FadeAllBustshots: + return OperationFadeAllBustshots(); + case BurikoOperations.FadeBustshotWithFiltering: + return OperationFadeBustshotWithFiltering(); + case BurikoOperations.SetDrawingPointOfMessage: + return OperationSetDrawingPointOfMessage(); + case BurikoOperations.Negative: + return OperationNegative(); + case BurikoOperations.PlaceViewTip: + return OperationPlaceViewTip(); + case BurikoOperations.DrawStandgraphic: + return OperationDrawStandgraphic(); + case BurikoOperations.DrawBustFace: + return OperationDrawBustFace(); + case BurikoOperations.PlusStandgraphic1: + return OperationPlusStandgraphic1(); + case BurikoOperations.PlusStandgraphic2: + return OperationPlusStandgraphic2(); + case BurikoOperations.PlusStandgraphic3: + return OperationPlusStandgraphic3(); + case BurikoOperations.FadeAllBustshots2: + return OperationFadeAllBustshots2(); + case BurikoOperations.FadeAllBustshots3: + return OperationFadeAllBustshots3(); + case BurikoOperations.BlurOffOn: + return OperationBlurOffOn(); + case BurikoOperations.TitleScreen: + return OperationTitleScreen(); + case BurikoOperations.Break: + return OperationBreak(); + case BurikoOperations.OpenGallery: + return OperationOpenGallery(); + case BurikoOperations.CloseGallery: + return OperationCloseGallery(); + case BurikoOperations.HideGallery: + return OperationHideGallery(); + case BurikoOperations.RevealGallery: + return OperationRevealGallery(); + case BurikoOperations.ViewChapterScreen: + return OperationViewChapterScreen(); + case BurikoOperations.ViewExtras: + return OperationViewExtras(); + case BurikoOperations.ViewTips: + return OperationViewTips(); + case BurikoOperations.ChapterPreview: + return OperationChapterPreview(); + case BurikoOperations.SetValidityOfInterface: + return OperationSetValidityOfInterface(); + case BurikoOperations.SavePoint: + return OperationSavePoint(); + case BurikoOperations.EnableJumpingOfReturnIcon: + return OperationEnableJumpingOfReturnIcon(); + case BurikoOperations.SetValidityOfWindowDisablingWhenGraphicsControl: + return OperationSetValidityOfWindowDisablingWhenGraphicsControl(); + case BurikoOperations.LanguagePrompt: + return OperationLanguagePrompt(); + case BurikoOperations.SetTextFade: + return OperationSetTextFade(); + case BurikoOperations.GetAchievement: + return OperationGetAchievement(); + case BurikoOperations.CheckTipsAchievements: + return OperationCheckTipsAchievements(); + case BurikoOperations.SetFontId: + return OperationSetFontId(); + case BurikoOperations.SetCharSpacing: + return OperationSetCharSpacing(); + case BurikoOperations.SetLineSpacing: + return OperationSetLineSpacing(); + case BurikoOperations.SetFontSize: + return OperationSetFontSize(); + case BurikoOperations.SetWindowPos: + return OperationSetWindowPos(); + case BurikoOperations.SetWindowSize: + return OperationSetWindowSize(); + case BurikoOperations.SetWindowMargins: + return OperationSetWindowMargins(); + case BurikoOperations.SetNameFormat: + return OperationSetNameFormat(); + case BurikoOperations.SetScreenAspect: + return OperationSetScreenAspect(); + case BurikoOperations.SetGuiPosition: + return OperationSetGuiPosition(); + default: + ScriptError("Unhandled Operation : " + op); + return BurikoVariable.Null; + } + } + + private void CommandOperation() + { + SetOperationType("Operation"); + BurikoOperations op = (BurikoOperations)dataReader.ReadInt16(); + ExecuteOperation(op); + } + + private void CommandDeclaration() + { + SetOperationType("Declaration"); + string text = dataReader.ReadString(); + string name = dataReader.ReadString(); + BurikoVariable burikoVariable = ReadVariable(); + int members = 1; + if (burikoVariable.Type != BurikoValueType.Null) + { + members = burikoVariable.IntValue(); + } + IBurikoObject burikoObject; + switch (text) + { + case "char": + burikoObject = new BurikoString(); + burikoObject.Create(members); + break; + case "ST_MtnCtrlElement": + burikoObject = new BurikoMtnCtrlElement(); + burikoObject.Create(members); + break; + case "ST_Vector": + burikoObject = new BurikoVector(); + burikoObject.Create(members); + break; + case "int": + burikoObject = new BurikoInt(); + burikoObject.Create(members); + break; + default: + throw new Exception("Unknown declaration variable type " + text); + } + BurikoMemory.Instance.AddMemory(name, burikoObject); + } + + public void CommandAssignment() + { + SetOperationType("Assignment"); + BurikoReference burikoReference = BurikoVariable.ReadReference(dataReader); + BurikoVariable var = ReadVariable(); + IBurikoObject memory = BurikoMemory.Instance.GetMemory(burikoReference.Property); + memory.SetValue(burikoReference, var); + } + + public void CommandIf() + { + SetOperationType("If"); + int num = ReadVariable().IntValue(); + int newposition = dataReader.ReadInt32(); + if (num != 1) + { + JumpToPosition(newposition); + } + } + + public void CommandJump() + { + SetOperationType("Jump"); + int newposition = dataReader.ReadInt32(); + JumpToPosition(newposition); + } + + public void Next() + { + if (!IsInitialized) + { + InitializeScript(); + } + BurikoCommands burikoCommands; + try + { + burikoCommands = (BurikoCommands)dataReader.ReadInt16(); + } + catch (Exception arg) + { + Debug.LogError($"{Filename}: Failed to read file! Position: {Position} Exception: {arg}"); + throw; + IL_0046:; + } + switch (burikoCommands) + { + case BurikoCommands.LineNum: + CommandLineNum(); + break; + case BurikoCommands.Operation: + CommandOperation(); + break; + case BurikoCommands.Declaration: + CommandDeclaration(); + break; + case BurikoCommands.Assignment: + CommandAssignment(); + break; + case BurikoCommands.If: + CommandIf(); + break; + case BurikoCommands.Jump: + CommandJump(); + break; + case BurikoCommands.Return: + BurikoScriptSystem.Instance.Return(); + break; + default: + ScriptError(string.Format("No handler for command " + burikoCommands + " (value " + (int)burikoCommands + ")")); + break; + } + } + + public void ScriptError(string message) + { + string message2 = $"{Filename} ({LineNum}): {message}"; + Logger.LogError(message2); + throw new Exception(message2); + } + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoScriptSystem.cs b/Assets.Scripts.Core.Buriko/BurikoScriptSystem.cs new file mode 100644 index 00000000..8b065c43 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoScriptSystem.cs @@ -0,0 +1,436 @@ +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Interfaces; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; + +namespace Assets.Scripts.Core.Buriko +{ + public class BurikoScriptSystem : IScriptInterpreter + { + private Dictionary scriptFiles = new Dictionary(); + + private Stack callStack = new Stack(); + + private BurikoScriptFile currentScript; + + private BurikoMemory memoryManager; + + private BurikoSaveManager saveManager; + + private byte[] snapshotData; + + private byte[] tempSnapshotData; + + private bool hasSnapshot; + + private readonly string[] tempSnapshotText = new string[2]; + + public static BurikoScriptSystem Instance + { + get; + private set; + } + + public void Initialize(GameSystem gameSystem) + { + Logger.Log("Preparing BurikoScriptSystem."); + LoadGameScripts(); + saveManager = new BurikoSaveManager(); + memoryManager = new BurikoMemory(); + Instance = this; + JumpToScript("init"); + } + + private void LoadGameScripts() + { + string[] availableScriptNames = AssetManager.Instance.GetAvailableScriptNames(); + foreach (string text in availableScriptNames) + { + BurikoScriptFile value = new BurikoScriptFile(this, text); + scriptFiles.Add(text, value); + } + } + + public BurikoScriptFile GetCurrentScript() + { + return currentScript; + } + + public void CallBlock(string blockname) + { + CallScript(Path.GetFileNameWithoutExtension(currentScript.Filename), blockname); + } + + public void JumpToBlock(string blockname) + { + JumpToScript(Path.GetFileNameWithoutExtension(currentScript.Filename), blockname); + } + + public void JumpToScript(string scriptname, string blockname = "main") + { + Logger.Log((currentScript == null) ? $"Starting at script {scriptname} (block {blockname})" : $"Jumping from script {currentScript.Filename} to script {scriptname} (block {blockname})"); + callStack.Clear(); + scriptname = scriptname.ToLower(); + if (!scriptFiles.TryGetValue(scriptname + ".mg", out currentScript)) + { + throw new KeyNotFoundException($"Could not JumpToScript {scriptname}, as the file was not found."); + } + if (!currentScript.IsInitialized) + { + currentScript.InitializeScript(); + } + memoryManager.ResetScope(); + currentScript.JumpToBlock(blockname); + } + + public void CallScript(string scriptname, string blockname = "main") + { + Logger.Log($"{currentScript.Filename}: calling script {scriptname} (block {blockname})"); + callStack.Push(new BurikoStackEntry(currentScript, currentScript.Position, currentScript.LineNum)); + scriptname = scriptname.ToLower(); + if (!scriptFiles.TryGetValue(scriptname + ".mg", out currentScript)) + { + throw new KeyNotFoundException($"Could not CallScript {scriptname}, as the file was not found."); + } + if (!currentScript.IsInitialized) + { + currentScript.InitializeScript(); + } + memoryManager.AddScope(); + currentScript.JumpToBlock(blockname); + } + + public void Return() + { + if (callStack.Count <= 0) + { + throw new Exception("Could not return from script, as the script is currently at the bottom of the call stack."); + } + BurikoStackEntry burikoStackEntry = callStack.Pop(); + Logger.Log($"Returning from script {currentScript.Filename} to script {burikoStackEntry.Script} LineNum {burikoStackEntry.LineNum}"); + if (!burikoStackEntry.Script.IsInitialized) + { + burikoStackEntry.Script.InitializeScript(); + } + currentScript = burikoStackEntry.Script; + currentScript.JumpToLineNum(burikoStackEntry.LineNum + 1); + memoryManager.DropScope(); + } + + public void Advance() + { + currentScript.Next(); + } + + public void SaveQuickSave() + { + int num = memoryManager.GetGlobalFlag("GQsaveNum").IntValue(); + if (saveManager.IsSaveInSlot(100)) + { + num++; + if (num > 2) + { + num = 0; + } + } + else + { + num = 0; + } + SaveGame(num + 100); + memoryManager.SetGlobalFlag("GQsaveNum", num); + GameSystem.Instance.MainUIController.ShowQuickSaveIcon(); + } + + public void DeleteSave(int slotnum) + { + saveManager.DeleteSave(slotnum); + } + + public bool IsSaveInSlot(int slotnum) + { + return saveManager.IsSaveInSlot(slotnum); + } + + public int GetQSaveSlotByMostRecent(int num) + { + if (num > 2) + { + throw new Exception("Can't get QSave for slot above 2!"); + } + int num2 = memoryManager.GetGlobalFlag("GQsaveNum").IntValue() - num; + if (num2 < 0) + { + num2 += 3; + } + return num2 + 100; + } + + public SaveEntry GetQSaveInfo(int qsavenum) + { + int num = memoryManager.GetGlobalFlag("GQsaveNum").IntValue() + qsavenum; + if (num >= 3) + { + num -= 3; + } + return saveManager.GetSaveInfoInSlot(num + 100); + } + + public SaveEntry GetSaveInfo(int savenum) + { + return saveManager.GetSaveInfoInSlot(savenum); + } + + public SaveEntry GetQSaveInfo() + { + int num = memoryManager.GetGlobalFlag("GQsaveNum").IntValue(); + return saveManager.GetSaveInfoInSlot(num + 100); + } + + public void LoadQuickSave() + { + int num = memoryManager.GetGlobalFlag("GQsaveNum").IntValue(); + LoadGame(num + 100); + } + + public void CopyTempSnapshot() + { + Debug.Log("CopyTempSnapshot"); + if (snapshotData.Length > 0) + { + tempSnapshotData = snapshotData; + tempSnapshotText[0] = GameSystem.Instance.TextController.GetFullText(0); + tempSnapshotText[1] = GameSystem.Instance.TextController.GetFullText(1); + } + } + + public void RestoreTempSnapshot() + { + Debug.Log("RestoreTempSnapshot"); + if (tempSnapshotData.Length > 0) + { + snapshotData = tempSnapshotData; + GameSystem.Instance.TextController.SetFullText(tempSnapshotText[0], 0); + GameSystem.Instance.TextController.SetFullText(tempSnapshotText[1], 1); + } + } + + public void TakeSaveSnapshot(string text = "") + { + if (GameSystem.Instance.CanSave) + { + using (MemoryStream memoryStream = new MemoryStream()) + { + using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) + { + binaryWriter.Write("MGSV".ToCharArray(0, 4)); + binaryWriter.Write(1); + binaryWriter.Write(DateTime.Now.ToBinary()); + if (text == string.Empty) + { + string fullText = GameSystem.Instance.TextController.GetFullText(0); + string fullText2 = GameSystem.Instance.TextController.GetFullText(1); + binaryWriter.Write(fullText); + binaryWriter.Write(fullText2); + string prevText = GameSystem.Instance.TextController.GetPrevText(0); + string prevText2 = GameSystem.Instance.TextController.GetPrevText(1); + binaryWriter.Write(prevText); + binaryWriter.Write(prevText2); + binaryWriter.Write(GameSystem.Instance.TextController.GetPrevAppendState()); + } + else + { + binaryWriter.Write(text); + binaryWriter.Write(text); + binaryWriter.Write(string.Empty); + binaryWriter.Write(string.Empty); + binaryWriter.Write(value: false); + } + binaryWriter.Write(callStack.Count); + foreach (BurikoStackEntry item in callStack.Reverse()) + { + binaryWriter.Write(item.Script.Filename); + binaryWriter.Write(item.LineNum); + } + binaryWriter.Write(currentScript.Filename); + binaryWriter.Write(currentScript.LineNum); + binaryWriter.Write(memoryManager.SaveMemory()); + AudioController.Instance.SerializeCurrentAudio(memoryStream); + GameSystem.Instance.SceneController.SerializeScene(memoryStream); + snapshotData = memoryStream.ToArray(); + hasSnapshot = true; + } + } + } + } + + public void ModifySaveGame(int slot, string description) + { + Debug.Log("ModifySaveGame " + slot); + SaveEntry saveInfoInSlot = saveManager.GetSaveInfoInSlot(slot); + if (saveInfoInSlot != null) + { + byte[] array = File.ReadAllBytes(saveInfoInSlot.Path); + MGHelper.KeyEncode(array); + byte[] buffer = CLZF2.Decompress(array); + MemoryStream memoryStream = new MemoryStream(buffer); + MemoryStream memoryStream2 = new MemoryStream(); + BinaryReader binaryReader = new BinaryReader(memoryStream); + BinaryWriter binaryWriter = new BinaryWriter(memoryStream2); + binaryWriter.Write(binaryReader.ReadBytes(16)); + binaryReader.ReadString(); + binaryWriter.Write(description); + binaryWriter.Write(binaryReader.ReadBytes((int)(memoryStream.Length - memoryStream.Position))); + byte[] inputBytes = memoryStream2.ToArray(); + memoryStream.Dispose(); + memoryStream2.Dispose(); + byte[] array2 = CLZF2.Compress(inputBytes); + MGHelper.KeyEncode(array2); + File.WriteAllBytes(saveInfoInSlot.Path, array2); + saveManager.UpdateSaveSlot(slot); + } + } + + public void ModifySnapshotDescription(string newdescription) + { + Debug.Log("ModifySnapshotDescription: " + newdescription); + MemoryStream memoryStream = new MemoryStream(snapshotData); + MemoryStream memoryStream2 = new MemoryStream(); + BinaryReader binaryReader = new BinaryReader(memoryStream); + BinaryWriter binaryWriter = new BinaryWriter(memoryStream2); + binaryWriter.Write(binaryReader.ReadBytes(16)); + binaryReader.ReadString(); + binaryWriter.Write(newdescription); + binaryWriter.Write(binaryReader.ReadBytes((int)(memoryStream.Length - memoryStream.Position))); + snapshotData = memoryStream2.ToArray(); + memoryStream.Dispose(); + memoryStream2.Dispose(); + } + + public void SaveGame(int slotnum) + { + if (hasSnapshot) + { + byte[] array = CLZF2.Compress(snapshotData); + MGHelper.KeyEncode(array); + string str = (slotnum < 100) ? ("save" + slotnum.ToString("D3")) : ("qsave" + (slotnum - 100)); + File.WriteAllBytes(Path.Combine(MGHelper.GetSavePath(), str + ".dat"), array); + saveManager.UpdateSaveSlot(slotnum); + GameSystem.Instance.SceneController.WriteScreenshot(Path.Combine(MGHelper.GetSavePath(), str + ".png")); + } + } + + public void LoadGame(int slotnum) + { + SaveEntry saveInfoInSlot = saveManager.GetSaveInfoInSlot(slotnum); + if (saveInfoInSlot != null) + { + GameSystem.Instance.TextController.ClearText(); + GameSystem.Instance.MainUIController.FadeOut(0f, isBlocking: true); + byte[] array = File.ReadAllBytes(saveInfoInSlot.Path); + MGHelper.KeyEncode(array); + byte[] buffer = tempSnapshotData = (snapshotData = CLZF2.Decompress(array)); + hasSnapshot = true; + GameSystem.Instance.ClearAllWaits(); + GameSystem.Instance.ClearActions(); + using (MemoryStream memoryStream = new MemoryStream(buffer)) + { + using (BinaryReader binaryReader = new BinaryReader(memoryStream)) + { + string a = new string(binaryReader.ReadChars(4)); + if (a != "MGSV") + { + throw new FileLoadException("Save file does not appear to be valid! Invalid header."); + } + int num = binaryReader.ReadInt32(); + if (num != 1) + { + throw new FileLoadException("Save file does not appear to be valid! Invalid version number."); + } + binaryReader.ReadInt64(); + string text = binaryReader.ReadString(); + string text2 = binaryReader.ReadString(); + string text3 = binaryReader.ReadString(); + string text4 = binaryReader.ReadString(); + bool flag = binaryReader.ReadBoolean(); + GameSystem.Instance.TextController.SetPrevText(text3, 0); + GameSystem.Instance.TextController.SetPrevText(text4, 1); + if (flag) + { + if (GameSystem.Instance.UseEnglishText) + { + GameSystem.Instance.TextController.TypeTextImmediately(text4); + GameSystem.Instance.TextController.SetFullText(text3, 0); + } + else + { + GameSystem.Instance.TextController.TypeTextImmediately(text3); + GameSystem.Instance.TextController.SetFullText(text4, 1); + } + tempSnapshotText[0] = text3; + tempSnapshotText[1] = text4; + GameSystem.Instance.TextController.SetAppendState(append: true); + } + else + { + GameSystem.Instance.TextController.SetFullText(text, 0); + GameSystem.Instance.TextController.SetFullText(text2, 1); + tempSnapshotText[0] = text; + tempSnapshotText[1] = text2; + GameSystem.Instance.TextController.SetAppendState(append: false); + } + callStack.Clear(); + int num2 = binaryReader.ReadInt32(); + for (int i = 0; i < num2; i++) + { + string key = binaryReader.ReadString(); + int linenum = binaryReader.ReadInt32(); + BurikoScriptFile script = scriptFiles[key]; + callStack.Push(new BurikoStackEntry(script, 0, linenum)); + } + string key2 = binaryReader.ReadString(); + int linenum2 = binaryReader.ReadInt32(); + currentScript = scriptFiles[key2]; + if (!currentScript.IsInitialized) + { + currentScript.InitializeScript(); + } + currentScript.JumpToLineNum(linenum2); + memoryManager.LoadMemory(memoryStream); + AudioController.Instance.DeSerializeCurrentAudio(memoryStream); + GameSystem.Instance.SceneController.DeSerializeScene(memoryStream); + GameSystem.Instance.ForceReturnNormalState(); + GameSystem.Instance.CloseChoiceIfExists(); + GameSystem.Instance.TextHistory.ClearHistory(); + GameSystem.Instance.IsSkipping = false; + GameSystem.Instance.IsAuto = false; + GameSystem.Instance.CanSkip = true; + GameSystem.Instance.CanInput = true; + GameSystem.Instance.CanSave = true; + int flag2 = GetFlag("LTextFade"); + GameSystem.Instance.TextController.SetTextFade(flag2 == 1); + } + } + } + } + + public int GetFlag(string name) + { + return memoryManager.GetFlag(name).IntValue(); + } + + public void SetFlag(string name, int value) + { + memoryManager.SetFlag(name, value); + } + + public void ShutDown() + { + throw new NotImplementedException(); + } + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoStackEntry.cs b/Assets.Scripts.Core.Buriko/BurikoStackEntry.cs new file mode 100644 index 00000000..e6a78067 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoStackEntry.cs @@ -0,0 +1,23 @@ +namespace Assets.Scripts.Core.Buriko +{ + public class BurikoStackEntry + { + public BurikoScriptFile Script; + + public int Position; + + public int LineNum; + + public BurikoStackEntry(BurikoScriptFile script, int position, int linenum) + { + Script = script; + Position = position; + LineNum = linenum; + } + + public void Restore() + { + Script.JumpToLineNum(LineNum); + } + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoTextModes.cs b/Assets.Scripts.Core.Buriko/BurikoTextModes.cs new file mode 100644 index 00000000..6db50d72 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoTextModes.cs @@ -0,0 +1,11 @@ +namespace Assets.Scripts.Core.Buriko +{ + public enum BurikoTextModes + { + Normal, + Continue, + WaitForInput, + ContinueAftertyping, + WaitThenContinue + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoValueType.cs b/Assets.Scripts.Core.Buriko/BurikoValueType.cs new file mode 100644 index 00000000..79214f38 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoValueType.cs @@ -0,0 +1,15 @@ +namespace Assets.Scripts.Core.Buriko +{ + public enum BurikoValueType + { + None, + Null, + Int, + String, + Bool, + Variable, + Operation, + Assignment, + Math + } +} diff --git a/Assets.Scripts.Core.Buriko/BurikoVariable.cs b/Assets.Scripts.Core.Buriko/BurikoVariable.cs new file mode 100644 index 00000000..6a7d0852 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/BurikoVariable.cs @@ -0,0 +1,233 @@ +using Assets.Scripts.Core.Buriko.Util; +using System; +using System.Globalization; +using System.IO; + +namespace Assets.Scripts.Core.Buriko +{ + public class BurikoVariable + { + private string valueString; + + private int valueInt; + + private BurikoReference valueReference; + + private BurikoVariable valueVariable; + + public BurikoValueType Type + { + get; + private set; + } + + public static BurikoVariable Null => new BurikoVariable(); + + public BurikoVariable() + { + Type = BurikoValueType.Null; + } + + public BurikoVariable(string s) + { + Type = BurikoValueType.String; + valueString = s; + } + + public BurikoVariable(int i) + { + Type = BurikoValueType.Int; + valueInt = i; + } + + public BurikoVariable(BurikoReference reference, BurikoVariable variable) + { + Type = BurikoValueType.Variable; + valueReference = reference; + valueVariable = variable; + } + + public BurikoVariable(BinaryReader stream) + { + Type = (BurikoValueType)stream.ReadInt16(); + switch (Type) + { + case BurikoValueType.Null: + valueInt = -1; + break; + case BurikoValueType.Bool: + valueInt = stream.ReadByte(); + break; + case BurikoValueType.Int: + valueInt = stream.ReadInt32(); + break; + case BurikoValueType.String: + valueString = stream.ReadString(); + break; + case BurikoValueType.Variable: + stream.BaseStream.Seek(-2L, SeekOrigin.Current); + valueReference = ReadReference(stream); + break; + case BurikoValueType.Math: + { + BurikoMathType type = (BurikoMathType)stream.ReadInt16(); + BurikoVariable a = new BurikoVariable(stream); + BurikoVariable b = new BurikoVariable(stream); + Type = BurikoValueType.Int; + valueInt = PerformMath(type, a, b); + break; + } + case BurikoValueType.Operation: + valueVariable = BurikoScriptSystem.Instance.GetCurrentScript().ExecuteOperation((BurikoOperations)stream.ReadInt16()); + break; + default: + throw new NotImplementedException("BurikoVariable: Unhandled BurikoValueType " + Type); + } + } + + public static BurikoReference ReadReference(BinaryReader dataReader) + { + short num = dataReader.ReadInt16(); + if (num != 5) + { + throw new Exception("Cannot perform assignment to an object that is not a declared variable."); + } + string property = dataReader.ReadString(); + int member = new BurikoVariable(dataReader).IntValue(); + bool flag = dataReader.ReadBoolean(); + BurikoReference burikoReference = new BurikoReference(property, member); + if (flag) + { + burikoReference.Reference = ReadReference(dataReader); + } + return burikoReference; + } + + private static int PerformMath(BurikoMathType type, BurikoVariable a, BurikoVariable b) + { + int num = a.IntValue(); + int num2 = b.IntValue(); + switch (type) + { + case BurikoMathType.Equals: + return (num == num2) ? 1 : 0; + case BurikoMathType.Add: + return num + num2; + case BurikoMathType.Divide: + return num / num2; + case BurikoMathType.Multiply: + return num * num2; + case BurikoMathType.Subtract: + return num - num2; + case BurikoMathType.GreaterThan: + return (num > num2) ? 1 : 0; + case BurikoMathType.GreaterThanOrEquals: + return (num >= num2) ? 1 : 0; + case BurikoMathType.LessThan: + return (num < num2) ? 1 : 0; + case BurikoMathType.LessThanOrEquals: + return (num <= num2) ? 1 : 0; + case BurikoMathType.Modulus: + return num % num2; + case BurikoMathType.NotEquals: + return (num != num2) ? 1 : 0; + default: + throw new Exception("Cannot find a handler for math type " + type); + } + } + + public bool BoolValue() + { + switch (Type) + { + case BurikoValueType.Int: + case BurikoValueType.Bool: + if (valueInt != 0) + { + return true; + } + return false; + case BurikoValueType.String: + if (valueString == "0" || valueString == string.Empty) + { + return false; + } + return true; + default: + throw new NotImplementedException($"BurikoValue: Cannot cast type {Type} into type Bool."); + } + } + + public int IntValue() + { + switch (Type) + { + case BurikoValueType.Int: + case BurikoValueType.Bool: + return valueInt; + case BurikoValueType.String: + if (int.TryParse(valueString, out int result)) + { + return result; + } + throw new Exception("BurikoValue: Cannot parse type string into type int."); + case BurikoValueType.Variable: + { + IBurikoObject memory = BurikoMemory.Instance.GetMemory(valueReference.Property); + return memory.IntValue(valueReference); + } + case BurikoValueType.Operation: + return valueVariable.IntValue(); + default: + throw new NotImplementedException($"BurikoValue: Cannot cast type {Type} into type Int."); + } + } + + public string StringValue() + { + switch (Type) + { + case BurikoValueType.Null: + return string.Empty; + case BurikoValueType.Int: + case BurikoValueType.Bool: + return valueInt.ToString(CultureInfo.InvariantCulture); + case BurikoValueType.String: + return valueString; + case BurikoValueType.Variable: + if (BurikoMemory.Instance.IsMemory(valueReference.Property)) + { + IBurikoObject memory = BurikoMemory.Instance.GetMemory(valueReference.Property); + return memory.GetObject(valueReference).StringValue(); + } + if (BurikoMemory.Instance.IsFlag(valueReference.Property)) + { + return BurikoMemory.Instance.GetFlag(valueReference.Property).StringValue(); + } + throw new Exception("Unable to convert variable type to string!"); + case BurikoValueType.Operation: + return valueVariable.StringValue(); + default: + throw new NotImplementedException($"BurikoValue: Cannot cast type {Type} into type String."); + } + } + + public BurikoReference VariableValue() + { + if (Type != BurikoValueType.Variable) + { + throw new Exception("Cannot convert variable type " + Type + " to variable type Variable!"); + } + return valueReference; + } + + public string VariableName() + { + if (Type != BurikoValueType.Variable) + { + throw new Exception("Expected type variable, cannot accept type " + Type); + } + return valueReference.Property; + } + } +} diff --git a/Assets.Scripts.Core.Buriko/SaveEntry.cs b/Assets.Scripts.Core.Buriko/SaveEntry.cs new file mode 100644 index 00000000..70e294d8 --- /dev/null +++ b/Assets.Scripts.Core.Buriko/SaveEntry.cs @@ -0,0 +1,15 @@ +using System; + +namespace Assets.Scripts.Core.Buriko +{ + public class SaveEntry + { + public string Path; + + public string Text; + + public string TextJp; + + public DateTime Time; + } +} diff --git a/Assets.Scripts.Core.History/HistoryButton.cs b/Assets.Scripts.Core.History/HistoryButton.cs new file mode 100644 index 00000000..6357f06d --- /dev/null +++ b/Assets.Scripts.Core.History/HistoryButton.cs @@ -0,0 +1,29 @@ +using Assets.Scripts.Core.State; +using UnityEngine; + +namespace Assets.Scripts.Core.History +{ + public class HistoryButton : MonoBehaviour + { + public HistoryWindow Hw; + + private void OnPress(bool isDown) + { + if (isDown) + { + switch (base.name) + { + case "UpArrow": + Hw.Step(1f); + break; + case "DownArrow": + Hw.Step(-1f); + break; + case "Return": + (GameSystem.Instance.GetStateObject() as StateHistory)?.RequestLeave(); + break; + } + } + } + } +} diff --git a/Assets.Scripts.Core.History/HistoryLine.cs b/Assets.Scripts.Core.History/HistoryLine.cs new file mode 100644 index 00000000..b3d2f288 --- /dev/null +++ b/Assets.Scripts.Core.History/HistoryLine.cs @@ -0,0 +1,20 @@ +using Assets.Scripts.Core.Audio; + +namespace Assets.Scripts.Core.History +{ + public class HistoryLine + { + public string TextEnglish; + + public string TextJapanese; + + public AudioInfo VoiceFile; + + public HistoryLine(string english, string japanese, AudioInfo voice) + { + TextJapanese = japanese; + TextEnglish = english; + VoiceFile = voice; + } + } +} diff --git a/Assets.Scripts.Core.History/HistoryTextButton.cs b/Assets.Scripts.Core.History/HistoryTextButton.cs new file mode 100644 index 00000000..2e61b733 --- /dev/null +++ b/Assets.Scripts.Core.History/HistoryTextButton.cs @@ -0,0 +1,47 @@ +using Assets.Scripts.Core.Audio; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.Core.History +{ + public class HistoryTextButton : MonoBehaviour + { + private UITweener tweener; + + private TextMeshPro textMesh; + + private void OnHover(bool isHover) + { + } + + public void UpdateAlpha(float a) + { + textMesh.color = new Color(1f, 1f, 1f, a); + } + + public void FadeIn(float t) + { + textMesh = GetComponent(); + UpdateAlpha(0f); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0, "to", 1, "time", t, "onupdate", "UpdateAlpha", "oncomplete", "UpdateAlpha", "oncompleteparams", 1)); + } + + public void FadeOut(float t) + { + UpdateAlpha(1f); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 1, "to", 0, "time", t, "onupdate", "UpdateAlpha", "oncomplete", "UpdateAlpha", "oncompleteparams", 0)); + } + + public void ClearVoice() + { + } + + public void RegisterVoice(AudioInfo vfile) + { + } + + private void LateUpdate() + { + } + } +} diff --git a/Assets.Scripts.Core.History/HistoryWindow.cs b/Assets.Scripts.Core.History/HistoryWindow.cs new file mode 100644 index 00000000..4e8b7752 --- /dev/null +++ b/Assets.Scripts.Core.History/HistoryWindow.cs @@ -0,0 +1,148 @@ +using System.Collections; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.Core.History +{ + public class HistoryWindow : MonoBehaviour + { + public TextMeshPro[] Labels; + + public UISlider Slider; + + public UITexture BackgroundTexture; + + public UIPanel HistoryPanel; + + private HistoryTextButton[] textButtons; + + private GameSystem gameSystem; + + private TextHistory textHistory; + + private int stepCount; + + private int lastStep = -1; + + private float stepsize; + + private IEnumerator LeaveMenuAnimation(MenuUIController.MenuCloseDelegate onClose) + { + yield return (object)new WaitForEndOfFrame(); + LeanTween.cancel(BackgroundTexture.gameObject); + LeanTween.cancel(HistoryPanel.gameObject); + LeanTween.value(this.BackgroundTexture.gameObject, delegate(float f) + { + this.BackgroundTexture.alpha = f; + }, 0.5f, 0f, 0.2f); + LeanTween.value(this.HistoryPanel.gameObject, delegate(float f) + { + this.HistoryPanel.alpha = f; + }, 1f, 0f, 0.2f); + GameSystem.Instance.MainUIController.FadeIn(0.2f); + GameSystem.Instance.SceneController.RevealFace(0.2f); + HistoryTextButton[] array = textButtons; + foreach (HistoryTextButton t in array) + { + t.FadeOut(0.2f); + } + GameSystem.Instance.ExecuteActions(); + yield return (object)new WaitForSeconds(0.3f); + onClose?.Invoke(); + Object.Destroy(base.gameObject); + } + + public void Leave(MenuUIController.MenuCloseDelegate onClose) + { + StartCoroutine(LeaveMenuAnimation(onClose)); + } + + private void FillText() + { + for (int i = 0; i < 5; i++) + { + int id = i + lastStep; + HistoryLine line = textHistory.GetLine(id); + if (line == null) + { + Labels[i].text = string.Empty; + textButtons[i].ClearVoice(); + } + else + { + if (GameSystem.Instance.UseEnglishText) + { + Labels[i].text = line.TextEnglish; + } + else + { + Labels[i].text = line.TextJapanese; + } + if (line.VoiceFile != null) + { + textButtons[i].RegisterVoice(line.VoiceFile); + } + else + { + textButtons[i].ClearVoice(); + } + } + } + } + + public void Step(float f) + { + if (Slider.numberOfSteps == 2) + { + f *= 10f; + } + Slider.value -= f * stepsize; + } + + private void Awake() + { + gameSystem = GameSystem.Instance; + textHistory = gameSystem.TextHistory; + stepCount = textHistory.LineCount - 4; + Slider.numberOfSteps = Mathf.Clamp(stepCount, 1, 100); + Slider.value = 1f; + lastStep = Slider.numberOfSteps; + stepsize = 1f / (float)lastStep; + textButtons = new HistoryTextButton[5]; + for (int i = 0; i < 5; i++) + { + textButtons[i] = Labels[i].gameObject.GetComponent(); + } + FillText(); + HistoryTextButton[] array = textButtons; + foreach (HistoryTextButton historyTextButton in array) + { + historyTextButton.FadeIn(0.2f); + } + BackgroundTexture.alpha = 0f; + HistoryPanel.alpha = 0f; + LeanTween.value(BackgroundTexture.gameObject, delegate(float f) + { + BackgroundTexture.alpha = f; + }, 0f, 0.5f, 0.2f); + LeanTween.value(HistoryPanel.gameObject, delegate(float f) + { + HistoryPanel.alpha = f; + }, 0f, 1f, 0.2f); + } + + private void Update() + { + if (!Mathf.Approximately(Input.GetAxis("Mouse ScrollWheel"), 0f)) + { + Step(Input.GetAxis("Mouse ScrollWheel") * 10f); + } + int num = Mathf.RoundToInt(Slider.value * (float)(Slider.numberOfSteps - 1)); + if (num != lastStep) + { + lastStep = num; + FillText(); + } + } + } +} diff --git a/Assets.Scripts.Core.History/TextHistory.cs b/Assets.Scripts.Core.History/TextHistory.cs new file mode 100644 index 00000000..536ad6dd --- /dev/null +++ b/Assets.Scripts.Core.History/TextHistory.cs @@ -0,0 +1,70 @@ +using Assets.Scripts.Core.Audio; +using System.Collections.Generic; + +namespace Assets.Scripts.Core.History +{ + public class TextHistory + { + private const int MaxEntries = 100; + + private List lines = new List(); + + private AudioInfo lastVoice; + + private HistoryLine last; + + public int LineCount => lines.Count; + + public void ClearHistory() + { + lines = new List(); + } + + public void RegisterLine(string english, string japanese, string nameen, string namejp) + { + if (english.StartsWith("\n")) + { + english = english.Replace("\n", string.Empty); + japanese = japanese.Replace("\n", string.Empty); + PushHistory(); + if (english == string.Empty || japanese == string.Empty) + { + return; + } + } + if (last != null) + { + last.TextEnglish += english; + last.TextJapanese += japanese; + } + else + { + string english2 = string.Format(GameSystem.Instance.TextController.NameFormat, nameen) + english; + string japanese2 = string.Format(GameSystem.Instance.TextController.NameFormat, namejp) + japanese; + last = new HistoryLine(english2, japanese2, null); + } + } + + public void PushHistory() + { + if (last != null) + { + lines.Add(last); + } + if (lines.Count > 100) + { + lines.RemoveAt(0); + } + last = null; + } + + public HistoryLine GetLine(int id) + { + if (id < 0 || lines.Count <= id) + { + return null; + } + return lines[id]; + } + } +} diff --git a/Assets.Scripts.Core.Interfaces/IScriptInterpreter.cs b/Assets.Scripts.Core.Interfaces/IScriptInterpreter.cs new file mode 100644 index 00000000..fba39b2c --- /dev/null +++ b/Assets.Scripts.Core.Interfaces/IScriptInterpreter.cs @@ -0,0 +1,23 @@ +namespace Assets.Scripts.Core.Interfaces +{ + public interface IScriptInterpreter + { + void Initialize(GameSystem gameSystem); + + void Advance(); + + void SaveQuickSave(); + + void LoadQuickSave(); + + void SaveGame(int slotnum); + + void LoadGame(int slotnum); + + int GetFlag(string name); + + void SetFlag(string name, int value); + + void ShutDown(); + } +} diff --git a/Assets.Scripts.Core.Scene/BlackBars.cs b/Assets.Scripts.Core.Scene/BlackBars.cs new file mode 100644 index 00000000..56b2e9bf --- /dev/null +++ b/Assets.Scripts.Core.Scene/BlackBars.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class BlackBars : MonoBehaviour + { + public bool IsLeft; + + public void UpdatePosition() + { + int num = Mathf.RoundToInt(400f + 480f * GameSystem.Instance.AspectRatio / 2f); + if (IsLeft) + { + num *= -1; + } + base.transform.localPosition = new Vector3((float)num, 0f, 0f); + } + } +} diff --git a/Assets.Scripts.Core.Scene/FilmEffector.cs b/Assets.Scripts.Core.Scene/FilmEffector.cs new file mode 100644 index 00000000..cc4fdc71 --- /dev/null +++ b/Assets.Scripts.Core.Scene/FilmEffector.cs @@ -0,0 +1,139 @@ +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class FilmEffector : MonoBehaviour + { + public Material SceneMaterial; + + public float Power; + + private float targetPower; + + private bool isReady; + + private void Update() + { + } + + public void FadeOut(float time, bool isBlocking) + { + Debug.Log("Removing Effector"); + if (Mathf.Approximately(time, 0f)) + { + RemoveEffector(); + } + else + { + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("time", time, "from", Power, "to", 0, "onupdate", "UpdatePower", "oncomplete", "RemoveEffector")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(time, WaitTypes.WaitForScene, RemoveEffector)); + } + } + } + + private void UpdatePower(float p) + { + Power = p; + SceneMaterial.SetFloat("_Power", Power); + } + + private void SetFinalPower() + { + Power = targetPower; + Debug.Log(Power); + UpdatePower(Power); + } + + public void RemoveEffector() + { + if (!(SceneMaterial == null) && !(base.gameObject == null)) + { + iTween.Stop(base.gameObject); + Object.Destroy(SceneMaterial); + SceneMaterial = null; + base.gameObject.GetComponent().enabled = false; + Object.Destroy(this); + } + } + + public void Prepare(int effecttype, Color targetColor, int targetpower, int style, float length, bool isBlocking) + { + iTween.Stop(base.gameObject); + Shader shader = null; + bool flag = false; + switch (effecttype) + { + case 0: + case 1: + shader = Shader.Find("MGShader/EffectColorMix"); + flag = true; + break; + case 2: + shader = Shader.Find("MGShader/DrainColor"); + flag = true; + break; + case 3: + shader = Shader.Find("MGShader/Negative"); + break; + case 10: + shader = Shader.Find("MGShader/HorizontalBlur2"); + break; + case 12: + shader = Shader.Find("MGShader/GaussianBlur"); + break; + default: + Logger.LogError("FilmEffector created without a valid effecttype! Effect type specified: " + effecttype); + break; + } + float num = 0f; + if (SceneMaterial != null) + { + num = targetPower; + } + targetPower = (float)targetpower / 256f; + SceneMaterial = new Material(shader); + if (flag) + { + SceneMaterial.SetColor("_Color", targetColor); + } + if (length > 0f) + { + SceneMaterial.SetFloat("_Power", num); + if (targetpower == 0) + { + iTween.ValueTo(base.gameObject, iTween.Hash("time", length, "from", num, "to", targetPower, "onupdate", "UpdatePower", "oncomplete", "RemoveEffector")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(length, WaitTypes.WaitForScene, RemoveEffector)); + } + } + else + { + iTween.ValueTo(base.gameObject, iTween.Hash("time", length, "from", num, "to", targetPower, "onupdate", "UpdatePower", "oncomplete", "SetFinalPower")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(length, WaitTypes.WaitForScene, SetFinalPower)); + } + } + } + else + { + Power = targetPower; + SceneMaterial.SetFloat("_Power", Power); + } + isReady = true; + } + + private void OnRenderImage(RenderTexture source, RenderTexture dest) + { + if (isReady) + { + Graphics.Blit(source, dest, SceneMaterial); + RenderTexture.active = null; + } + } + } +} diff --git a/Assets.Scripts.Core.Scene/Layer.cs b/Assets.Scripts.Core.Scene/Layer.cs new file mode 100644 index 00000000..83a73846 --- /dev/null +++ b/Assets.Scripts.Core.Scene/Layer.cs @@ -0,0 +1,752 @@ +using Assets.Scripts.Core.AssetManagement; +using System.Collections; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class Layer : MonoBehaviour + { + private const string shaderDefaultName = "MGShader/LayerShader"; + + private const string shaderAlphaBlendName = "MGShader/LayerShaderAlpha"; + + private const string shaderCrossfadeName = "MGShader/LayerCrossfade4"; + + private const string shaderMaskedName = "MGShader/LayerMasked"; + + private const string shaderMultiplyName = "MGShader/LayerMultiply"; + + private const string shaderReverseZName = "MGShader/LayerShaderReverseZ"; + + private Mesh mesh; + + private MeshFilter meshFilter; + + private MeshRenderer meshRenderer; + + private Material material; + + private Texture2D primary; + + private Texture2D secondary; + + private Texture2D mask; + + public string PrimaryName = string.Empty; + + public string SecondaryName = string.Empty; + + public string MaskName = string.Empty; + + private Shader shaderDefault; + + private Shader shaderAlphaBlend; + + private Shader shaderCrossfade; + + private Shader shaderMasked; + + private Shader shaderMultiply; + + private Shader shaderReverseZ; + + public int Priority; + + private int shaderType; + + public bool IsInitialized; + + public bool IsStatic; + + public bool FadingOut; + + private float startRange; + + private float targetRange; + + public Vector3 targetPosition = new Vector3(0f, 0f, 0f); + + public Vector3 targetScale = new Vector3(1f, 1f, 1f); + + public float targetAngle; + + private bool isInMotion; + + private float targetAlpha; + + private LayerAlignment alignment; + + private MtnCtrlElement[] motion; + + public bool IsInUse => primary != null; + + public void RestoreScaleAndPosition(Vector3 scale, Vector3 position) + { + targetPosition = position; + targetScale = scale; + base.transform.localPosition = position; + base.transform.localScale = scale; + } + + private IEnumerator ControlledMotion() + { + MtnCtrlElement[] array = motion; + foreach (MtnCtrlElement mt in array) + { + float time = (float)mt.Time / 1000f; + MoveLayerEx(mt.Route, mt.Points, 1f - (float)mt.Transparancy / 256f, time); + yield return (object)new WaitForSeconds(time); + startRange = 1f - (float)mt.Transparancy / 256f; + } + FinishAll(); + if (motion[motion.Length - 1].Transparancy == 256) + { + HideLayer(); + } + isInMotion = false; + } + + public void ControlLayerMotion(MtnCtrlElement[] motions) + { + if (isInMotion) + { + base.transform.localPosition = targetPosition; + } + motion = motions; + MtnCtrlElement mtnCtrlElement = motion[motion.Length - 1]; + Vector3 vector = mtnCtrlElement.Route[mtnCtrlElement.Points - 1]; + Vector3 localPosition = base.transform.localPosition; + vector.z = localPosition.z; + targetPosition = vector; + targetRange = (float)mtnCtrlElement.Transparancy / 256f; + GameSystem.Instance.RegisterAction(delegate + { + StartCoroutine("ControlledMotion"); + }); + } + + public void MoveLayerEx(Vector3[] path, int points, float alpha, float time) + { + iTween.Stop(base.gameObject); + Vector3[] array = new Vector3[points + 1]; + array[0] = base.transform.localPosition; + for (int i = 0; i < points; i++) + { + array[i + 1].x = path[i].x; + array[i + 1].y = 0f - path[i].y; + ref Vector3 reference = ref array[i + 1]; + Vector3 localPosition = base.transform.localPosition; + reference.z = localPosition.z; + } + if (UsingCrossShader()) + { + alpha = 1f - alpha; + } + startRange = targetAlpha; + targetPosition = array[array.Length - 1]; + targetAlpha = alpha; + FadeTo(alpha, time); + isInMotion = true; + if (path.Length > 1) + { + iTween.MoveTo(base.gameObject, iTween.Hash("path", array, "movetopath", false, "time", time, "islocal", true, "easetype", iTween.EaseType.linear)); + } + else + { + iTween.MoveTo(base.gameObject, iTween.Hash("position", array[1], "time", time, "islocal", true, "easetype", iTween.EaseType.linear)); + } + } + + public void MoveLayer(int x, int y, int z, float alpha, int easetype, float wait, bool isBlocking, bool adjustAlpha) + { + float num = 1f; + if (z > 0) + { + num = 1f - (float)z / 400f; + } + if (z < 0) + { + num = 1f + (float)z / -400f; + } + float x2 = (float)x; + float y2 = (float)(-y); + Vector3 localPosition = base.transform.localPosition; + targetPosition = new Vector3(x2, y2, localPosition.z); + targetScale = new Vector3(num, num, 1f); + if (adjustAlpha) + { + startRange = targetAlpha; + targetRange = alpha; + targetAlpha = alpha; + } + GameSystem.Instance.RegisterAction(delegate + { + if (Mathf.Approximately(wait, 0f)) + { + FinishAll(); + } + else + { + if (adjustAlpha) + { + if (Mathf.Approximately(alpha, 0f)) + { + FadeOut(wait); + } + else + { + FadeTo(alpha, wait); + } + } + iTween.EaseType easeType = iTween.EaseType.linear; + switch (easetype) + { + case 0: + easeType = iTween.EaseType.linear; + break; + case 1: + easeType = iTween.EaseType.easeInOutSine; + break; + case 2: + easeType = iTween.EaseType.easeInOutSine; + break; + case 3: + easeType = iTween.EaseType.easeInOutQuad; + break; + case 4: + easeType = iTween.EaseType.easeInSine; + break; + case 5: + easeType = iTween.EaseType.easeOutSine; + break; + case 6: + easeType = iTween.EaseType.easeInQuad; + break; + case 7: + easeType = iTween.EaseType.easeOutQuad; + break; + case 8: + easeType = iTween.EaseType.easeInCubic; + break; + case 9: + easeType = iTween.EaseType.easeOutCubic; + break; + case 10: + easeType = iTween.EaseType.easeInQuart; + break; + case 11: + easeType = iTween.EaseType.easeOutQuart; + break; + case 12: + easeType = iTween.EaseType.easeInExpo; + break; + case 13: + easeType = iTween.EaseType.easeOutExpo; + break; + case 14: + easeType = iTween.EaseType.easeInExpo; + break; + case 15: + easeType = iTween.EaseType.easeOutExpo; + break; + } + iTween.ScaleTo(base.gameObject, iTween.Hash("scale", targetScale, "time", wait, "islocal", true, "easetype", easeType, "oncomplete", "FinishAll", "oncompletetarget", base.gameObject)); + iTween.MoveTo(base.gameObject, iTween.Hash("position", targetPosition, "time", wait, "islocal", true, "easetype", easeType, "oncomplete", "FinishAll", "oncompletetarget", base.gameObject)); + if (isBlocking) + { + if (Mathf.Approximately(alpha, 0f) && adjustAlpha) + { + GameSystem.Instance.AddWait(new Wait(wait, WaitTypes.WaitForMove, HideLayer)); + } + else + { + GameSystem.Instance.AddWait(new Wait(wait, WaitTypes.WaitForMove, FinishAll)); + } + } + else if (wait > 0f) + { + StartCoroutine(WaitThenFinish(wait)); + } + } + }); + } + + public IEnumerator WaitThenFinish(float time) + { + yield return (object)new WaitForSeconds(time); + FinishAll(); + } + + public void FadeOutLayer(float time, bool isBlocking) + { + if (!(primary == null)) + { + float current = targetRange; + targetRange = 0f; + targetAlpha = 0f; + GameSystem.Instance.RegisterAction(delegate + { + if (Mathf.Approximately(time, 0f)) + { + HideLayer(); + } + else + { + material.shader = shaderDefault; + current = 1f; + FadingOut = true; + iTween.ValueTo(base.gameObject, iTween.Hash("from", current, "to", targetRange, "time", time, "onupdate", "SetRange", "oncomplete", "HideLayer")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(time, WaitTypes.WaitForMove, HideLayer)); + } + } + }); + } + } + + public void DrawLayerWithMask(string textureName, string maskName, int x, int y, Vector2? origin, bool isBustshot, int style, float wait, bool isBlocking) + { + Texture2D texture2D = AssetManager.Instance.LoadTexture(textureName); + Texture2D maskTexture = AssetManager.Instance.LoadTexture(maskName); + material.shader = shaderMasked; + SetPrimaryTexture(texture2D); + SetMaskTexture(maskTexture); + PrimaryName = textureName; + MaskName = maskName; + startRange = 0f; + targetRange = 1f; + targetAlpha = 1f; + targetAngle = 0f; + shaderType = 0; + if (mesh == null) + { + alignment = LayerAlignment.AlignCenter; + if ((x != 0 || y != 0) && !isBustshot) + { + alignment = LayerAlignment.AlignTopleft; + } + if (origin.HasValue) + { + CreateMesh(texture2D.width, texture2D.height, origin.GetValueOrDefault()); + } + else + { + CreateMesh(texture2D.width, texture2D.height, alignment); + } + } + SetRange(startRange); + base.transform.localPosition = new Vector3((float)x, (float)(-y), (float)Priority * -0.1f); + GameSystem.Instance.RegisterAction(delegate + { + meshRenderer.enabled = true; + material.SetFloat("_Fuzziness", (style != 0) ? 0.15f : 0.45f); + material.SetFloat("_Direction", 1f); + FadeInLayer(wait); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(wait, WaitTypes.WaitForMove, FinishAll)); + } + }); + } + + public void FadeLayerWithMask(string maskName, int style, float time, bool isBlocking) + { + Texture2D maskTexture = AssetManager.Instance.LoadTexture(maskName); + material.shader = shaderMasked; + SetMaskTexture(maskTexture); + material.SetFloat("_Fuzziness", (style != 0) ? 0.15f : 0.45f); + material.SetFloat("_Direction", 0f); + startRange = 1f; + targetRange = 0f; + targetAlpha = 0f; + SetRange(startRange); + GameSystem.Instance.RegisterAction(delegate + { + iTween.ValueTo(base.gameObject, iTween.Hash("from", startRange, "to", targetRange, "time", time, "onupdate", "SetRange", "oncomplete", "HideLayer")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(time, WaitTypes.WaitForMove, HideLayer)); + } + }); + } + + public void DrawLayer(string textureName, int x, int y, int z, Vector2? origin, float alpha, bool isBustshot, int type, float wait, bool isBlocking) + { + FinishAll(); + if (textureName == string.Empty) + { + HideLayer(); + } + else + { + Texture2D texture2D = AssetManager.Instance.LoadTexture(textureName); + if (texture2D == null) + { + Logger.LogError("Failed to load texture " + textureName); + } + else + { + startRange = 0f; + targetRange = alpha; + targetAlpha = alpha; + meshRenderer.enabled = true; + shaderType = type; + PrimaryName = textureName; + float num = 1f; + if (z > 0) + { + num = 1f - (float)z / 400f; + } + if (z < 0) + { + num = 1f + (float)z / -400f; + } + if (mesh == null) + { + alignment = LayerAlignment.AlignCenter; + if ((x != 0 || y != 0) && !isBustshot) + { + alignment = LayerAlignment.AlignTopleft; + } + if (origin.HasValue) + { + CreateMesh(texture2D.width, texture2D.height, origin.GetValueOrDefault()); + } + else + { + CreateMesh(texture2D.width, texture2D.height, alignment); + } + } + if (primary != null) + { + material.shader = shaderCrossfade; + SetSecondaryTexture(primary); + SetPrimaryTexture(texture2D); + startRange = 1f; + targetRange = 0f; + targetAlpha = 1f; + } + else + { + material.shader = shaderDefault; + if (type == 3) + { + material.shader = shaderMultiply; + } + SetPrimaryTexture(texture2D); + } + SetRange(startRange); + base.transform.localPosition = new Vector3((float)x, (float)(-y), (float)Priority * -0.1f); + base.transform.localScale = new Vector3(num, num, 1f); + targetPosition = base.transform.localPosition; + targetScale = base.transform.localScale; + if (Mathf.Approximately(wait, 0f)) + { + FinishFade(); + } + else + { + GameSystem.Instance.RegisterAction(delegate + { + if (Mathf.Approximately(wait, 0f)) + { + FinishFade(); + } + else + { + FadeInLayer(wait); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(wait, WaitTypes.WaitForMove, FinishFade)); + } + } + }); + } + } + } + } + + public void SetAngle(float angle, float wait) + { + base.transform.localRotation = Quaternion.AngleAxis(targetAngle, Vector3.forward); + targetAngle = angle; + GameSystem.Instance.RegisterAction(delegate + { + if (Mathf.Approximately(wait, 0f)) + { + base.transform.localRotation = Quaternion.AngleAxis(targetAngle, Vector3.forward); + } + else + { + iTween.RotateTo(base.gameObject, iTween.Hash("z", targetAngle, "time", wait, "isLocal", true, "easetype", "linear", "oncomplete", "FinishAll")); + } + }); + } + + public void CrossfadeLayer(string targetImage, float wait, bool isBlocking) + { + Texture2D primaryTexture = AssetManager.Instance.LoadTexture(targetImage); + material.shader = shaderCrossfade; + SetSecondaryTexture(primary); + SetPrimaryTexture(primaryTexture); + startRange = 1f; + targetRange = 0f; + targetAlpha = 1f; + SetRange(startRange); + GameSystem.Instance.RegisterAction(delegate + { + if (Mathf.Approximately(wait, 0f)) + { + FinishFade(); + } + else + { + FadeInLayer(wait); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(wait, WaitTypes.WaitForMove, FinishFade)); + } + } + }); + } + + public bool UsingCrossShader() + { + if (material.shader.name == shaderCrossfade.name) + { + return true; + } + return false; + } + + public void SwitchToAlphaShader() + { + material.shader = shaderAlphaBlend; + } + + public void SwitchToMaskedShader() + { + material.shader = shaderReverseZ; + } + + public void SetPriority(int newpriority) + { + Priority = newpriority + 1; + Vector3 localPosition = base.transform.localPosition; + float x = localPosition.x; + Vector3 localPosition2 = base.transform.localPosition; + targetPosition = new Vector3(x, localPosition2.y, (float)Priority * -0.1f); + base.transform.localPosition = targetPosition; + } + + public void FadeInLayer(float time) + { + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("from", startRange, "to", targetRange, "time", time, "onupdate", "SetRange", "oncomplete", "FinishFade")); + } + + public void FadeTo(float alpha, float time) + { + iTween.Stop(base.gameObject); + startRange = targetRange; + targetRange = alpha; + iTween.ValueTo(base.gameObject, iTween.Hash("from", startRange, "to", targetRange, "time", time, "onupdate", "SetRange", "oncomplete", "FinishFade")); + } + + public void FadeOut(float time) + { + if (material.shader.name == shaderCrossfade.name) + { + material.shader = shaderDefault; + startRange = 1f; + } + FadingOut = true; + targetRange = 0f; + iTween.ValueTo(base.gameObject, iTween.Hash("from", startRange, "to", targetRange, "time", time, "onupdate", "SetRange", "oncomplete", "HideLayer")); + } + + public void FinishAll() + { + StopCoroutine("MoveLayerEx"); + iTween.Stop(base.gameObject); + FinishFade(); + base.transform.localPosition = targetPosition; + base.transform.localScale = targetScale; + base.transform.localRotation = Quaternion.AngleAxis(targetAngle, Vector3.forward); + } + + public void FinishFade() + { + iTween.Stop(base.gameObject); + SetRange(targetRange); + } + + public void SetRange(float a) + { + if (material.shader.name != shaderCrossfade.name && material.shader.name != shaderMasked.name) + { + material.SetFloat("_Alpha", a); + } + else + { + material.SetFloat("_Range", a); + } + } + + private void SetPrimaryTexture(Texture2D tex) + { + primary = tex; + material.SetTexture("_Primary", primary); + meshRenderer.enabled = true; + } + + private void SetSecondaryTexture(Texture2D tex) + { + secondary = tex; + material.SetTexture("_Secondary", secondary); + } + + private void SetMaskTexture(Texture2D tex) + { + mask = tex; + material.SetTexture("_Mask", mask); + } + + public void HideLayer() + { + iTween.Stop(base.gameObject); + ReleaseTextures(); + if (!IsStatic) + { + GameSystem.Instance.SceneController.LayerPool.ReturnLayer(this); + GameSystem.Instance.SceneController.RemoveLayerReference(this); + } + targetAngle = 0f; + } + + public void ReloadTexture() + { + if (PrimaryName == string.Empty) + { + HideLayer(); + } + else + { + Texture2D texture2D = AssetManager.Instance.LoadTexture(PrimaryName); + if (texture2D == null) + { + Logger.LogError("Failed to load texture " + PrimaryName); + } + else + { + SetPrimaryTexture(texture2D); + } + } + } + + public void ReleaseTextures() + { + if (!(primary == null)) + { + ReleaseSecondaryTexture(); + ReleaseMaskTexture(); + Object.Destroy(primary); + primary = null; + material.shader = shaderDefault; + material.SetTexture("_Primary", null); + meshRenderer.enabled = false; + PrimaryName = string.Empty; + SecondaryName = string.Empty; + MaskName = string.Empty; + Object.Destroy(mesh); + mesh = null; + meshFilter.mesh = null; + FadingOut = false; + shaderType = 0; + targetAngle = 0f; + } + } + + private void ReleaseSecondaryTexture() + { + if (!(secondary == null)) + { + Object.Destroy(secondary); + secondary = null; + SecondaryName = string.Empty; + material.SetTexture("_Secondary", null); + } + } + + private void ReleaseMaskTexture() + { + if (!(mask == null)) + { + Object.Destroy(mask); + mask = null; + MaskName = string.Empty; + material.SetTexture("_Mask", null); + } + } + + private void CreateMesh(int width, int height, Vector2 origin) + { + int num = Mathf.Clamp(height, 1, 480); + int num2 = num / height; + int width2 = Mathf.RoundToInt((float)Mathf.Clamp(width, 1, num2 * width)); + mesh = MGHelper.CreateMeshWithOrigin(width2, num, origin); + meshFilter.mesh = mesh; + } + + private void CreateMesh(int width, int height, LayerAlignment alignment) + { + int num = Mathf.Clamp(height, 1, 480); + float num2 = (float)num / (float)height; + int width2 = Mathf.RoundToInt(Mathf.Clamp((float)width, 1f, num2 * (float)width)); + mesh = MGHelper.CreateMesh(width2, num, alignment); + meshFilter.mesh = mesh; + } + + private void Initialize() + { + shaderDefault = Shader.Find("MGShader/LayerShader"); + shaderAlphaBlend = Shader.Find("MGShader/LayerShaderAlpha"); + shaderCrossfade = Shader.Find("MGShader/LayerCrossfade4"); + shaderMasked = Shader.Find("MGShader/LayerMasked"); + shaderMultiply = Shader.Find("MGShader/LayerMultiply"); + shaderReverseZ = Shader.Find("MGShader/LayerShaderReverseZ"); + shaderType = 0; + meshFilter = GetComponent(); + meshRenderer = GetComponent(); + material = new Material(shaderDefault); + meshRenderer.material = material; + meshRenderer.enabled = false; + targetAngle = 0f; + IsInitialized = true; + } + + public void Serialize(BinaryWriter br) + { + MGHelper.WriteVector3(br, targetPosition); + MGHelper.WriteVector3(br, targetScale); + br.Write(PrimaryName); + br.Write(targetAlpha); + br.Write((int)alignment); + br.Write(shaderType); + } + + private void Awake() + { + if (!IsInitialized) + { + Initialize(); + } + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.Core.Scene/LayerOld.cs b/Assets.Scripts.Core.Scene/LayerOld.cs new file mode 100644 index 00000000..e2b33ab9 --- /dev/null +++ b/Assets.Scripts.Core.Scene/LayerOld.cs @@ -0,0 +1,278 @@ +using Assets.Scripts.Core.AssetManagement; +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class LayerOld : MonoBehaviour + { + public Shader LayerShader; + + public Shader LayerShaderNormal; + + public Shader LayerAddative; + + public Shader LayerCrossfade; + + public Shader LayerFadeWithMask; + + private Mesh mesh; + + private MeshFilter meshFilter; + + private MeshRenderer meshRenderer; + + private Material material; + + private Texture2D primary; + + private Texture2D secondary; + + private float targetalpha; + + private Vector3 endpos = new Vector3(0f, 0f, 0f); + + public int LayerNum; + + private void Prepare(int width, int height, Shader shader, LayerAlignment align, bool retainMainTexture) + { + if (meshFilter == null) + { + meshFilter = base.gameObject.AddComponent(); + } + if (meshRenderer == null) + { + meshRenderer = base.gameObject.AddComponent(); + } + mesh = MGHelper.CreateMesh(width, height, align); + if (material != null) + { + if (!retainMainTexture) + { + Object.Destroy(primary); + } + Object.Destroy(material); + } + material = new Material(shader); + meshFilter.mesh = mesh; + meshRenderer.material = material; + } + + public void HideLayer() + { + ChangeBlendMode(0); + iTween.Stop(base.gameObject); + base.transform.localPosition = new Vector3(0f, 0f, 0f); + Object.Destroy(material); + Object.Destroy(meshRenderer); + Object.Destroy(meshFilter); + if (primary != null) + { + Object.Destroy(primary); + primary = null; + } + if (secondary != null) + { + Object.Destroy(secondary); + secondary = null; + } + } + + public void UpdateAlpha(float a) + { + material.SetFloat("_Alpha", a); + } + + public void UpdateOpaque() + { + material.SetFloat("_Alpha", 0f); + } + + public void FinalizeAlpha() + { + material.SetFloat("_Alpha", targetalpha); + } + + public void UpdateRange(float r) + { + material.SetFloat("_Range", r); + } + + public void FinalizeFade() + { + Object.Destroy(secondary); + material.shader = LayerShader; + material.SetTexture("_MainTex", primary); + material.SetFloat("_Alpha", 0f); + } + + public void FinalizeMove() + { + iTween.Stop(base.gameObject); + base.transform.localPosition = endpos; + } + + public void FinalizeAll() + { + FinalizeFade(); + FinalizeMove(); + } + + public void ChangeBlendMode(int mode) + { + switch (mode) + { + case 0: + LayerShader = LayerShaderNormal; + break; + case 1: + LayerShader = LayerAddative; + break; + default: + Logger.LogWarning("Unknown Blend Mode: " + mode); + break; + } + } + + public void FadeOutSprite(float wait, bool isblocking) + { + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0f, "to", 1f, "time", wait, "onupdate", "UpdateAlpha", "oncomplete", "HideLayer")); + if (isblocking) + { + GameSystem.Instance.AddWait(new Wait(wait / 1000f, WaitTypes.WaitForMove, HideLayer)); + } + } + + public void FadeInSprite(float wait, bool isblocking) + { + material.SetFloat("_Alpha", 1f); + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 1f, "to", 0f, "time", wait, "onupdate", "UpdateAlpha", "oncomplete", "UpdateOpaque")); + if (isblocking) + { + GameSystem.Instance.AddWait(new Wait(wait / 1000f, WaitTypes.WaitForMove, UpdateOpaque)); + } + } + + public void MoveSprite(int x, int y, int z, int alpha, float wait, bool isblocking) + { + targetalpha = 0f + (float)alpha / 256f; + float @float = material.GetFloat("_Alpha"); + if (!Mathf.Approximately(targetalpha, @float)) + { + iTween.ValueTo(base.gameObject, iTween.Hash("from", @float, "to", targetalpha, "time", wait, "onupdate", "UpdateAlpha", "oncomplete", "FinalizeAlpha")); + } + float targetscale = 1f; + if (z > 0) + { + targetscale = 1f - (float)z / 100f; + } + if (z < 0) + { + targetscale = 1f + (float)z / -100f; + } + float x2 = (float)x; + float y2 = (float)y; + Vector3 localPosition = base.transform.localPosition; + endpos = new Vector3(x2, y2, localPosition.z); + iTween.ScaleTo(base.gameObject, iTween.Hash("scale", new Vector3(targetscale, targetscale, 1f), "time", wait, "islocal", true)); + iTween.MoveTo(base.gameObject, iTween.Hash("position", endpos, "time", wait, "islocal", true)); + if (isblocking) + { + GameSystem.Instance.AddWait(new Wait(wait, WaitTypes.WaitForMove, delegate + { + iTween.Stop(base.gameObject); + base.transform.localScale = new Vector3(targetscale, targetscale, 1f); + FinalizeAll(); + })); + } + } + + public void DrawSprite(string textureName, int x, int y, int z, int alpha, int priority, float wait, bool isblocking) + { + iTween.Stop(base.gameObject); + Texture2D texture2D = AssetManager.Instance.LoadTexture(textureName); + if (!(texture2D == null)) + { + LayerAlignment align = LayerAlignment.AlignCenter; + if (x != 0 || y != 0) + { + align = LayerAlignment.AlignTopleft; + } + Prepare(texture2D.width, texture2D.height, LayerShader, align, retainMainTexture: false); + float num = 1f; + if (z > 0) + { + num = 1f - (float)z / 100f; + } + if (z < 0) + { + num = 1f + (float)z / -100f; + } + base.transform.localPosition = new Vector3((float)x, (float)(y * -1), (float)priority * -0.1f); + base.transform.localScale = new Vector3(num, num, 1f); + material.SetTexture("_MainTex", texture2D); + if (wait > 0f) + { + FadeInSprite(wait, isblocking); + } + else + { + material.SetFloat("_Alpha", 0f + (float)alpha / 256f); + } + } + } + + public void DrawBustshot(string textureName, float x, float y, float z, float oldx, float oldy, float oldz, bool move, int priority, float wait, bool isblocking) + { + Vector3 localPosition = (!move) ? new Vector3(x, y, (float)priority * -0.1f) : new Vector3(oldx, oldy, (float)priority * -0.1f); + base.transform.localPosition = localPosition; + endpos = new Vector3(x, y, (float)priority * -0.1f); + SetTextureCrossFade(textureName, wait, LayerAlignment.AlignCenter); + if (move) + { + iTween.MoveTo(base.gameObject, iTween.Hash("position", endpos, "time", wait, "islocal", true)); + } + if (isblocking) + { + GameSystem.Instance.AddWait(new Wait(wait, WaitTypes.WaitForMove, FinalizeAll)); + } + } + + public void SetTextureCrossFade(string textureName, float time, LayerAlignment align) + { + Texture2D texture2D = AssetManager.Instance.LoadTexture(textureName); + if (!(texture2D == null)) + { + if (primary != null) + { + Prepare(texture2D.width, texture2D.height, LayerCrossfade, align, retainMainTexture: true); + secondary = primary; + primary = texture2D; + material.SetTexture("_Primary", primary); + material.SetTexture("_Secondary", secondary); + material.SetFloat("_Range", 0f); + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0f, "to", 1f, "time", time, "onupdate", "UpdateRange", "oncomplete", "FinalizeFade")); + } + else + { + SetTextureImmediate(textureName, align); + FadeInSprite(time, isblocking: false); + } + } + } + + public void SetTextureImmediate(string textureName, LayerAlignment align) + { + Texture2D texture2D = AssetManager.Instance.LoadTexture(textureName); + if (!(texture2D == null)) + { + Prepare(texture2D.width, texture2D.height, LayerShader, align, retainMainTexture: false); + primary = texture2D; + material.SetTexture("_MainTex", texture2D); + material.SetFloat("_Alpha", 0f); + } + } + } +} diff --git a/Assets.Scripts.Core.Scene/LayerPool.cs b/Assets.Scripts.Core.Scene/LayerPool.cs new file mode 100644 index 00000000..3020ec4c --- /dev/null +++ b/Assets.Scripts.Core.Scene/LayerPool.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class LayerPool : MonoBehaviour + { + public GameObject Panel; + + public int PoolSize; + + private Stack layerList = new Stack(); + + private List layerObjList = new List(); + + public Layer ActivateLayer() + { + GameObject gameObject = layerList.Pop(); + gameObject.transform.parent = Panel.transform; + gameObject.transform.localPosition = new Vector3(0f, 0f, 0f); + gameObject.transform.localScale = new Vector3(1f, 1f, 1f); + Layer component = gameObject.GetComponent(); + gameObject.SetActive(value: true); + layerObjList.Remove(gameObject); + return component; + } + + public void ReturnLayer(Layer layer) + { + GameObject gameObject = layer.gameObject; + gameObject.transform.parent = base.transform; + gameObject.layer = LayerMask.NameToLayer("NotRendered"); + gameObject.SetActive(value: false); + layerList.Push(gameObject); + layerObjList.Add(gameObject); + } + + public bool IsInPool(GameObject layer) + { + return layerObjList.Exists((GameObject a) => a == layer); + } + + private void Awake() + { + GameObject original = Resources.Load("Layer"); + int num = 0; + while (true) + { + if (num >= PoolSize) + { + return; + } + GameObject gameObject = UnityEngine.Object.Instantiate(original); + if (gameObject == null) + { + break; + } + gameObject.transform.parent = base.transform; + gameObject.SetActive(value: false); + layerList.Push(gameObject); + layerObjList.Add(gameObject); + num++; + } + throw new Exception("Failed to instantiate Layer prefab!"); + } + } +} diff --git a/Assets.Scripts.Core.Scene/MtnCtrlElement.cs b/Assets.Scripts.Core.Scene/MtnCtrlElement.cs new file mode 100644 index 00000000..2aa46be9 --- /dev/null +++ b/Assets.Scripts.Core.Scene/MtnCtrlElement.cs @@ -0,0 +1,34 @@ +using System; +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + [Serializable] + public class MtnCtrlElement + { + public int Points; + + public int Angle; + + public int Transparancy; + + public int StyleOfMovement; + + public int StyleOfRotation; + + public int Time; + + public Vector3[] Route = new Vector3[16]; + + public void CopyFrom(MtnCtrlElement src) + { + Points = src.Points; + Angle = src.Angle; + Transparancy = src.Transparancy; + StyleOfMovement = src.StyleOfMovement; + StyleOfRotation = src.StyleOfRotation; + Time = src.Time; + Route = (src.Route.Clone() as Vector3[]); + } + } +} diff --git a/Assets.Scripts.Core.Scene/Scene.cs b/Assets.Scripts.Core.Scene/Scene.cs new file mode 100644 index 00000000..e73520d8 --- /dev/null +++ b/Assets.Scripts.Core.Scene/Scene.cs @@ -0,0 +1,167 @@ +using Assets.Scripts.Core.AssetManagement; +using System; +using System.Collections; +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + [RequireComponent(typeof(Camera))] + [RequireComponent(typeof(UICamera))] + public class Scene : MonoBehaviour + { + public GameObject Panel; + + public LayerMask LayerMask; + + public string LayerName; + + public bool HasBackground; + + [HideInInspector] + public Layer BackgroundLayer; + + private SceneController sceneController; + + private UICamera uiCamera; + + public Material sceneMaterial; + + private Shader defaultShader; + + private Shader maskShader; + + private Shader fadeShader; + + public float Depth + { + get + { + return GetComponent().depth; + } + set + { + GetComponent().depth = value; + } + } + + public bool IsEnabled + { + get + { + return GetComponent().enabled; + } + set + { + GetComponent().enabled = value; + uiCamera.enabled = value; + } + } + + public void SetTransitionMask(string maskname) + { + sceneMaterial.shader = maskShader; + Texture2D texture = AssetManager.Instance.LoadTexture(maskname); + sceneMaterial.SetTexture("_Mask", texture); + sceneMaterial.SetFloat("_Fuzzyness", 0.45f); + UpdateRange(0f); + } + + public void StartTransition(float time) + { + base.gameObject.SetActive(value: true); + UpdateRange(0f); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0f, "to", 1f, "time", time, "onupdate", "UpdateRange", "oncomplete", "UpdateRange", "oncompleteparams", 1f)); + } + + public void FadeSceneIn(float time) + { + base.gameObject.SetActive(value: true); + sceneMaterial.shader = fadeShader; + StartTransition(time); + } + + public void StopFadeIn() + { + iTween.Stop(base.gameObject); + UpdateRange(1f); + Layer[] componentsInChildren = Panel.GetComponentsInChildren(); + foreach (Layer layer in componentsInChildren) + { + if (layer.gameObject.layer != sceneController.GetActiveLayerMask()) + { + if (layer.gameObject.layer == LayerMask.NameToLayer("RenderBoth")) + { + layer.gameObject.layer = sceneController.GetActiveLayerMask(); + } + else if (layer.Priority < SceneController.UpperLayerRange && layer.tag != "BackgroundLayer") + { + layer.HideLayer(); + } + } + } + sceneController.HideBackgroundSceneObject(); + if (base.gameObject.activeInHierarchy) + { + StartCoroutine(ChangeShader(defaultShader)); + } + else + { + sceneMaterial.shader = defaultShader; + } + } + + public void UpdateRange(float r) + { + if (sceneMaterial != null) + { + sceneMaterial.SetFloat("_Range", r); + } + } + + private IEnumerator ChangeShader(Shader target) + { + yield return (object)new WaitForEndOfFrame(); + sceneMaterial.shader = target; + } + + private void Awake() + { + sceneController = base.transform.parent.parent.GetComponent(); + uiCamera = GetComponent(); + GetComponent().cullingMask = LayerMask; + if (HasBackground) + { + GameObject gameObject = UnityEngine.Object.Instantiate(Resources.Load("Layer", typeof(GameObject))) as GameObject; + if (gameObject == null) + { + throw new Exception("Failed to instantiate Layer prefab!"); + } + gameObject.transform.parent = Panel.transform; + gameObject.layer = LayerMask.NameToLayer(LayerName); + gameObject.transform.localPosition = new Vector3(0f, 0f, 9.9f); + gameObject.transform.localScale = new Vector3(1f, 1f, 1f); + gameObject.tag = "BackgroundLayer"; + gameObject.name = base.name + " Background"; + BackgroundLayer = gameObject.GetComponent(); + } + defaultShader = Shader.Find("MGShader/SceneOpaque"); + maskShader = Shader.Find("MGShader/SceneFadeWithMask"); + fadeShader = Shader.Find("MGShader/SceneFade"); + sceneMaterial = new Material(defaultShader); + } + + private void Update() + { + GetComponent().cullingMask = LayerMask; + uiCamera.eventReceiverMask = LayerMask; + } + + private void OnRenderImage(RenderTexture source, RenderTexture dest) + { + if (!(sceneMaterial == null)) + { + Graphics.Blit(source, dest, sceneMaterial); + } + } + } +} diff --git a/Assets.Scripts.Core.Scene/SceneController.cs b/Assets.Scripts.Core.Scene/SceneController.cs new file mode 100644 index 00000000..05fa0b68 --- /dev/null +++ b/Assets.Scripts.Core.Scene/SceneController.cs @@ -0,0 +1,781 @@ +using System; +using System.Collections; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class SceneController : MonoBehaviour + { + public GameObject Scene1; + + public GameObject Scene2; + + public GameObject Scene3; + + public GameObject SceneCameras; + + public GameObject EffectCamera; + + public LayerPool LayerPool; + + public GameObject Panel; + + public GameObject FacePanel; + + public Camera ScreenshotCamera; + + private Scene scene1; + + private Scene scene2; + + private GameSystem gameSystem; + + private Layer[] layers = new Layer[64]; + + private Layer faceLayer; + + private int activeScene; + + public static int UpperLayerRange = 32; + + private Vector3 defaultOffset = new Vector3(0f, 0f, 0f); + + private Vector3 targetPosition; + + private Vector3 targetScale; + + private bool faceToUpperLayer = true; + + private string faceName = string.Empty; + + private bool useFilm; + + private bool useHorizontalBlur; + + private bool useBlur; + + private int filmType; + + private int filmPower; + + private int filmStyle; + + private Color filmColor = Color.white; + + private FilmEffector effector; + + private int lastWidth; + + public Layer GetIfInUse(int id) + { + if (layers[id] != null && !LayerPool.IsInPool(layers[id].gameObject) && layers[id].IsInUse) + { + return layers[id]; + } + return null; + } + + public Layer GetLayer(int id) + { + if (layers[id] != null && !LayerPool.IsInPool(layers[id].gameObject) && layers[id].IsInUse) + { + return layers[id]; + } + Layer layer = LayerPool.ActivateLayer(); + layer.name = "Layer " + id; + layers[id] = layer; + return layer; + } + + public void RemoveLayerReference(Layer l) + { + for (int i = 0; i < layers.Length; i++) + { + if (l == layers[i]) + { + layers[i] = null; + } + } + } + + public int GetActiveLayerMask() + { + if (activeScene == 0) + { + return LayerMask.NameToLayer("Scene1"); + } + return LayerMask.NameToLayer("Scene2"); + } + + private void UpdateLayerMask(Layer layer, int priority) + { + if (priority >= UpperLayerRange) + { + layer.gameObject.layer = LayerMask.NameToLayer("Scene3"); + } + else + { + layer.gameObject.layer = GetActiveLayerMask(); + } + } + + private void SetLayerActiveOnBothScenes(Layer layer) + { + layer.gameObject.layer = LayerMask.NameToLayer("RenderBoth"); + } + + public void ControlMotionOfSprite(int layer, MtnCtrlElement[] motions, int style) + { + Layer layer2 = GetLayer(layer); + layer2.ControlLayerMotion(motions); + } + + public void MoveSprite(int layer, int x, int y, int z, int angle, int easetype, float alpha, float wait, bool isblocking) + { + Layer layer2 = GetLayer(layer); + layer2.MoveLayer(x, y, z, alpha, easetype, wait, isblocking, adjustAlpha: true); + layer2.SetAngle((float)angle, wait); + } + + public void MoveSpriteEx(int layer, string filename, Vector3[] points, float alpha, float time, bool isblocking) + { + Layer i = GetLayer(layer); + if (filename != string.Empty) + { + i.CrossfadeLayer(filename, time, isblocking); + } + gameSystem.RegisterAction(delegate + { + i.MoveLayerEx(points, points.Length, 1f - alpha, time); + if (isblocking) + { + gameSystem.AddWait(new Wait(time, WaitTypes.WaitForMove, i.FinishAll)); + } + }); + } + + public void DrawBustshot(int layer, string textureName, int x, int y, int z, int oldx, int oldy, int oldz, bool move, int priority, int type, float wait, bool isblocking) + { + Layer i = GetLayer(layer); + while (i.FadingOut) + { + i.HideLayer(); + i = GetLayer(layer); + } + if (!move) + { + oldx = x; + oldy = y; + oldz = z; + } + i.DrawLayer(textureName, oldx, oldy, oldz, null, 1f, /*isBustshot:*/ true, type, wait, isblocking); + i.SetPriority(priority); + if (move) + { + i.MoveLayer(x, y, z, 1f, 0, wait, isblocking, adjustAlpha: false); + } + iTween.Stop(i.gameObject); + gameSystem.RegisterAction(delegate + { + if (i.UsingCrossShader() && i.gameObject.layer != GetActiveLayerMask()) + { + SetLayerActiveOnBothScenes(i); + } + else + { + UpdateLayerMask(i, priority); + } + }); + } + + public void FadeBustshotWithFiltering(int layer, string mask, int style, float wait, bool isblocking) + { + Layer layer2 = GetLayer(layer); + while (layer2.FadingOut) + { + layer2.HideLayer(); + layer2 = GetLayer(layer); + } + layer2.FadeLayerWithMask(mask, style, wait, isblocking); + gameSystem.RegisterAction(delegate + { + }); + } + + public void DrawBustshotWithFiltering(int layer, string textureName, string mask, int x, int y, int z, int originx, int originy, int oldx, int oldy, int oldz, bool move, int priority, int type, float wait, bool isblocking) + { + Layer i = GetLayer(layer); + while (i.FadingOut) + { + i.HideLayer(); + i = GetLayer(layer); + } + if (!move) + { + oldx = x; + oldy = y; + oldz = z; + } + Vector2? origin = null; + if (originx != 0 || originy != 0) + { + origin = new Vector2((float)originx, (float)originy); + } + i.DrawLayerWithMask(textureName, mask, oldx, oldy, origin, /*isBustshot:*/ true, type, wait, isblocking); + i.SetPriority(priority); + if (move) + { + i.MoveLayer(x, y, z, 1f, 0, wait, isblocking, adjustAlpha: false); + } + iTween.Stop(i.gameObject); + gameSystem.RegisterAction(delegate + { + if (i.UsingCrossShader() && i.gameObject.layer != GetActiveLayerMask()) + { + SetLayerActiveOnBothScenes(i); + } + else + { + UpdateLayerMask(i, priority); + } + }); + } + + public void MoveBustshot(int layer, string textureName, int x, int y, int z, float wait, bool isblocking) + { + Layer layer2 = GetLayer(layer); + Vector3 localPosition = layer2.transform.localPosition; + int x2 = (int)localPosition.x; + Vector3 localPosition2 = layer2.transform.localPosition; + int y2 = (int)localPosition2.y; + Vector3 localPosition3 = layer2.transform.localPosition; + int z2 = (int)localPosition3.z; + if (Mathf.Approximately(wait, 0f)) + { + x2 = x; + y2 = y; + z2 = z; + } + if (textureName != string.Empty) + { + layer2.DrawLayer(textureName, x2, y2, z2, null, 1f, /*isBustshot:*/ true, 0, wait, isBlocking: false); + } + layer2.MoveLayer(x, y, z, 1f, 0, wait, isblocking, adjustAlpha: true); + } + + public void SetLayerToDepthMasked(int layer) + { + Layer layer2 = GetLayer(layer); + layer2.SwitchToMaskedShader(); + } + + public void FadeSpriteWithFiltering(int layer, string mask, int style, float wait, bool isblocking) + { + Layer layer2 = GetLayer(layer); + layer2.FadeLayerWithMask(mask, style, wait, isblocking); + } + + public void DrawSpriteWithFiltering(int layer, string texture, string mask, int x, int y, int style, int priority, float wait, bool isBlocking) + { + Layer layer2 = GetLayer(layer); + UpdateLayerMask(layer2, priority); + layer2.DrawLayerWithMask(texture, mask, x, y, null, /*isBustshot:*/ false, style, wait, isBlocking); + layer2.SetPriority(priority); + } + + public void FadeSprite(int layer, float wait, bool isblocking) + { + Layer ifInUse = GetIfInUse(layer); + if (ifInUse != null) + { + ifInUse.FadeOutLayer(wait, isblocking); + } + } + + public void DrawSprite(int layer, string texture, string mask, int x, int y, int z, int originx, int originy, int angle, int style, float alpha, int priority, float wait, bool isblocking) + { + Layer layer2 = GetLayer(layer); + UpdateLayerMask(layer2, priority); + Vector2? origin = null; + if (originx != 0 || originy != 0) + { + origin = new Vector2((float)originx, (float)originy); + } + layer2.DrawLayer(texture, x, y, z, origin, 1f - alpha, /*isBustshot:*/ false, 0, wait, isblocking); + layer2.SetAngle((float)angle, 0f); + layer2.SetPriority(priority); + if (style == 1) + { + layer2.SwitchToAlphaShader(); + } + } + + public void DrawBG(string texture, float wait, bool isblocking) + { + Scene scene = GetActiveScene(); + scene.BackgroundLayer.DrawLayer(texture, 0, 0, 0, null, 0f, /*isBustshot:*/ false, 0, wait, isblocking); + } + + public void SetFaceToUpperLayer(bool isUpper) + { + faceToUpperLayer = isUpper; + faceLayer.gameObject.layer = ((!faceToUpperLayer) ? GetActiveLayerMask() : LayerMask.NameToLayer("Scene3")); + } + + public void FadeFace(float wait, bool isblocking) + { + faceLayer.FadeOutLayer(wait, isblocking); + faceName = string.Empty; + } + + public void DrawFace(string texture, float wait, bool isblocking) + { + faceName = texture; + if (Mathf.Approximately(wait, 0f)) + { + isblocking = false; + } + faceLayer.DrawLayer(texture, 0, 0, 0, null, 1f, /*isBustshot:*/ false, 0, wait, isblocking); + faceLayer.gameObject.layer = GetActiveLayerMask(); + if (faceToUpperLayer) + { + faceLayer.gameObject.layer = LayerMask.NameToLayer("Scene3"); + } + faceLayer.SetPriority(63); + } + + public void HideFace(float time) + { + if (!(faceName == string.Empty)) + { + faceLayer.FadeOutLayer(time, isBlocking: false); + } + } + + public void RevealFace(float time) + { + if (!(faceName == string.Empty)) + { + DrawFace(faceName, time, isblocking: false); + } + } + + public void DrawSceneWithMask(string backgroundfilename, string maskname, float time) + { + SwapActiveScenes(); + Scene s = GetActiveScene(); + s.UpdateRange(0f); + s.BackgroundLayer.ReleaseTextures(); + s.BackgroundLayer.DrawLayer(backgroundfilename, 0, 0, 0, null, 0f, /*isBustshot:*/ false, 0, 0f, /*isBlocking:*/ false); + s.SetTransitionMask(maskname); + faceLayer.HideLayer(); + gameSystem.RegisterAction(delegate + { + s.StartTransition(time); + s.BackgroundLayer.SetRange(1f); + gameSystem.AddWait(new Wait(time, WaitTypes.WaitForScene, s.StopFadeIn)); + }); + } + + public void DrawScene(string backgroundfilename, float time) + { + SwapActiveScenes(); + Scene s = GetActiveScene(); + s.GetComponent().enabled = false; + s.UpdateRange(0f); + s.BackgroundLayer.ReleaseTextures(); + s.BackgroundLayer.DrawLayer(backgroundfilename, 0, 0, 0, null, 0f, /*isBustshot:*/ false, 0, 0f, /*isBlocking:*/ false); + faceLayer.HideLayer(); + gameSystem.RegisterAction(delegate + { + s.GetComponent().enabled = true; + s.FadeSceneIn(time); + s.BackgroundLayer.SetRange(1f); + gameSystem.AddWait(new Wait(time, WaitTypes.WaitForScene, s.StopFadeIn)); + }); + } + + public void FinalizeViewportChange() + { + iTween.Stop(Panel); + Panel.transform.localPosition = targetPosition; + Panel.transform.localScale = targetScale; + } + + public void ResetViewportSize() + { + iTween.Stop(Panel); + Panel.transform.localPosition = (targetPosition = defaultOffset); + Panel.transform.localScale = (targetScale = new Vector3(1f, 1f, 1f)); + } + + public void EnlargeScene(float x, float y, float sx, float sy, float time, bool isblocking) + { + targetPosition = new Vector3(x, 0f - y, 0f) + defaultOffset; + targetScale = new Vector3(800f / sx, 600f / sy, 1f); + gameSystem.RegisterAction(delegate + { + iTween.ScaleTo(Panel, iTween.Hash("scale", targetScale, "time", time, "islocal", true, "easetype", iTween.EaseType.linear)); + iTween.MoveTo(Panel, iTween.Hash("position", targetPosition, "time", time, "islocal", true, "easetype", iTween.EaseType.linear)); + if (isblocking) + { + GameSystem.Instance.AddWait(new Wait(time, WaitTypes.WaitForMove, FinalizeViewportChange)); + } + }); + if (isblocking) + { + gameSystem.ExecuteActions(); + } + } + + public void ShakeBustshot(int layer, float speed, int level, int attenuation, int vector, int loopcount, bool isblocking) + { + Layer layer2 = GetLayer(layer); + Shaker.ShakeObject(layer2.gameObject, speed, level, attenuation, vector, loopcount, isblocking); + } + + public void StopBustshotShake(int layer) + { + Shaker component = GetLayer(layer).GetComponent(); + if (component != null) + { + component.StopShake(); + } + } + + public void ShakeScene(float speed, int level, int attenuation, int vector, int loopcount, bool isblocking) + { + Shaker.ShakeObject(SceneCameras, speed, level, attenuation, vector, loopcount, isblocking); + } + + public void StopSceneShake() + { + Shaker component = SceneCameras.GetComponent(); + if (component != null) + { + component.StopShake(); + } + SceneCameras.transform.localPosition = Vector3.zero; + } + + public void HideBackgroundSceneObject() + { + if (activeScene == 0) + { + scene2.gameObject.SetActive(value: false); + } + else + { + scene1.gameObject.SetActive(value: true); + } + } + + public Vector3 GetPositionOfLayer(int layer) + { + return layers[layer].targetPosition; + } + + public void HideFilmEffector(float time, bool isBlocking) + { + useFilm = false; + useBlur = false; + useHorizontalBlur = false; + if (!(effector == null)) + { + FilmEffector targeteffector = effector; + if (Mathf.Approximately(time, 0f)) + { + targeteffector.RemoveEffector(); + } + else + { + gameSystem.RegisterAction(delegate + { + targeteffector.FadeOut(time, isBlocking); + }); + } + effector = null; + } + } + + public void CreateFilmEffector(int effecttype, Color targetColor, int targetpower, int style, float length, bool isBlocking) + { + useFilm = true; + filmPower = targetpower; + filmColor = targetColor; + filmType = effecttype; + filmStyle = style; + gameSystem.RegisterAction(delegate + { + EffectCamera.GetComponent().enabled = true; + if (effector == null) + { + effector = EffectCamera.AddComponent(); + } + effector.Prepare(effecttype, targetColor, targetpower, style, length, isBlocking); + }); + } + + public void CreateHorizontalGradation(int targetpower, float length, bool isBlocking) + { + useHorizontalBlur = true; + filmPower = targetpower; + if (effector != null) + { + HideFilmEffector(length, isBlocking: false); + effector = null; + } + gameSystem.RegisterAction(delegate + { + EffectCamera.GetComponent().enabled = true; + effector = EffectCamera.AddComponent(); + effector.Prepare(10, Color.white, targetpower, 0, length, isBlocking); + }); + } + + public void CreateBlur(int targetpower, float length, bool isBlocking) + { + useBlur = true; + filmPower = targetpower; + if (effector != null) + { + HideFilmEffector(length, isBlocking: false); + effector = null; + } + gameSystem.RegisterAction(delegate + { + EffectCamera.GetComponent().enabled = true; + effector = EffectCamera.AddComponent(); + effector.Prepare(12, Color.white, targetpower, 0, length, isBlocking); + }); + } + + public void SerializeScene(MemoryStream ms) + { + BinaryWriter binaryWriter = new BinaryWriter(ms); + binaryWriter.Write(faceToUpperLayer); + binaryWriter.Write(useFilm); + binaryWriter.Write(useBlur); + binaryWriter.Write(useHorizontalBlur); + binaryWriter.Write(filmPower); + binaryWriter.Write(filmType); + binaryWriter.Write(filmStyle); + MGHelper.WriteColor(binaryWriter, filmColor); + if (activeScene == 0) + { + scene1.BackgroundLayer.Serialize(binaryWriter); + } + else + { + scene2.BackgroundLayer.Serialize(binaryWriter); + } + if (faceLayer.IsInUse) + { + binaryWriter.Write(value: true); + faceLayer.Serialize(binaryWriter); + } + else + { + binaryWriter.Write(value: false); + } + for (int i = 0; i < 64; i++) + { + if (layers[i] == null) + { + binaryWriter.Write(value: false); + } + else if (layers[i].FadingOut || !layers[i].IsInUse) + { + binaryWriter.Write(value: false); + } + else + { + binaryWriter.Write(value: true); + layers[i].Serialize(binaryWriter); + } + } + } + + public void DeSerializeScene(MemoryStream ms) + { + BinaryReader binaryReader = new BinaryReader(ms); + HideFilmEffector(0f, isBlocking: false); + DrawScene("black", 0f); + gameSystem.ExecuteActions(); + faceToUpperLayer = binaryReader.ReadBoolean(); + useFilm = binaryReader.ReadBoolean(); + useBlur = binaryReader.ReadBoolean(); + useHorizontalBlur = binaryReader.ReadBoolean(); + filmPower = binaryReader.ReadInt32(); + filmType = binaryReader.ReadInt32(); + filmStyle = binaryReader.ReadInt32(); + filmColor = MGHelper.ReadColor(binaryReader); + MGHelper.ReadVector3(binaryReader); + MGHelper.ReadVector3(binaryReader); + string backgroundfilename = binaryReader.ReadString(); + binaryReader.ReadSingle(); + binaryReader.ReadInt32(); + binaryReader.ReadInt32(); + DrawScene(backgroundfilename, 0.3f); + if (binaryReader.ReadBoolean()) + { + MGHelper.ReadVector3(binaryReader); + MGHelper.ReadVector3(binaryReader); + string texture = binaryReader.ReadString(); + binaryReader.ReadSingle(); + binaryReader.ReadInt32(); + binaryReader.ReadInt32(); + DrawFace(texture, 0f, isblocking: false); + } + for (int i = 0; i < 64; i++) + { + if (layers[i] != null && layers[i].IsInUse) + { + layers[i].HideLayer(); + } + if (binaryReader.ReadBoolean()) + { + Vector3 position = MGHelper.ReadVector3(binaryReader); + Vector3 scale = MGHelper.ReadVector3(binaryReader); + string textureName = binaryReader.ReadString(); + float alpha = binaryReader.ReadSingle(); + int num = binaryReader.ReadInt32(); + int type = binaryReader.ReadInt32(); + if (i != 50) + { + bool isBustshot = num != 0; + Layer layer = GetLayer(i); + UpdateLayerMask(layer, i); + layer.DrawLayer(textureName, (int)position.x, (int)position.y, 0, null, alpha, isBustshot, type, 0f, isBlocking: false); + layer.SetPriority(i); + layer.RestoreScaleAndPosition(scale, position); + } + } + } + if (useFilm) + { + CreateFilmEffector(filmType, filmColor, filmPower, filmStyle, 0f, isBlocking: false); + } + if (useHorizontalBlur) + { + CreateHorizontalGradation(filmPower, 0f, isBlocking: false); + } + SetFaceToUpperLayer(faceToUpperLayer); + gameSystem.ExecuteActions(); + } + + private IEnumerator GetScreenshotCoroutine(Action OnFinishAction) + { + yield return (object)new WaitForEndOfFrame(); + RenderTexture rt = new RenderTexture(800, 600, 24); + ScreenshotCamera.cullingMask = ((1 << GetActiveLayerMask()) | (1 << LayerMask.NameToLayer("Scene3"))); + ScreenshotCamera.targetTexture = rt; + ScreenshotCamera.Render(); + RenderTexture.active = rt; + Texture2D tex = new Texture2D(rt.width, rt.height); + tex.ReadPixels(new Rect(0f, 0f, (float)rt.width, (float)rt.height), 0, 0, recalculateMipMaps: true); + tex.Apply(); + OnFinishAction(tex); + } + + private IEnumerator WriteScreenshotToFile(string path) + { + yield return (object)new WaitForEndOfFrame(); + RenderTexture rt = new RenderTexture(800, 600, 24); + ScreenshotCamera.cullingMask = ((1 << GetActiveLayerMask()) | (1 << LayerMask.NameToLayer("Scene3"))); + ScreenshotCamera.targetTexture = rt; + ScreenshotCamera.Render(); + RenderTexture.active = rt; + Texture2D tex = new Texture2D(rt.width, rt.height); + tex.ReadPixels(new Rect(0f, 0f, (float)rt.width, (float)rt.height), 0, 0, recalculateMipMaps: true); + tex.Apply(); + byte[] texout = tex.EncodeToPNG(); + ScreenshotCamera.targetTexture = null; + UnityEngine.Object.Destroy(rt); + File.WriteAllBytes(path, texout); + } + + public void WriteScreenshot(string path) + { + StartCoroutine(WriteScreenshotToFile(path)); + } + + public void GetScreenshot(Action onFinishAction) + { + StartCoroutine(GetScreenshotCoroutine(onFinishAction)); + } + + public void ReloadAllImages() + { + Layer[] componentsInChildren = Panel.GetComponentsInChildren(); + foreach (Layer layer in componentsInChildren) + { + layer.ReloadTexture(); + } + } + + private Scene GetActiveScene() + { + if (activeScene == 0) + { + return scene1; + } + return scene2; + } + + private void SwapActiveScenes() + { + if (activeScene == 0) + { + activeScene = 1; + scene1.Depth = 0f; + scene2.Depth = 1f; + } + else + { + activeScene = 0; + scene1.Depth = 1f; + scene2.Depth = 0f; + } + } + + private void Start() + { + scene1 = Scene1.GetComponent(); + scene2 = Scene2.GetComponent(); + scene1.Depth = 1f; + scene2.Depth = 0f; + scene2.gameObject.SetActive(value: false); + gameSystem = GameSystem.Instance; + activeScene = 0; + scene1.BackgroundLayer.transform.localPosition = defaultOffset; + scene2.BackgroundLayer.transform.localPosition = defaultOffset; + Panel.transform.localPosition = defaultOffset; + FacePanel.transform.localPosition = defaultOffset; + faceLayer = LayerPool.ActivateLayer(); + faceLayer.transform.parent = FacePanel.transform; + faceLayer.gameObject.name = "Face Layer"; + faceLayer.gameObject.layer = LayerMask.NameToLayer("Face"); + faceLayer.IsStatic = true; + faceLayer.gameObject.SetActive(value: false); + gameSystem.CheckinSystem(); + } + + private void Update() + { + if (Screen.width != lastWidth) + { + Vector2 screenSize = NGUITools.screenSize; + float num = screenSize.x / screenSize.y; + float num2 = GameSystem.Instance.AspectRatio * 480f; + float num3 = 480f; + float num4 = num2 / num3; + float num5 = (!(num4 > num)) ? num3 : ((float)Mathf.RoundToInt(num2 / num)); + float num6 = 2f / num5; + base.gameObject.transform.localScale = new Vector3(num6, num6, num6); + lastWidth = Screen.width; + } + } + } +} diff --git a/Assets.Scripts.Core.Scene/SceneControllerOld.cs b/Assets.Scripts.Core.Scene/SceneControllerOld.cs new file mode 100644 index 00000000..7435a6f0 --- /dev/null +++ b/Assets.Scripts.Core.Scene/SceneControllerOld.cs @@ -0,0 +1,94 @@ +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class SceneControllerOld : MonoBehaviour + { + private const int NumCharLayers = 32; + + private SceneOld[] scenes = new SceneOld[2]; + + private GameSystem gameSystem; + + private GameObject effectCamera; + + private int foregroundScene; + + private int backgroundScene = 1; + + public SceneControllerOld() + { + gameSystem = GameSystem.Instance; + for (int i = 0; i < 2; i++) + { + GameObject gameObject = Object.Instantiate(gameSystem.ScenePrefab); + scenes[i] = gameObject.GetComponent(); + scenes[i].Initialize(i, 32); + } + scenes[0].ResetLayer(); + scenes[1].HideScene(); + effectCamera = GameObject.FindGameObjectWithTag("EffectCamera"); + } + + private void SwapScenes() + { + if (foregroundScene == 0) + { + foregroundScene = 1; + backgroundScene = 0; + } + else + { + foregroundScene = 0; + backgroundScene = 1; + } + } + + public void HideFilmEffector(float time, bool isBlocking) + { + FilmEffector component = effectCamera.GetComponent(); + component.FadeOut(time, isBlocking); + } + + public void CreateFilmEffector(int effecttype, Color targetColor, int targetpower, int style, float length, bool isBlocking) + { + effectCamera.GetComponent().enabled = true; + FilmEffector filmEffector = effectCamera.AddComponent(); + filmEffector.Prepare(effecttype, targetColor, targetpower, style, length, isBlocking); + } + + public SceneOld GetForegroundScene() + { + return scenes[foregroundScene]; + } + + public LayerOld GetLayer(int layNum) + { + return scenes[foregroundScene].GetLayer(layNum); + } + + private void UpdateDepth() + { + scenes[foregroundScene].ChangeSceneDepth(1); + scenes[backgroundScene].ChangeSceneDepth(0); + } + + public void SetNewSceneFade(string textureName, int time) + { + scenes[foregroundScene].FadeScene((float)time); + scenes[backgroundScene].SetLayerTextureImmediate(0, textureName); + scenes[backgroundScene].ShowScene(); + UpdateDepth(); + SwapScenes(); + } + + public void SetNewSceneFadeWithMask(string textureName, string maskname, int time) + { + scenes[foregroundScene].FadeSceneWithMask(maskname, (float)time); + scenes[backgroundScene].SetLayerTextureImmediate(0, textureName); + scenes[backgroundScene].ShowScene(); + UpdateDepth(); + SwapScenes(); + } + } +} diff --git a/Assets.Scripts.Core.Scene/SceneOld.cs b/Assets.Scripts.Core.Scene/SceneOld.cs new file mode 100644 index 00000000..ea122eee --- /dev/null +++ b/Assets.Scripts.Core.Scene/SceneOld.cs @@ -0,0 +1,235 @@ +using Assets.Scripts.Core.AssetManagement; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class SceneOld : MonoBehaviour + { + private const float Fuzziness = 0.32f; + + private Camera sceneCamera; + + private UICamera uiCamera; + + private int layerNum; + + public GameObject PanelGameObject; + + public GameObject LayerPrefab; + + public Material SceneMaterial; + + public Shader SceneShader; + + public Shader SceneFadeShader; + + public Shader SceneTransitionShader; + + public int SceneNum; + + public int LayerCount; + + public string SceneName; + + private Vector3 targetPosition; + + private Vector3 targetScale; + + private Vector3 defaultOffset = Vector3.zero; + + private List layerList = new List(); + + public void ResetLayer() + { + ResetViewportSize(); + SceneMaterial.shader = SceneShader; + SceneMaterial.SetFloat("_Range", 0f); + sceneCamera.enabled = true; + } + + public LayerOld GetLayer(int layer) + { + return layerList[layer]; + } + + public void SetLayerTextureImmediate(int layer, string textureName) + { + layerList[layer].SetTextureImmediate(textureName, LayerAlignment.AlignCenter); + } + + public void StopShake() + { + iTween.Stop(PanelGameObject); + PanelGameObject.transform.localPosition = new Vector3(0f, 0f, 0f); + } + + public void FinalizeViewportChange() + { + iTween.Stop(PanelGameObject); + PanelGameObject.transform.localPosition = targetPosition; + PanelGameObject.transform.localScale = targetScale; + } + + public void ResetViewportSize() + { + iTween.Stop(PanelGameObject); + PanelGameObject.transform.localPosition = (targetPosition = defaultOffset); + PanelGameObject.transform.localScale = (targetScale = new Vector3(1f, 1f, 1f)); + } + + public void EnlargeScene(float x, float y, float sx, float sy, float time, bool isblocking) + { + targetPosition = new Vector3(x, 0f - y, 0f) + defaultOffset; + targetScale = new Vector3(800f / sx, 600f / sy, 1f); + iTween.ScaleTo(PanelGameObject, iTween.Hash("scale", targetScale, "time", time, "islocal", true, "easetype", iTween.EaseType.linear)); + iTween.MoveTo(PanelGameObject, iTween.Hash("position", targetPosition, "time", time, "islocal", true, "easetype", iTween.EaseType.linear)); + if (isblocking) + { + GameSystem.Instance.AddWait(new Wait(time, WaitTypes.WaitForMove, FinalizeViewportChange)); + } + } + + public void ShakeScene(int speed, int level, int attenuation, int vector, int loopcount, bool isblocking) + { + StopShake(); + float num = (float)(speed * loopcount); + if (loopcount == 0) + { + num = 2.14748365E+09f; + } + Hashtable hashtable = iTween.Hash("time", num, "islocal", true); + switch (vector) + { + case 0: + hashtable.Add("x", level); + break; + case 2: + hashtable.Add("y", level); + break; + default: + Debug.LogWarning("Unhandled vector type for SHakeScreen! Type: " + vector); + hashtable.Add("amount", level); + break; + } + if (attenuation > 0) + { + Debug.LogWarning("attenuation set on ShakeScreen, but no handler set!"); + } + iTween.ShakePosition(PanelGameObject, hashtable); + if (isblocking && loopcount != 0) + { + GameSystem.Instance.AddWait(new Wait(num, WaitTypes.WaitForMove, StopShake)); + } + } + + public void FadeScene(float time) + { + SceneMaterial.shader = SceneFadeShader; + SceneMaterial.SetFloat("_Range", 0f); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0, "to", 1, "time", time / 1000f, "onupdate", "UpdateFadeProgress", "oncomplete", "HideScene")); + GameSystem.Instance.AddWait(new Wait(time / 1000f, WaitTypes.WaitForScene, HideScene)); + } + + public void FadeSceneWithMask(string mask, float time) + { + Texture2D texture2D = AssetManager.Instance.LoadTexture(mask); + if (texture2D == null) + { + Logger.LogWarning("Failed to load mask '" + mask + "' for scene transition! Falling back to fade."); + FadeScene(time); + } + else + { + SceneMaterial.shader = SceneTransitionShader; + SceneMaterial.SetTexture("_Mask", texture2D); + SceneMaterial.SetFloat("_Range", 0f); + SceneMaterial.SetFloat("_Fuzzyness", 0.32f); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0, "to", 1, "time", time / 1000f, "onupdate", "UpdateFadeProgress", "oncomplete", "HideScene")); + GameSystem.Instance.AddWait(new Wait(time / 1000f, WaitTypes.WaitForScene, HideScene)); + } + } + + public void ChangeSceneDepth(int depth) + { + sceneCamera.depth = (float)depth; + } + + public void UpdateFadeProgress(float progress) + { + SceneMaterial.SetFloat("_Range", progress); + } + + public void ShowScene() + { + ResetLayer(); + } + + public void HideScene() + { + iTween.Stop(base.gameObject); + sceneCamera.enabled = false; + foreach (LayerOld layer in layerList) + { + layer.HideLayer(); + } + } + + public void Initialize(int scenenum, int layercount) + { + sceneCamera = base.gameObject.GetComponent(); + uiCamera = base.gameObject.GetComponent(); + SceneNum = scenenum; + SceneName = "Scene" + (scenenum + 1); + base.gameObject.name = SceneName; + layerNum = LayerMask.NameToLayer(SceneName); + base.gameObject.layer = layerNum; + PanelGameObject.layer = layerNum; + int num = 1 << layerNum; + sceneCamera.cullingMask = num; + uiCamera.eventReceiverMask = num; + sceneCamera.depth = (float)scenenum; + LayerCount = layercount; + for (int i = 0; i <= LayerCount; i++) + { + GameObject gameObject = Object.Instantiate(LayerPrefab); + gameObject.transform.parent = PanelGameObject.transform; + gameObject.name = "Layer " + i; + gameObject.transform.localPosition = new Vector3(0f, 0f, (float)i * 0.1f); + gameObject.layer = base.gameObject.layer; + LayerOld component = gameObject.GetComponent(); + component.LayerNum = i; + layerList.Add(component); + } + if (SceneMaterial == null) + { + PrepareMaterial(); + } + if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer) + { + defaultOffset = new Vector3(-0.5f, -0.5f, 0f); + PanelGameObject.transform.localPosition = defaultOffset; + } + } + + private void PrepareMaterial() + { + SceneMaterial = new Material(SceneShader); + } + + private void Start() + { + PrepareMaterial(); + } + + private void OnRenderImage(RenderTexture source, RenderTexture dest) + { + if (SceneMaterial == null) + { + PrepareMaterial(); + } + Graphics.Blit(source, dest, SceneMaterial); + } + } +} diff --git a/Assets.Scripts.Core.Scene/Shaker.cs b/Assets.Scripts.Core.Scene/Shaker.cs new file mode 100644 index 00000000..6e8639cf --- /dev/null +++ b/Assets.Scripts.Core.Scene/Shaker.cs @@ -0,0 +1,172 @@ +using UnityEngine; + +namespace Assets.Scripts.Core.Scene +{ + public class Shaker : MonoBehaviour + { + private Vector3 srcPos = Vector3.zero; + + private Vector3 lastPos; + + private Vector3 destination; + + private bool isActive = true; + + private float intensity; + + private int shaketype; + + private int attenuation; + + private int remainingcount; + + private float timeperswing; + + private float timetoswitch; + + private bool shakedir; + + private bool infinite; + + public static void ShakeObject(GameObject target, float speed, int level, int attenuation, int vector, int loopcount, bool isblocking) + { + Shaker component = target.GetComponent(); + if (component != null) + { + component.StopShake(); + } + GameSystem.Instance.RegisterAction(delegate + { + Shaker shaker = target.AddComponent(); + shaker.StartShake(speed, level, attenuation, vector, loopcount, isblocking); + }); + if (isblocking) + { + GameSystem.Instance.ExecuteActions(); + } + } + + public void StartShake(float speed, int level, int atten, int vector, int loopcount, bool isblocking) + { + isActive = true; + infinite = false; + srcPos = base.gameObject.transform.localPosition; + lastPos = srcPos; + intensity = (float)level; + attenuation = atten; + shaketype = vector; + shakedir = false; + remainingcount = loopcount; + timeperswing = speed; + if (timeperswing < 0.01f) + { + timeperswing = 0.01f; + } + float num = timeperswing * (float)loopcount; + num += (float)loopcount * 0.005f; + if (loopcount == 0) + { + num = 2.14748365E+09f; + infinite = true; + } + UpdateShake(); + if (isblocking && loopcount != 0) + { + GameSystem.Instance.AddWait(new Wait(num, WaitTypes.WaitForMove, StopShake)); + } + if (isblocking) + { + GameSystem.Instance.ExecuteActions(); + } + } + + private void UpdateShake() + { + SetShakeTarget(); + } + + private void SetShakeTarget() + { + int num = 1; + if (shakedir) + { + num = -1; + } + float num2 = intensity; + lastPos = destination; + switch (shaketype) + { + case 0: + destination = srcPos + new Vector3(intensity * (float)num, 0f, 0f); + break; + case 1: + destination = srcPos + new Vector3(intensity * (float)num, intensity * (float)(-num), 0f); + break; + case 2: + destination = srcPos + new Vector3(0f, intensity * (float)num, 0f); + break; + case 3: + destination = srcPos + new Vector3(intensity * (float)(-num), intensity * (float)num, 0f); + break; + case 4: + destination = srcPos + new Vector3(Random.Range(0f - num2, num2), Random.Range(0f - num2, num2), 0f); + break; + default: + Debug.LogError("Error: Undefined shake type " + shaketype); + break; + } + shakedir = !shakedir; + intensity *= 1f - (float)attenuation / 100f; + } + + public void StopShake() + { + isActive = false; + } + + private void Update() + { + if (isActive) + { + timetoswitch -= Time.deltaTime; + float num = 1f - timetoswitch / timeperswing; + float num2 = (float)Sine.EaseInOut((double)num, (double)lastPos.x, (double)(destination.x - lastPos.x), 1.0); + float num3 = (float)Sine.EaseInOut((double)num, (double)lastPos.y, (double)(destination.y - lastPos.y), 1.0); + Transform transform = base.transform; + float x = num2; + float y = num3; + Vector3 localPosition = base.transform.localPosition; + transform.localPosition = new Vector3(x, y, localPosition.z); + if (!(timetoswitch > 0f)) + { + base.transform.localPosition = destination; + if (remainingcount > 0 || infinite) + { + timetoswitch = timeperswing; + UpdateShake(); + remainingcount--; + } + else + { + isActive = false; + base.transform.localPosition = srcPos; + } + } + } + } + + private void LateUpdate() + { + if (!isActive) + { + Object.Destroy(this); + } + } + + private void OnDestroy() + { + isActive = false; + base.transform.localPosition = srcPos; + } + } +} diff --git a/Assets.Scripts.Core.State/IGameState.cs b/Assets.Scripts.Core.State/IGameState.cs new file mode 100644 index 00000000..0f4d84e3 --- /dev/null +++ b/Assets.Scripts.Core.State/IGameState.cs @@ -0,0 +1,17 @@ +namespace Assets.Scripts.Core.State +{ + public interface IGameState + { + void RequestLeaveImmediate(); + + void RequestLeave(); + + void OnLeaveState(); + + void OnRestoreState(); + + bool InputHandler(); + + GameState GetStateType(); + } +} diff --git a/Assets.Scripts.Core.State/StateChapterJump.cs b/Assets.Scripts.Core.State/StateChapterJump.cs new file mode 100644 index 00000000..a1f0ade3 --- /dev/null +++ b/Assets.Scripts.Core.State/StateChapterJump.cs @@ -0,0 +1,66 @@ +using Assets.Scripts.UI.ChapterJump; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateChapterJump : IGameState + { + private GameSystem gameSystem; + + private ChapterJumpManager jumpScreen; + + private bool isLeaving; + + public StateChapterJump() + { + gameSystem = GameSystem.Instance; + GameObject gameObject = Object.Instantiate(gameSystem.ChapterJumpPrefab); + jumpScreen = gameObject.GetComponent(); + jumpScreen.Show(); + } + + public void RequestLeaveImmediate() + { + Object.Destroy(jumpScreen.gameObject); + gameSystem.PopStateStack(); + isLeaving = true; + } + + public void RequestLeave() + { + if (!isLeaving) + { + jumpScreen.Hide(delegate + { + gameSystem.PopStateStack(); + }); + isLeaving = true; + } + } + + public void OnLeaveState() + { + Debug.Log("OnLeave StateExtraScreen " + isLeaving); + if (!isLeaving) + { + jumpScreen.Hide(delegate + { + }); + } + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + return false; + } + + public GameState GetStateType() + { + return GameState.ChapterJumpScreen; + } + } +} diff --git a/Assets.Scripts.Core.State/StateChapterPreview.cs b/Assets.Scripts.Core.State/StateChapterPreview.cs new file mode 100644 index 00000000..880b909e --- /dev/null +++ b/Assets.Scripts.Core.State/StateChapterPreview.cs @@ -0,0 +1,66 @@ +using Assets.Scripts.UI.ChapterPreview; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateChapterPreview : IGameState + { + private GameSystem gameSystem; + + private ChapterPreviewManager previewScreen; + + private bool isLeaving; + + public StateChapterPreview() + { + gameSystem = GameSystem.Instance; + GameObject gameObject = Object.Instantiate(gameSystem.ChapterPreviewPrefab); + previewScreen = gameObject.GetComponent(); + previewScreen.Show(); + } + + public void RequestLeaveImmediate() + { + Object.Destroy(previewScreen.gameObject); + gameSystem.PopStateStack(); + isLeaving = true; + } + + public void RequestLeave() + { + if (!isLeaving) + { + previewScreen.Hide(delegate + { + gameSystem.PopStateStack(); + }); + isLeaving = true; + } + } + + public void OnLeaveState() + { + Debug.Log("OnLeave StateChapterPreview " + isLeaving); + if (!isLeaving) + { + previewScreen.Hide(delegate + { + }); + } + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + return false; + } + + public GameState GetStateType() + { + return GameState.ChapterPreview; + } + } +} diff --git a/Assets.Scripts.Core.State/StateChapterScreen.cs b/Assets.Scripts.Core.State/StateChapterScreen.cs new file mode 100644 index 00000000..e9d365d1 --- /dev/null +++ b/Assets.Scripts.Core.State/StateChapterScreen.cs @@ -0,0 +1,66 @@ +using Assets.Scripts.UI.ChapterScreen; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateChapterScreen : IGameState + { + private GameSystem gameSystem; + + private ChapterScreen chapterScreen; + + private bool isLeaving; + + public StateChapterScreen() + { + gameSystem = GameSystem.Instance; + GameObject gameObject = Object.Instantiate(gameSystem.ChapterScreenPrefab); + chapterScreen = gameObject.GetComponent(); + chapterScreen.Show(); + } + + public void RequestLeaveImmediate() + { + Object.Destroy(chapterScreen.gameObject); + gameSystem.PopStateStack(); + isLeaving = true; + } + + public void RequestLeave() + { + if (!isLeaving) + { + chapterScreen.Hide(delegate + { + gameSystem.PopStateStack(); + }); + isLeaving = true; + } + } + + public void OnLeaveState() + { + Debug.Log("OnLeave StateChapterScreen " + isLeaving); + if (!isLeaving) + { + chapterScreen.Hide(delegate + { + }); + } + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + return false; + } + + public GameState GetStateType() + { + return GameState.ChapterScreen; + } + } +} diff --git a/Assets.Scripts.Core.State/StateDialogPrompt.cs b/Assets.Scripts.Core.State/StateDialogPrompt.cs new file mode 100644 index 00000000..7971543c --- /dev/null +++ b/Assets.Scripts.Core.State/StateDialogPrompt.cs @@ -0,0 +1,87 @@ +using Assets.Scripts.UI.Prompt; +using System; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateDialogPrompt : IGameState + { + private GameSystem gameSystem; + + private PromptController promptController; + + private bool isActive = true; + + public StateDialogPrompt(PromptType type, DialogCallback onYes, DialogCallback onNo) + { + gameSystem = GameSystem.Instance; + if (!gameSystem.UsePrompts && type != 0) + { + Debug.Log("Immediately completing dialog, dialogs disabled in config."); + gameSystem.RegisterAction(delegate + { + if (onYes != null) + { + onYes(); + } + gameSystem.PopStateStack(); + }); + gameSystem.ExecuteActions(); + } + else + { + GameObject gameObject = UnityEngine.Object.Instantiate(gameSystem.PromptPrefab); + promptController = gameObject.GetComponent(); + if (promptController == null) + { + throw new Exception("Failed to instantiate promptController!"); + } + promptController.Open(type, onYes, onNo); + } + } + + public PromptController GetPromptController() + { + return promptController; + } + + public void RequestLeaveImmediate() + { + } + + public void RequestLeave() + { + } + + public void OnLeaveState() + { + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + if (!isActive) + { + return false; + } + if (Input.GetMouseButtonDown(1)) + { + promptController.Hide(affirmative: false); + } + return false; + } + + public GameState GetStateType() + { + return GameState.DialogPrompt; + } + + public void DisableInputActions() + { + isActive = false; + } + } +} diff --git a/Assets.Scripts.Core.State/StateExtraScreen.cs b/Assets.Scripts.Core.State/StateExtraScreen.cs new file mode 100644 index 00000000..8d0b428a --- /dev/null +++ b/Assets.Scripts.Core.State/StateExtraScreen.cs @@ -0,0 +1,69 @@ +using Assets.Scripts.UI.Extra; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateExtraScreen : IGameState + { + private GameSystem gameSystem; + + private ExtraManager extraScreen; + + private bool isLeaving; + + public StateExtraScreen() + { + gameSystem = GameSystem.Instance; + GameObject gameObject = Object.Instantiate(gameSystem.ExtraScreenPrefab); + extraScreen = gameObject.GetComponent(); + GameSystem.Instance.IsForceSkip = false; + GameSystem.Instance.IsSkipping = false; + GameSystem.Instance.IsAuto = false; + extraScreen.Show(); + } + + public void RequestLeaveImmediate() + { + Object.Destroy(extraScreen.gameObject); + gameSystem.PopStateStack(); + isLeaving = true; + } + + public void RequestLeave() + { + if (!isLeaving) + { + extraScreen.Hide(delegate + { + gameSystem.PopStateStack(); + }); + isLeaving = true; + } + } + + public void OnLeaveState() + { + Debug.Log("OnLeave StateExtraScreen " + isLeaving); + if (!isLeaving) + { + extraScreen.Hide(delegate + { + }); + } + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + return false; + } + + public GameState GetStateType() + { + return GameState.ExtraScreen; + } + } +} diff --git a/Assets.Scripts.Core.State/StateHistory.cs b/Assets.Scripts.Core.State/StateHistory.cs new file mode 100644 index 00000000..f186838a --- /dev/null +++ b/Assets.Scripts.Core.State/StateHistory.cs @@ -0,0 +1,85 @@ +using Assets.Scripts.Core.History; +using System; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateHistory : IGameState + { + private GameSystem gameSystem; + + private HistoryWindow historyWindow; + + public StateHistory() + { + gameSystem = GameSystem.Instance; + GameObject gameObject = UnityEngine.Object.Instantiate(gameSystem.HistoryPrefab); + historyWindow = gameObject.GetComponent(); + if (historyWindow == null) + { + throw new Exception("Failed to instantiate historyWindow!"); + } + gameSystem.MainUIController.FadeOut(0.2f, isBlocking: false); + gameSystem.SceneController.HideFace(0.2f); + gameSystem.ExecuteActions(); + } + + public void RequestLeaveImmediate() + { + } + + public void RequestLeave() + { + historyWindow.Leave(delegate + { + gameSystem.PopStateStack(); + gameSystem.UpdateWaits(); + gameSystem.MessageBoxVisible = true; + gameSystem.MainUIController.ShowMessageBox(); + gameSystem.ExecuteActions(); + }); + } + + public void OnLeaveState() + { + if (historyWindow != null) + { + UnityEngine.Object.Destroy(historyWindow); + } + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter)) + { + RequestLeave(); + } + if (Input.GetKeyDown(KeyCode.PageUp)) + { + historyWindow.Step(5f); + } + if (Input.GetKeyDown(KeyCode.PageDown)) + { + historyWindow.Step(-5f); + } + if (Input.GetKeyDown(KeyCode.UpArrow)) + { + historyWindow.Step(1f); + } + if (Input.GetKeyDown(KeyCode.DownArrow)) + { + historyWindow.Step(-1f); + } + return false; + } + + public GameState GetStateType() + { + return GameState.History; + } + } +} diff --git a/Assets.Scripts.Core.State/StateNormal.cs b/Assets.Scripts.Core.State/StateNormal.cs new file mode 100644 index 00000000..9eefb1f2 --- /dev/null +++ b/Assets.Scripts.Core.State/StateNormal.cs @@ -0,0 +1,196 @@ +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Buriko; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateNormal : IGameState + { + private GameSystem gameSystem; + + public StateNormal() + { + gameSystem = GameSystem.Instance; + } + + public void RequestLeaveImmediate() + { + } + + public void RequestLeave() + { + } + + public void OnLeaveState() + { + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) + { + if (!gameSystem.CanSkip) + { + return true; + } + gameSystem.IsSkipping = true; + gameSystem.IsForceSkip = true; + if (gameSystem.WaitList.Count > 0) + { + return true; + } + return true; + } + if (gameSystem.IsForceSkip) + { + gameSystem.IsSkipping = false; + gameSystem.IsForceSkip = false; + } + if (Input.GetKeyDown(KeyCode.Space)) + { + if (!gameSystem.MessageBoxVisible && gameSystem.GameState == GameState.Normal) + { + return false; + } + gameSystem.IsSkipping = false; + gameSystem.IsForceSkip = false; + gameSystem.IsAuto = false; + gameSystem.SwitchToViewMode(); + return false; + } + if (Input.GetAxis("Mouse ScrollWheel") > 0f || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.PageUp)) + { + if (!gameSystem.MessageBoxVisible && gameSystem.GameState == GameState.Normal) + { + return false; + } + gameSystem.SwitchToHistoryScreen(); + return false; + } + if (Input.GetMouseButtonDown(0) || Input.GetAxis("Mouse ScrollWheel") < 0f || Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.PageDown) || Input.GetKeyDown(KeyCode.KeypadEnter)) + { + if (gameSystem.IsSkipping) + { + gameSystem.IsSkipping = false; + } + if (gameSystem.IsAuto && !gameSystem.ClickDuringAuto) + { + gameSystem.IsAuto = false; + if (gameSystem.WaitList.Exists((Wait a) => a.Type == WaitTypes.WaitForAuto)) + { + gameSystem.AddWait(new Wait(0f, WaitTypes.WaitForInput, null)); + } + return false; + } + if (UICamera.hoveredObject == gameSystem.SceneController.SceneCameras || UICamera.hoveredObject == null) + { + gameSystem.ClearWait(); + } + return false; + } + if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) + { + if (!gameSystem.MessageBoxVisible && gameSystem.GameState == GameState.Normal) + { + return false; + } + if (gameSystem.IsAuto && gameSystem.ClickDuringAuto) + { + gameSystem.IsAuto = false; + if (gameSystem.WaitList.Exists((Wait a) => a.Type == WaitTypes.WaitForAuto)) + { + gameSystem.AddWait(new Wait(0f, WaitTypes.WaitForInput, null)); + } + return false; + } + gameSystem.IsSkipping = false; + gameSystem.IsForceSkip = false; + if (gameSystem.RightClickMenu) + { + gameSystem.SwitchToRightClickMenu(); + } + else + { + gameSystem.SwitchToHiddenWindow2(); + } + return false; + } + if (Input.GetKeyDown(KeyCode.A)) + { + gameSystem.IsAuto = !gameSystem.IsAuto; + if (gameSystem.IsAuto) + { + return true; + } + if (gameSystem.WaitList.Exists((Wait a) => a.Type == WaitTypes.WaitForAuto)) + { + gameSystem.AddWait(new Wait(0f, WaitTypes.WaitForInput, null)); + } + } + if (Input.GetKeyDown(KeyCode.S)) + { + gameSystem.IsSkipping = !gameSystem.IsSkipping; + } + if (Input.GetKeyDown(KeyCode.F)) + { + if (Screen.fullScreen) + { + int num = PlayerPrefs.GetInt("width"); + int num2 = PlayerPrefs.GetInt("height"); + if (num == 0 || num2 == 0) + { + num = 640; + num2 = 480; + } + Screen.SetResolution(num, num2, fullscreen: false); + } + else + { + GameSystem.Instance.GoFullscreen(); + } + } + if (Input.GetKeyDown(KeyCode.L)) + { + if (!gameSystem.MessageBoxVisible || gameSystem.IsAuto || gameSystem.IsSkipping || gameSystem.IsForceSkip) + { + return false; + } + if (!gameSystem.HasWaitOfType(WaitTypes.WaitForText)) + { + GameSystem.Instance.UseEnglishText = !GameSystem.Instance.UseEnglishText; + int val = 0; + if (gameSystem.UseEnglishText) + { + val = 1; + } + gameSystem.TextController.SwapLanguages(); + BurikoMemory.Instance.SetGlobalFlag("GLanguage", val); + } + } + if (Input.GetKeyDown(KeyCode.P)) + { + if (!gameSystem.MessageBoxVisible || gameSystem.IsAuto || gameSystem.IsSkipping || gameSystem.IsForceSkip) + { + return false; + } + if (!gameSystem.HasWaitOfType(WaitTypes.WaitForInput)) + { + return false; + } + AssetManager.Instance.UseNewArt = !AssetManager.Instance.UseNewArt; + BurikoMemory.Instance.SetGlobalFlag("GArtStyle", AssetManager.Instance.UseNewArt ? 1 : 0); + GameSystem.Instance.SceneController.ReloadAllImages(); + } + return true; + } + + public GameState GetStateType() + { + return GameState.Normal; + } + } +} diff --git a/Assets.Scripts.Core.State/StateSaveLoad.cs b/Assets.Scripts.Core.State/StateSaveLoad.cs new file mode 100644 index 00000000..e300d4d7 --- /dev/null +++ b/Assets.Scripts.Core.State/StateSaveLoad.cs @@ -0,0 +1,81 @@ +using Assets.Scripts.UI.SaveLoad; +using System; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateSaveLoad : IGameState + { + private GameSystem gameSystem; + + private SaveLoadManager saveLoadManager; + + private bool isActive = true; + + public StateSaveLoad(bool restoreUI) + { + gameSystem = GameSystem.Instance; + GameObject gameObject = UnityEngine.Object.Instantiate(gameSystem.SaveLoadPrefab); + saveLoadManager = gameObject.GetComponent(); + if (saveLoadManager == null) + { + throw new Exception("Failed to instantiate configManager!"); + } + saveLoadManager.Open(restoreUI); + gameSystem.ExecuteActions(); + } + + public void Leave(Action onLeave) + { + saveLoadManager.Leave(delegate + { + gameSystem.PopStateStack(); + gameSystem.ExecuteActions(); + if (onLeave != null) + { + onLeave(); + } + }); + } + + public void RequestLeaveImmediate() + { + } + + public void RequestLeave() + { + } + + public void OnLeaveState() + { + } + + public void OnRestoreState() + { + gameSystem.RegisterAction(delegate + { + saveLoadManager.RefreshList(); + }); + gameSystem.ExecuteActions(); + } + + public bool InputHandler() + { + if (!isActive) + { + return false; + } + if (Input.GetMouseButtonDown(1)) + { + Leave(null); + isActive = false; + } + return false; + } + + public GameState GetStateType() + { + return GameState.SaveLoadScreen; + } + } +} diff --git a/Assets.Scripts.Core.State/StateTitle.cs b/Assets.Scripts.Core.State/StateTitle.cs new file mode 100644 index 00000000..2143d4ce --- /dev/null +++ b/Assets.Scripts.Core.State/StateTitle.cs @@ -0,0 +1,58 @@ +using Assets.Scripts.UI.TitleScreen; +using System; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateTitle : IGameState + { + private GameSystem gameSystem; + + private TitleScreen titleScreen; + + public StateTitle() + { + gameSystem = GameSystem.Instance; + GameObject gameObject = UnityEngine.Object.Instantiate(gameSystem.TitlePrefab); + titleScreen = gameObject.GetComponent(); + gameSystem.IsSkipping = false; + gameSystem.IsForceSkip = false; + gameSystem.IsAuto = false; + gameSystem.TextHistory.ClearHistory(); + if (titleScreen == null) + { + throw new Exception("Failed to instantiate titleScreen!"); + } + titleScreen.Enter(); + } + + public void RequestLeave() + { + titleScreen.Leave(gameSystem.PopStateStack); + } + + public void RequestLeaveImmediate() + { + UnityEngine.Object.Destroy(titleScreen.gameObject); + gameSystem.PopStateStack(); + } + + public void OnLeaveState() + { + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + return false; + } + + public GameState GetStateType() + { + return GameState.TitleScreen; + } + } +} diff --git a/Assets.Scripts.Core.State/StateViewTips.cs b/Assets.Scripts.Core.State/StateViewTips.cs new file mode 100644 index 00000000..00e31063 --- /dev/null +++ b/Assets.Scripts.Core.State/StateViewTips.cs @@ -0,0 +1,87 @@ +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.UI.Tips; +using UnityEngine; + +namespace Assets.Scripts.Core.State +{ + internal class StateViewTips : IGameState + { + private GameSystem gameSystem; + + private TipsManager tipsManager; + + private int mode; + + public StateViewTips(int tipsMode) + { + mode = tipsMode; + gameSystem = GameSystem.Instance; + GameObject gameObject = Object.Instantiate(gameSystem.TipsPrefab); + tipsManager = gameObject.GetComponent(); + GameSystem.Instance.IsForceSkip = false; + GameSystem.Instance.IsSkipping = false; + GameSystem.Instance.IsAuto = false; + tipsManager.Show(tipsMode); + } + + public void OpenTips(string script) + { + BurikoScriptSystem.Instance.CallScript(script); + gameSystem.AudioController.FadeOutBGM(0, 500, waitForFade: false); + gameSystem.TextController.ClearText(); + gameSystem.CanSave = false; + tipsManager.Hide(delegate + { + gameSystem.PopStateStack(); + }); + } + + public void RequestLeave() + { + tipsManager.Hide(delegate + { + gameSystem.PopStateStack(); + }); + gameSystem.AudioController.FadeOutBGM(0, 500, waitForFade: false); + switch (mode) + { + case 0: + case 1: + BurikoMemory.Instance.SetFlag("TipsMode", 2); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 1); + break; + case 2: + BurikoMemory.Instance.SetFlag("TipsMode", 1); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 1); + break; + } + } + + public void RequestLeaveImmediate() + { + Object.Destroy(tipsManager.gameObject); + } + + public void OnLeaveState() + { + if (tipsManager != null) + { + Object.Destroy(tipsManager.gameObject); + } + } + + public void OnRestoreState() + { + } + + public bool InputHandler() + { + return false; + } + + public GameState GetStateType() + { + return GameState.TipsScreen; + } + } +} diff --git a/Assets.Scripts.Core.SteamWorks/Achievement.cs b/Assets.Scripts.Core.SteamWorks/Achievement.cs new file mode 100644 index 00000000..4c54f9d3 --- /dev/null +++ b/Assets.Scripts.Core.SteamWorks/Achievement.cs @@ -0,0 +1,20 @@ +namespace Assets.Scripts.Core.SteamWorks +{ + public enum Achievement + { + HIGURASHI_STORY_EP01_01, + HIGURASHI_STORY_EP01_02, + HIGURASHI_STORY_EP01_03, + HIGURASHI_STORY_EP01_04, + HIGURASHI_STORY_EP01_05, + HIGURASHI_STORY_EP01_06, + HIGURASHI_STORY_EP01_07, + HIGURASHI_STORY_EP01_08, + HIGURASHI_STORY_EP01_09, + HIGURASHI_STORY_EP01_10, + HIGURASHI_STORY_EP01_11, + HIGURASHI_STORY_EP01_ENDING, + HIGURASHI_STORY_EP01_OMAKE, + HIGURASHI_STORY_EP01_TIPS + } +} diff --git a/Assets.Scripts.Core.SteamWorks/Achievement_t.cs b/Assets.Scripts.Core.SteamWorks/Achievement_t.cs new file mode 100644 index 00000000..a7a36047 --- /dev/null +++ b/Assets.Scripts.Core.SteamWorks/Achievement_t.cs @@ -0,0 +1,21 @@ +namespace Assets.Scripts.Core.SteamWorks +{ + public class Achievement_t + { + public Achievement m_eAchievementID; + + public string m_strName; + + public string m_strDescription; + + public bool m_bAchieved; + + public Achievement_t(Achievement achievementID, string name, string desc) + { + m_eAchievementID = achievementID; + m_strName = name; + m_strDescription = desc; + m_bAchieved = false; + } + } +} diff --git a/Assets.Scripts.Core.SteamWorks/Achievements.cs b/Assets.Scripts.Core.SteamWorks/Achievements.cs new file mode 100644 index 00000000..e2af896f --- /dev/null +++ b/Assets.Scripts.Core.SteamWorks/Achievements.cs @@ -0,0 +1,23 @@ +namespace Assets.Scripts.Core.SteamWorks +{ + public static class Achievements + { + public static Achievement_t[] achievements = new Achievement_t[14] + { + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_01, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_02, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_03, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_04, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_05, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_06, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_07, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_08, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_09, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_10, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_11, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_ENDING, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_OMAKE, string.Empty, string.Empty), + new Achievement_t(Achievement.HIGURASHI_STORY_EP01_TIPS, string.Empty, string.Empty) + }; + } +} diff --git a/Assets.Scripts.Core.SteamWorks/SteamController.cs b/Assets.Scripts.Core.SteamWorks/SteamController.cs new file mode 100644 index 00000000..631f1279 --- /dev/null +++ b/Assets.Scripts.Core.SteamWorks/SteamController.cs @@ -0,0 +1,101 @@ +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.UI.Tips; +using Steamworks; +using System.Linq; +using UnityEngine; + +namespace Assets.Scripts.Core.SteamWorks +{ + public class SteamController : MonoBehaviour + { + private SteamManager steamManager; + + private Callback userStatsReceived; + + private CGameID gameID; + + private bool requestedStats; + + private bool hasStats; + + private bool needPushStats; + + public void Close() + { + if (!(steamManager == null)) + { + SteamAPI.Shutdown(); + } + } + + public void CheckTipsAchievements() + { + if (!(steamManager == null)) + { + foreach (TipsDataEntry tip in TipsData.Tips) + { + if (!BurikoMemory.Instance.HasReadScript(tip.Script + ".mg")) + { + return; + } + } + AddAchievement("HIGURASHI_STORY_EP01_TIPS"); + } + } + + public void AddAchievement(string id) + { + if (!(steamManager == null) && SteamManager.Initialized && hasStats) + { + Achievement_t achievement_t = Achievements.achievements.SingleOrDefault((Achievement_t a) => a.m_eAchievementID.ToString() == id); + if (achievement_t == null) + { + Debug.LogWarning("Achievement id " + id + " does not exist!"); + } + else if (!achievement_t.m_bAchieved) + { + achievement_t.m_bAchieved = true; + SteamUserStats.SetAchievement(id); + needPushStats = true; + } + } + } + + private void OnUserStatsReceived(UserStatsReceived_t pCallback) + { + if (!(steamManager == null) && SteamManager.Initialized) + { + Debug.Log("Steamworks UserStats Received"); + if ((ulong)gameID == pCallback.m_nGameID) + { + if (pCallback.m_eResult == EResult.k_EResultOK) + { + hasStats = true; + Achievement_t[] achievements = Achievements.achievements; + foreach (Achievement_t achievement_t in achievements) + { + if (SteamUserStats.GetAchievement(achievement_t.m_eAchievementID.ToString(), out achievement_t.m_bAchieved)) + { + achievement_t.m_strName = SteamUserStats.GetAchievementDisplayAttribute(achievement_t.m_eAchievementID.ToString(), "name"); + achievement_t.m_strDescription = SteamUserStats.GetAchievementDisplayAttribute(achievement_t.m_eAchievementID.ToString(), "desc"); + Debug.Log(achievement_t.m_strName + " : " + achievement_t.m_bAchieved); + } + else + { + Debug.LogWarning("SteamUserStats.GetAchievement failed for Achievement " + achievement_t.m_eAchievementID + "\nIs it registered in the Steam Partner site?"); + } + } + } + else + { + Debug.LogWarning("Steamworks UserStats failed to retrieve: " + pCallback.m_eResult); + } + } + else + { + Debug.Log("Received stats for incorrect gameID: " + pCallback.m_nGameID); + } + } + } + } +} diff --git a/Assets.Scripts.Core.SteamWorks/SteamManager.cs b/Assets.Scripts.Core.SteamWorks/SteamManager.cs new file mode 100644 index 00000000..ad58d07e --- /dev/null +++ b/Assets.Scripts.Core.SteamWorks/SteamManager.cs @@ -0,0 +1,101 @@ +using Steamworks; +using System; +using System.Text; +using UnityEngine; + +namespace Assets.Scripts.Core.SteamWorks +{ + internal class SteamManager : MonoBehaviour + { + private static SteamManager s_instance; + + private bool m_bInitialized; + + private SteamAPIWarningMessageHook_t m_SteamAPIWarningMessageHook; + + private static SteamManager Instance => s_instance ?? new GameObject("SteamManager").AddComponent(); + + public static bool Initialized => Instance.m_bInitialized; + + private static void SteamAPIDebugTextHook(int nSeverity, StringBuilder pchDebugText) + { + Debug.LogWarning(pchDebugText); + } + + private void Awake() + { + if (s_instance != null) + { + UnityEngine.Object.Destroy(base.gameObject); + } + else + { + s_instance = this; + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + if (!Packsize.Test()) + { + Debug.LogError("[Steamworks.NET] Packsize Test returned false, the wrong version of Steamworks.NET is being run in this platform.", this); + } + if (!DllCheck.Test()) + { + Debug.LogError("[Steamworks.NET] DllCheck Test returned false, One or more of the Steamworks binaries seems to be the wrong version.", this); + } + try + { + if (SteamAPI.RestartAppIfNecessary(new AppId_t(310360u))) + { + GameSystem.Instance.CanExit = true; + Application.Quit(); + return; + } + } + catch (DllNotFoundException arg) + { + Debug.LogError("[Steamworks.NET] Could not load [lib]steam_api.dll/so/dylib. It's likely not in the correct location. Refer to the README for more details.\n" + arg, this); + GameSystem.Instance.CanExit = true; + Application.Quit(); + return; + IL_00ac:; + } + m_bInitialized = SteamAPI.Init(); + if (!m_bInitialized) + { + Debug.LogError("[Steamworks.NET] SteamAPI_Init() failed. Refer to Valve's documentation or the comment above this line for more information.", this); + } + } + } + + private void OnEnable() + { + if (s_instance == null) + { + s_instance = this; + } + if (m_bInitialized && m_SteamAPIWarningMessageHook == null) + { + m_SteamAPIWarningMessageHook = SteamAPIDebugTextHook; + SteamClient.SetWarningMessageHook(m_SteamAPIWarningMessageHook); + } + } + + private void OnDestroy() + { + if (!(s_instance != this)) + { + s_instance = null; + if (m_bInitialized) + { + SteamAPI.Shutdown(); + } + } + } + + private void Update() + { + if (m_bInitialized) + { + SteamAPI.RunCallbacks(); + } + } + } +} diff --git a/Assets.Scripts.Core.TextWindow/FaceController.cs b/Assets.Scripts.Core.TextWindow/FaceController.cs new file mode 100644 index 00000000..fb1be936 --- /dev/null +++ b/Assets.Scripts.Core.TextWindow/FaceController.cs @@ -0,0 +1,59 @@ +using Assets.Scripts.Core.AssetManagement; +using UnityEngine; + +namespace Assets.Scripts.Core.TextWindow +{ + [RequireComponent(typeof(UITexture))] + public class FaceController : MonoBehaviour + { + private UITexture uiTexture; + + public void UpdateFaceAlpha(float a) + { + uiTexture.alpha = a; + } + + public void ShowFace() + { + iTween.Stop(base.gameObject); + uiTexture.alpha = 1f; + } + + public void HideFace() + { + uiTexture.alpha = 0f; + uiTexture.mainTexture = null; + uiTexture.enabled = false; + } + + public void FadeFace(float time, bool isBlocking) + { + iTween.ValueTo(base.gameObject, iTween.Hash("from", uiTexture.alpha, "to", 0, "time", time / 1000f, "onupdate", "UpdateFaceAlpha", "oncomplete", "HideFace")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(time / 1000f, WaitTypes.WaitForMove, HideFace)); + } + } + + public void SetFaceTexture(string texName, float time, bool isBlocking) + { + uiTexture.enabled = true; + uiTexture.alpha = 0f; + uiTexture.mainTexture = AssetManager.Instance.LoadTexture(texName); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0f, "to", 1f, "time", time / 1000f, "onupdate", "UpdateFaceAlpha", "oncomplete", "ShowFace")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(time / 1000f, WaitTypes.WaitForMove, ShowFace)); + } + } + + private void Start() + { + uiTexture = GetComponent(); + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.Core.TextWindow/TextCharacter.cs b/Assets.Scripts.Core.TextWindow/TextCharacter.cs new file mode 100644 index 00000000..ffecae54 --- /dev/null +++ b/Assets.Scripts.Core.TextWindow/TextCharacter.cs @@ -0,0 +1,55 @@ +using System.Globalization; +using UnityEngine; + +namespace Assets.Scripts.Core.TextWindow +{ + public class TextCharacter + { + private readonly char ch; + + public float StartTime; + + public float FinishTime; + + private float time; + + public TextCharacter(char character, float start, float end) + { + ch = character; + StartTime = start; + FinishTime = end; + time = 0f; + } + + public char GetCharacter() + { + return ch; + } + + public string GetCharacter(float delta) + { + time += delta; + if (StartTime > time) + { + return "<#FFFFFF00>" + ch; + } + if (ch == ' ') + { + return ch.ToString(CultureInfo.InvariantCulture); + } + if (FinishTime < time) + { + return ch.ToString(CultureInfo.InvariantCulture); + } + float t = (time - StartTime) / (FinishTime - StartTime); + int num = (int)Mathf.Lerp(0f, 255f, t); + return "<#FFFFFF" + num.ToString("X2") + ">" + ch; + } + + public void Finish() + { + StartTime = 0f; + FinishTime = 0f; + } + } +} diff --git a/Assets.Scripts.Core.TextWindow/TextController.cs b/Assets.Scripts.Core.TextWindow/TextController.cs new file mode 100644 index 00000000..38fb0da8 --- /dev/null +++ b/Assets.Scripts.Core.TextWindow/TextController.cs @@ -0,0 +1,531 @@ +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using System.Collections.Generic; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.Core.TextWindow +{ + public class TextController + { + public readonly TextMeshPro TextArea; + + private GameSystem gameSystem; + + private bool appendNext; + + private bool prevAppendState; + + private bool isFading; + + private float textTimeRemaining; + + public int TextSpeed = 50; + + public int AutoSpeed = 50; + + public int AutoPageSpeed = 50; + + public int OverrideTextSpeed = -1; + + private float timePerChar = 0.025f; + + private float timeForFade = 0.15f; + + private float timePerLine = 1f; + + private string txt = string.Empty; + + private string englishtext = string.Empty; + + private string japanesetext = string.Empty; + + private string englishprev = string.Empty; + + private string japaneseprev = string.Empty; + + public string NameFormat = string.Empty; + + private BurikoTextModes lastMode; + + private List charList = new List(); + + public TextController() + { + gameSystem = GameSystem.Instance; + TextArea = GameObject.FindGameObjectWithTag("TextArea").GetComponent(); + } + + public bool IsTyping() + { + return isFading; + } + + public void SetTextFade(bool value) + { + if (value) + { + timeForFade = 0.15f; + } + else + { + timeForFade = 0f; + } + } + + public void SwapLanguages() + { + if (GameSystem.Instance.UseEnglishText) + { + japanesetext = txt; + txt = englishtext; + } + else + { + englishtext = txt; + txt = japanesetext; + } + string text = japanesetext; + string text2 = englishtext; + bool flag = appendNext; + TypeTextImmediately(txt); + FinishTyping(); + UpdateTextArea(); + appendNext = flag; + japanesetext = text; + englishtext = text2; + } + + public Vector3 GetCarretPosition() + { + if (TextArea.text == string.Empty) + { + return Vector3.zero; + } + TMP_LineInfo tMP_LineInfo = TextArea.textInfo.lineInfo[TextArea.textInfo.lineCount - 1]; + int num = Mathf.RoundToInt(20f + TextArea.textInfo.lineInfo[TextArea.textInfo.lineCount - 1].lineExtents.max.x); + Vector3 localPosition = TextArea.gameObject.transform.localPosition; + float y = localPosition.y + TextArea.textInfo.characterInfo[tMP_LineInfo.lastCharacterIndex].baseLine + 12f; + return new Vector3((float)num, y, 0f); + } + + public bool GetPrevAppendState() + { + return prevAppendState; + } + + public bool GetAppendState() + { + return appendNext; + } + + public void SetAppendState(bool append) + { + appendNext = append; + prevAppendState = append; + } + + public void TypeTextImmediately(string text) + { + ClearText(); + txt = text; + if (GameSystem.Instance.UseEnglishText) + { + englishprev = text; + } + else + { + japaneseprev = text; + } + string text2 = txt; + foreach (char character in text2) + { + charList.Add(new TextCharacter(character, 0f, 0f)); + } + } + + public void SetPrevText(string text, int language) + { + if (language == 1) + { + englishprev = text; + } + else + { + japaneseprev = text; + } + } + + public string GetPrevText(int language) + { + if (language == 1) + { + return englishprev; + } + return japaneseprev; + } + + public void SetFullText(string text, int language) + { + if (language == 1) + { + if (GameSystem.Instance.UseEnglishText) + { + txt = text; + } + englishtext = text; + } + else + { + if (!GameSystem.Instance.UseEnglishText) + { + txt = text; + } + japanesetext = text; + } + } + + public string GetFullText(int language) + { + if (language == 1) + { + return englishtext; + } + return japanesetext; + } + + public void FinishedTyping() + { + textTimeRemaining = 0f; + } + + public void FinishTyping() + { + textTimeRemaining = 0f; + } + + public void AddWaitToFinishTyping() + { + if (isFading) + { + gameSystem.AddWait(new Wait(textTimeRemaining, WaitTypes.WaitForText, FinishedTyping)); + } + } + + public void ClearText() + { + TextArea.text = string.Empty; + appendNext = false; + charList.Clear(); + isFading = false; + englishprev = englishtext; + japaneseprev = japanesetext; + englishtext = string.Empty; + japanesetext = string.Empty; + txt = string.Empty; + AudioController.Instance.ClearVoiceQueue(); + } + + public void UpdateTextArea() + { + string text = string.Empty; + if (textTimeRemaining <= 0f) + { + if (isFading) + { + foreach (TextCharacter @char in charList) + { + @char.Finish(); + } + } + isFading = false; + } + foreach (TextCharacter char2 in charList) + { + text = ((!isFading) ? (text + char2.GetCharacter()) : (text + char2.GetCharacter(Time.deltaTime))); + } + if (textTimeRemaining > 0f) + { + textTimeRemaining -= Time.deltaTime; + } + TextArea.text = text; + } + + public void SetTextPoint(int x, int y) + { + string text = string.Empty; + int num = 0; + if (!appendNext) + { + ClearText(); + } + else + { + num = TextArea.textInfo.lineCount; + } + for (int i = num; i < y; i++) + { + text += "\n"; + } + for (int j = num; j < x; j++) + { + text += "\u3000"; + } + englishtext += text; + japanesetext += text; + txt += text; + string text2 = text; + foreach (char character in text2) + { + charList.Add(new TextCharacter(character, 0f, 0f)); + } + appendNext = true; + FinishTyping(); + } + + private void AddText(string str, int displayimmediate, bool isFade, bool addToTime) + { + float num = (float)(100 - TextSpeed) / 100f * 2f; + if (gameSystem.IsAuto) + { + num = (float)(100 - AutoSpeed) / 100f * 2f; + } + if (OverrideTextSpeed != -1) + { + num = (float)(100 - OverrideTextSpeed) / 100f * 2f; + } + int num2 = 1; + if (!GameSystem.Instance.UseEnglishText) + { + num2 = 2; + } + bool flag = false; + bool flag2 = false; + foreach (char c in str) + { + if (c == '<') + { + flag = true; + } + if (c == '\\') + { + flag2 = true; + } + if (!isFade || flag || flag2) + { + charList.Add(new TextCharacter(c, 0f, 0f)); + if (c == '>') + { + flag = false; + } + if (c != '\\') + { + flag2 = false; + } + } + else if (displayimmediate > 0) + { + charList.Add(new TextCharacter(c, 0f, 0f)); + displayimmediate--; + } + else + { + charList.Add(new TextCharacter(c, textTimeRemaining, textTimeRemaining + timeForFade)); + if (addToTime) + { + textTimeRemaining += timePerChar * num * (float)num2; + } + } + } + } + + private void CreateText(string name, string text, BurikoTextModes textMode) + { + isFading = !gameSystem.IsSkipping; + string text2 = string.Format(NameFormat, name); + if (appendNext) + { + int length = txt.Length; + txt += text; + string text3 = txt; + string str = text3.Substring(length); + AddText(str, 0, isFading, addToTime: true); + txt = text3; + } + else + { + charList.Clear(); + int length2 = text2.Length; + AddText(text, length2, isFading, addToTime: true); + txt = text; + } + if (isFading) + { + switch (textMode) + { + case BurikoTextModes.Normal: + case BurikoTextModes.WaitForInput: + case BurikoTextModes.ContinueAftertyping: + case BurikoTextModes.WaitThenContinue: + gameSystem.AddWait(new Wait(textTimeRemaining, WaitTypes.WaitForText, FinishedTyping)); + break; + } + } + else + { + UpdateTextArea(); + } + bool flag = false; + switch (textMode) + { + case BurikoTextModes.Normal: + gameSystem.AddWait(new Wait(0f, WaitTypes.WaitForInput, ClearText)); + flag = true; + break; + case BurikoTextModes.WaitForInput: + gameSystem.AddWait(new Wait(0f, WaitTypes.WaitForInput, null)); + flag = true; + break; + } + lastMode = textMode; + if (gameSystem.IsAuto && flag) + { + SetAutoTextWait(); + } + } + + public void SetAutoTextWait() + { + if (gameSystem.IsAuto) + { + float num = (float)(100 - AutoPageSpeed) / 100f * 2f; + float num2 = textTimeRemaining + timePerLine * num; + if (lastMode != BurikoTextModes.Continue && lastMode != BurikoTextModes.ContinueAftertyping) + { + num2 += (float)charList.Count * 0.01f * num; + } + gameSystem.AddWait(new Wait(num2, WaitTypes.WaitForAuto, delegate + { + gameSystem.ClearInputWaits(); + })); + } + } + + public void SetText(string name, string text, BurikoTextModes textMode, int language) + { + if (!appendNext) + { + text = string.Format(NameFormat, name) + text; + } + if (language == 1 && GameSystem.Instance.UseEnglishText) + { + japaneseprev = japanesetext; + if (appendNext) + { + japanesetext += text; + } + else + { + japanesetext = text; + } + } + else if (language == 2 && !GameSystem.Instance.UseEnglishText) + { + if (englishprev.EndsWith(",") || englishprev.EndsWith(".") || englishprev.EndsWith("!") || englishprev.EndsWith("?")) + { + text += " "; + } + if (englishprev.Length > 0 && englishprev[englishprev.Length - 1] > 'a' && englishprev[englishprev.Length - 1] < 'Z') + { + text += " "; + } + englishprev = englishtext; + if (prevAppendState) + { + englishtext += text; + } + else + { + englishtext = text; + } + } + else + { + if (textTimeRemaining < 0f) + { + textTimeRemaining = 0f; + isFading = false; + } + if (GameSystem.Instance.UseEnglishText) + { + englishprev = txt; + englishtext += text; + } + else + { + japaneseprev = txt; + japanesetext += text; + } + prevAppendState = appendNext; + if (language == 0) + { + if (!GameSystem.Instance.UseEnglishText) + { + englishprev = englishtext; + } + else + { + japaneseprev = japanesetext; + } + if (appendNext) + { + englishtext += text; + japanesetext += text; + } + else + { + englishtext = text; + japanesetext = text; + } + } + if (!gameSystem.MessageBoxVisible) + { + if (gameSystem.IsSkipping) + { + gameSystem.MainUIController.ShowMessageBox(); + CreateText(name, text, textMode); + appendNext = (textMode != BurikoTextModes.Normal); + gameSystem.ExecuteActions(); + } + else + { + gameSystem.MainUIController.FadeIn(0.2f); + gameSystem.AddWait(new Wait(0.2f, WaitTypes.WaitForMove, delegate + { + CreateText(name, text, textMode); + appendNext = (textMode != BurikoTextModes.Normal); + })); + } + } + else + { + CreateText(name, text, textMode); + appendNext = (textMode != BurikoTextModes.Normal); + } + gameSystem.ExecuteActions(); + } + } + + public void Update() + { + if (isFading) + { + UpdateTextArea(); + } + if (gameSystem.IsAuto && lastMode == BurikoTextModes.Continue) + { + gameSystem.ClearVoiceWaits(); + } + } + } +} diff --git a/Assets.Scripts.Core/GameState.cs b/Assets.Scripts.Core/GameState.cs new file mode 100644 index 00000000..ae39913d --- /dev/null +++ b/Assets.Scripts.Core/GameState.cs @@ -0,0 +1,24 @@ +namespace Assets.Scripts.Core +{ + public enum GameState + { + None, + Normal, + RightClickMenu, + HiddenMessageWindow, + OptionsPanel, + ChoiceScreen, + History, + TitleScreen, + DialogPrompt, + ConfigScreen, + SaveLoadScreen, + CGGallery, + GalleryView, + ExtraScreen, + TipsScreen, + ChapterScreen, + ChapterJumpScreen, + ChapterPreview + } +} diff --git a/Assets.Scripts.Core/GameSystem.cs b/Assets.Scripts.Core/GameSystem.cs new file mode 100644 index 00000000..be64d9e3 --- /dev/null +++ b/Assets.Scripts.Core/GameSystem.cs @@ -0,0 +1,894 @@ +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.History; +using Assets.Scripts.Core.Interfaces; +using Assets.Scripts.Core.Scene; +using Assets.Scripts.Core.State; +using Assets.Scripts.Core.SteamWorks; +using Assets.Scripts.Core.TextWindow; +using Assets.Scripts.UI; +using Assets.Scripts.UI.CGGallery; +using Assets.Scripts.UI.Choice; +using Assets.Scripts.UI.Config; +using Assets.Scripts.UI.Prompt; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace Assets.Scripts.Core +{ + public class GameSystem : MonoBehaviour + { + private const float maxProcTime = 0.01f; + + private static GameSystem _instance; + + public AssetManager AssetManager; + + public AudioController AudioController; + + public SceneController SceneController; + + public MainUIController MainUIController; + + public TextController TextController; + + public TextHistory TextHistory; + + public KeyHook KeyHook; + + public GameObject UIControl; + + public SteamController SteamController; + + public LoggingLevel ConsoleLoggingLevel = LoggingLevel.All; + + public LoggingLevel FileLoggingLevel = LoggingLevel.WarningsAndErrors; + + public ChoiceController ChoiceController; + + public IScriptInterpreter ScriptSystem; + + public string ScriptInterpreterName; + + public GameObject MenuPrefab; + + public GameObject ScenePrefab; + + public GameObject HistoryPrefab; + + public GameObject TitlePrefab; + + public GameObject PromptPrefab; + + public GameObject ConfigPrefab; + + public GameObject SaveLoadPrefab; + + public GameObject ChapterJumpPrefab; + + public GameObject GalleryPrefab; + + public GameObject ChapterScreenPrefab; + + public GameObject ExtraScreenPrefab; + + public GameObject TipsPrefab; + + public GameObject ChapterPreviewPrefab; + + private PreparedAction actions; + + public bool IsInitialized; + + public bool IsSkipping; + + public bool IsForceSkip; + + public bool IsAuto; + + public bool IsRunning; + + public bool ForceForceSkip; + + public bool CanSkip = true; + + public bool CanSave = true; + + public bool CanInput = true; + + public bool CanReturn; + + public bool UsePrompts = true; + + public bool SkipUnreadMessages; + + public bool SkipModeDelay = true; + + public bool ClickDuringAuto; + + public bool RightClickMenu = true; + + public bool StopVoiceOnClick; + + public bool UseSystemSounds = true; + + public bool UseEnglishText = true; + + public bool DisableUI; + + private float skipWait = 0.1f; + + private bool CanAdvance = true; + + public bool CanExit; + + private GameState gameState; + + public bool MessageBoxVisible; + + public float MessageWindowOpacity = 0.5f; + + private bool ReopenMessageBox; + + public readonly List WaitList = new List(); + + private MenuUIController menuUIController; + + private HistoryWindow historyWindow; + + private PromptController promptController; + + private ConfigManager configManager; + + private GalleryManager galleryManager; + + private MGHelper.InputHandler inputHandler; + + private IGameState curStateObj; + + private float blockInputTime; + + private int SystemInit = 1; + + private Resolution fullscreenResolution; + + private int screenModeSet = -1; + + private Stack stateStack = new Stack(); + + public bool HasFocus; + + public float AspectRatio; + + public static GameSystem Instance => _instance ?? (_instance = GameObject.Find("_GameSystem").GetComponent()); + + public GameState GameState + { + get + { + return gameState; + } + set + { + Debug.Log("Changing game state to " + value); + gameState = value; + } + } + + private void Initialize() + { + Logger.Log("GameSystem: Starting GameSystem"); + IsInitialized = true; + AssetManager = new AssetManager(); + AudioController = new AudioController(); + TextController = new TextController(); + TextHistory = new TextHistory(); + try + { + AssetManager.CompileIfNeeded(); + Logger.Log("GameSystem: Starting ScriptInterpreter"); + Type type = Type.GetType(ScriptInterpreterName); + if (type == null) + { + throw new Exception("Cannot find class " + ScriptInterpreterName + " through reflection!"); + } + ScriptSystem = (Activator.CreateInstance(type) as IScriptInterpreter); + if (ScriptSystem == null) + { + throw new Exception("Failed to instantiate ScriptSystem!"); + } + ScriptSystem.Initialize(this); + } + catch (Exception arg) + { + Logger.LogError($"Unable to load Script Interpreter of type {ScriptInterpreterName}!\r\n{arg}"); + throw; + IL_00d0:; + } + IsRunning = true; + GameState = GameState.Normal; + curStateObj = new StateNormal(); + IGameState obj = curStateObj; + inputHandler = obj.InputHandler; + MessageBoxVisible = false; + if (!PlayerPrefs.HasKey("width")) + { + PlayerPrefs.SetInt("width", 640); + } + if (!PlayerPrefs.HasKey("height")) + { + PlayerPrefs.SetInt("height", 480); + } + if (PlayerPrefs.GetInt("width") < 640) + { + PlayerPrefs.SetInt("width", 640); + } + if (PlayerPrefs.GetInt("height") < 480) + { + PlayerPrefs.SetInt("height", 480); + } + if ((Screen.width < 640 || Screen.height < 480) && !Screen.fullScreen) + { + Screen.SetResolution(640, 480, fullscreen: false); + } + } + + public void UpdateAspectRatio(float newratio) + { + AspectRatio = newratio; + if (!Screen.fullScreen) + { + int width = Mathf.RoundToInt((float)Screen.height * AspectRatio); + Screen.SetResolution(width, Screen.height, fullscreen: false); + } + if (!PlayerPrefs.HasKey("width")) + { + PlayerPrefs.SetInt("width", Mathf.RoundToInt((float)PlayerPrefs.GetInt("height") * AspectRatio)); + } + MainUIController.UpdateBlackBars(); + } + + public void CheckinSystem() + { + SystemInit--; + } + + public void ForceReturnNormalState() + { + stateStack.Clear(); + curStateObj = new StateNormal(); + IGameState obj = curStateObj; + inputHandler = obj.InputHandler; + GameState = GameState.Normal; + } + + public void PopStateStack() + { + if (stateStack.Count == 0) + { + Debug.Log("PopStateStack has no state to remove."); + curStateObj = new StateNormal(); + IGameState obj = curStateObj; + inputHandler = obj.InputHandler; + GameState = GameState.Normal; + } + else + { + if (curStateObj != null) + { + Debug.Log("PopStateStack - Calling OnLeaveState"); + curStateObj.OnLeaveState(); + curStateObj = null; + } + StateEntry stateEntry = stateStack.Pop(); + inputHandler = stateEntry.InputHandler; + GameState = stateEntry.State; + curStateObj = stateEntry.StateObject; + if (curStateObj != null) + { + curStateObj.OnRestoreState(); + } + Debug.Log("StateStack now has " + stateStack.Count + " entries."); + } + } + + private void PushStateStack(MGHelper.InputHandler newHandler, GameState newState) + { + if (curStateObj != null) + { + stateStack.Push(new StateEntry(curStateObj, GameState)); + } + else + { + stateStack.Push(new StateEntry(inputHandler, GameState)); + } + inputHandler = newHandler; + GameState = newState; + curStateObj = null; + } + + public void PushStateObject(IGameState stateObject) + { + if (curStateObj != null) + { + stateStack.Push(new StateEntry(curStateObj, GameState)); + } + else + { + stateStack.Push(new StateEntry(inputHandler, GameState)); + } + curStateObj = stateObject; + IGameState obj = curStateObj; + inputHandler = obj.InputHandler; + GameState = curStateObj.GetStateType(); + } + + public IGameState GetStateObject() + { + return curStateObj; + } + + public void ClearActions() + { + actions = null; + } + + public void RegisterAction(PreparedAction action) + { + actions = (PreparedAction)Delegate.Combine(actions, action); + } + + public void ExecuteActions() + { + StartCoroutine(ActionRunner()); + CanAdvance = false; + } + + private IEnumerator ActionRunner() + { + Resources.UnloadUnusedAssets(); + yield return (object)null; + yield return (object)null; + if (actions != null) + { + actions(); + } + actions = null; + CanAdvance = true; + } + + public void HideUIControls() + { + DisableUI = true; + UIControl.SetActive(value: false); + } + + public void ShowUIControls() + { + DisableUI = false; + UIControl.SetActive(value: true); + } + + public void CloseChoiceIfExists() + { + if (ChoiceController != null) + { + ChoiceController.Destroy(); + ChoiceController = null; + } + } + + public void LeaveChoices() + { + PopStateStack(); + AddWait(new Wait(0.5f, WaitTypes.WaitForTime, delegate + { + ChoiceController.Destroy(); + ChoiceController = null; + })); + ExecuteActions(); + } + + public void DisplayChoices(List options, int count) + { + if (ChoiceController != null) + { + ChoiceController.Destroy(); + ChoiceController = null; + } + PushStateStack(ChoiceHandleInput, GameState.ChoiceScreen); + ChoiceController = new ChoiceController(); + ChoiceController.Create(options, count); + } + + private bool ChoiceHandleInput() + { + if (Input.GetKeyDown(KeyCode.Space)) + { + SwitchToViewMode(); + return false; + } + if (Input.GetMouseButtonDown(1)) + { + if (IsSkipping && !IsForceSkip) + { + IsSkipping = false; + return false; + } + if (IsAuto) + { + IsAuto = false; + return false; + } + } + if (Input.GetMouseButtonDown(1) && MessageBoxVisible) + { + SwitchToRightClickMenu(); + return false; + } + return false; + } + + private bool HiddenMessageWindowHandleInput() + { + if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Escape)) + { + PopStateStack(); + UpdateWaits(); + MessageBoxVisible = true; + MainUIController.FadeIn(0.2f); + SceneController.RevealFace(0.2f); + ExecuteActions(); + blockInputTime = 0.25f; + } + return false; + } + + public void LeaveMenu(MenuUIController.MenuCloseDelegate onClose, bool doPop) + { + menuUIController.LeaveMenu(delegate + { + if (doPop) + { + PopStateStack(); + } + UpdateWaits(); + ExecuteActions(); + if (onClose != null) + { + onClose(); + } + }, showMessage: false); + } + + public void SwitchToHiddenWindow2() + { + MainUIController.FadeOut(0.3f, isBlocking: false); + SceneController.HideFace(0.3f); + ExecuteActions(); + PushStateStack(HiddenMessageWindowHandleInput, GameState.HiddenMessageWindow); + } + + public void SwitchToHiddenWindow() + { + menuUIController.LeaveMenu(delegate + { + PopStateStack(); + UpdateWaits(); + ExecuteActions(); + PushStateStack(HiddenMessageWindowHandleInput, GameState.HiddenMessageWindow); + }, showMessage: false); + } + + public void LeaveGalleryScreen(GalleryManager.GalleryCloseCallback callback) + { + if (!(galleryManager == null)) + { + inputHandler = null; + galleryManager.Close(delegate + { + PopStateStack(); + ExecuteActions(); + galleryManager = null; + if (callback != null) + { + callback(); + } + }); + } + } + + public void LeaveConfigScreen(ConfigManager.LeaveConfigDelegate callback) + { + inputHandler = null; + configManager.Leave(delegate + { + PopStateStack(); + ExecuteActions(); + if (callback != null) + { + callback(); + } + }); + } + + public void RevealMessageBox() + { + MessageBoxVisible = true; + MainUIController.FadeIn(0.5f); + SceneController.RevealFace(0.5f); + ExecuteActions(); + } + + private bool MenuHandleInput() + { + if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) + { + menuUIController.LeaveMenu(delegate + { + PopStateStack(); + UpdateWaits(); + MessageBoxVisible = true; + MainUIController.ShowMessageBox(); + ExecuteActions(); + }, showMessage: true); + } + return false; + } + + private void UpdateCarret() + { + if (IsSkipping || IsAuto || GameState != GameState.Normal) + { + MainUIController.HideCarret(); + } + else if (WaitList.Exists((Wait a) => a.Type == WaitTypes.WaitForInput) && !WaitList.Exists((Wait a) => a.Type == WaitTypes.WaitForText) && !TextController.IsTyping() && MessageBoxVisible) + { + MainUIController.ShowCarret(); + } + else + { + MainUIController.HideCarret(); + } + } + + public void SwitchToConfig(int configtype, bool showMessageWindow) + { + ReopenMessageBox = showMessageWindow; + RegisterAction(delegate + { + PushStateStack(ConfigHandleInput, GameState.ConfigScreen); + GameObject gameObject = UnityEngine.Object.Instantiate(ConfigPrefab); + configManager = gameObject.GetComponent(); + if (configManager == null) + { + throw new Exception("Failed to instantiate configManager!"); + } + configManager.Open(configtype, showMessageWindow); + }); + ExecuteActions(); + } + + public void SwitchToGallery() + { + if (galleryManager != null) + { + Debug.Log(galleryManager); + PushStateStack(GalleryHandleInput, GameState.CGGallery); + ExecuteActions(); + } + else + { + RegisterAction(delegate + { + PushStateStack(GalleryHandleInput, GameState.CGGallery); + GameObject gameObject = UnityEngine.Object.Instantiate(GalleryPrefab); + galleryManager = gameObject.GetComponent(); + if (galleryManager == null) + { + throw new Exception("Failed to instantiate GalleryManager!"); + } + galleryManager.Open(); + }); + ExecuteActions(); + } + } + + public void SwitchToViewMode() + { + PushStateStack(HiddenMessageWindowHandleInput, GameState.HiddenMessageWindow); + MainUIController.FadeOut(0.2f, isBlocking: false); + SceneController.HideFace(0.2f); + ExecuteActions(); + blockInputTime = 0.25f; + } + + public void SwitchToHistoryScreen() + { + PushStateObject(new StateHistory()); + } + + public void SwitchToRightClickMenu() + { + PushStateStack(MenuHandleInput, GameState.RightClickMenu); + GameObject gameObject = UnityEngine.Object.Instantiate(MenuPrefab); + menuUIController = gameObject.GetComponent(); + if (menuUIController == null) + { + throw new Exception("Failed to instantiate MenuUIController!"); + } + MainUIController.FadeOut(0.3f, isBlocking: false); + SceneController.HideFace(0.3f); + ExecuteActions(); + } + + private bool GalleryHandleInput() + { + if (Input.GetMouseButtonDown(1)) + { + PopStateStack(); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 0); + return false; + } + return false; + } + + private bool ConfigHandleInput() + { + if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) + { + LeaveConfigScreen(null); + } + return false; + } + + public void ClearAllWaits() + { + WaitList.ForEach(delegate(Wait a) + { + a.Finish(); + }); + WaitList.RemoveAll((Wait a) => a.IsActive); + } + + public bool HasWaitOfType(WaitTypes type) + { + return WaitList.Exists((Wait f) => f.Type == type); + } + + public void ClearTextWait(bool finish) + { + List list = (from a in WaitList + where a.Type == WaitTypes.WaitForText + select a).ToList(); + foreach (Wait item in list) + { + if (finish) + { + item.Finish(); + } + WaitList.Remove(item); + } + TextController.FinishTyping(); + } + + public void ClearVoiceWaits() + { + WaitList.RemoveAll((Wait a) => a.Type == WaitTypes.WaitForVoice); + } + + public void ClearInputWaits() + { + if (IsAuto) + { + } + } + + public void ClearWait() + { + if (WaitList.Exists((Wait a) => a.Type == WaitTypes.WaitForText) && !IsSkipping) + { + ClearTextWait(finish: true); + } + else + { + WaitList.ForEach(delegate(Wait a) + { + a.Finish(); + }); + WaitList.RemoveAll((Wait a) => a.IsActive); + if (StopVoiceOnClick) + { + AudioController.StopAllVoice(); + } + } + } + + public void AddWait(Wait newWait) + { + WaitList.Add(newWait); + } + + private bool HasExistingWaits() + { + bool result = WaitList.Count != 0; + WaitList.RemoveAll((Wait a) => !a.IsRunning()); + if (IsAuto) + { + WaitList.RemoveAll((Wait a) => a.Type == WaitTypes.WaitForInput); + } + return result; + } + + public void UpdateWaits() + { + WaitList.ForEach(delegate(Wait a) + { + a.Update(); + }); + } + + public IEnumerator FrameWaitForFullscreen(int width, int height, bool fullscreen) + { + yield return (object)new WaitForEndOfFrame(); + yield return (object)new WaitForFixedUpdate(); + Screen.SetResolution(width, height, fullscreen); + while (Screen.width != width || Screen.height != height) + { + yield return (object)null; + } + } + + public void GoFullscreen() + { + int width = fullscreenResolution.width; + int height = fullscreenResolution.height; + Screen.SetResolution(width, height, fullscreen: true); + Debug.Log(width + " , " + height); + PlayerPrefs.SetInt("fullscreen_width", width); + PlayerPrefs.SetInt("fullscreen_height", height); + } + + private void OnApplicationFocus(bool focusStatus) + { + HasFocus = focusStatus; + } + + private void LateUpdate() + { + if (screenModeSet == -1) + { + screenModeSet = 0; + fullscreenResolution = Screen.currentResolution; + if (PlayerPrefs.HasKey("fullscreen_width") && PlayerPrefs.HasKey("fullscreen_height") && Screen.fullScreen) + { + fullscreenResolution.width = PlayerPrefs.GetInt("fullscreen_width"); + fullscreenResolution.height = PlayerPrefs.GetInt("fullscreen_height"); + } + Debug.Log("Fullscreen Resolution: " + fullscreenResolution.width + ", " + fullscreenResolution.height); + } + } + + private void Update() + { + if (SystemInit <= 0) + { + Logger.Update(); + if (!IsInitialized) + { + Initialize(); + } + else + { + if (blockInputTime <= 0f) + { + if ((CanInput || GameState != GameState.Normal) && (inputHandler == null || !inputHandler())) + { + return; + } + } + else + { + blockInputTime -= Time.deltaTime; + } + if (IsRunning && CanAdvance) + { + UpdateWaits(); + UpdateCarret(); + try + { + if (GameState == GameState.Normal) + { + TextController.Update(); + if (!IsSkipping) + { + goto IL_0112; + } + skipWait -= Time.deltaTime; + if (!(skipWait <= 0f)) + { + goto IL_0112; + } + if (!HasExistingWaits()) + { + if (SkipModeDelay) + { + skipWait = 0.1f; + } + goto IL_0112; + } + ClearAllWaits(); + } + goto end_IL_00a2; + IL_0112: + float num = Time.time + 0.01f; + while (!HasExistingWaits() && !(Time.time > num) && !HasExistingWaits() && CanAdvance) + { + ScriptSystem.Advance(); + } + end_IL_00a2:; + } + catch (Exception) + { + IsRunning = false; + throw; + IL_0178:; + } + } + } + } + } + + private void OnDestroy() + { + } + + private void OnApplicationQuit() + { + BurikoMemory.Instance.SaveGlobals(); + if (GameState != GameState.DialogPrompt && !CanExit) + { + Application.CancelQuit(); + if (GameState == GameState.ConfigScreen) + { + if (ReopenMessageBox) + { + RevealMessageBox(); + } + RegisterAction(delegate + { + LeaveConfigScreen(delegate + { + PushStateObject(new StateDialogPrompt(PromptType.DialogExit, delegate + { + CanExit = true; + Application.Quit(); + }, null)); + }); + }); + ExecuteActions(); + } + else + { + RegisterAction(delegate + { + PushStateObject(new StateDialogPrompt(PromptType.DialogExit, delegate + { + CanExit = true; + Application.Quit(); + }, null)); + }); + ExecuteActions(); + } + } + else + { + SteamController.Close(); + } + } + } +} diff --git a/Assets.Scripts.Core/KeyHook.cs b/Assets.Scripts.Core/KeyHook.cs new file mode 100644 index 00000000..8c479051 --- /dev/null +++ b/Assets.Scripts.Core/KeyHook.cs @@ -0,0 +1,6 @@ +namespace Assets.Scripts.Core +{ + public class KeyHook + { + } +} diff --git a/Assets.Scripts.Core/LayerAlignment.cs b/Assets.Scripts.Core/LayerAlignment.cs new file mode 100644 index 00000000..ef6195a8 --- /dev/null +++ b/Assets.Scripts.Core/LayerAlignment.cs @@ -0,0 +1,9 @@ +namespace Assets.Scripts.Core +{ + public enum LayerAlignment + { + AlignTopleft, + AlignBottomCenter, + AlignCenter + } +} diff --git a/Assets.Scripts.Core/LogOnMainThread.cs b/Assets.Scripts.Core/LogOnMainThread.cs new file mode 100644 index 00000000..046ce507 --- /dev/null +++ b/Assets.Scripts.Core/LogOnMainThread.cs @@ -0,0 +1,4 @@ +namespace Assets.Scripts.Core +{ + public delegate void LogOnMainThread(); +} diff --git a/Assets.Scripts.Core/Logger.cs b/Assets.Scripts.Core/Logger.cs new file mode 100644 index 00000000..9211dce0 --- /dev/null +++ b/Assets.Scripts.Core/Logger.cs @@ -0,0 +1,53 @@ +using System; +using UnityEngine; + +namespace Assets.Scripts.Core +{ + public static class Logger + { + private static LogOnMainThread logDelegate; + + public static void RegisterLogOnMainThread(LogOnMainThread d) + { + logDelegate = (LogOnMainThread)Delegate.Combine(logDelegate, d); + } + + private static bool CheckConsoleLogLevel(LoggingLevel targetLevel) + { + return GameSystem.Instance.ConsoleLoggingLevel >= targetLevel; + } + + public static void Log(string message) + { + if (CheckConsoleLogLevel(LoggingLevel.All)) + { + Debug.Log(message); + } + } + + public static void LogWarning(string message) + { + if (CheckConsoleLogLevel(LoggingLevel.WarningsAndErrors)) + { + Debug.LogWarning(message); + } + } + + public static void LogError(string message) + { + if (CheckConsoleLogLevel(LoggingLevel.ErrorOnly)) + { + Debug.LogError(message); + } + } + + public static void Update() + { + if (logDelegate != null) + { + logDelegate(); + logDelegate = null; + } + } + } +} diff --git a/Assets.Scripts.Core/LoggingLevel.cs b/Assets.Scripts.Core/LoggingLevel.cs new file mode 100644 index 00000000..78b5d3f1 --- /dev/null +++ b/Assets.Scripts.Core/LoggingLevel.cs @@ -0,0 +1,10 @@ +namespace Assets.Scripts.Core +{ + public enum LoggingLevel + { + None, + ErrorOnly, + WarningsAndErrors, + All + } +} diff --git a/Assets.Scripts.Core/MGHelper.cs b/Assets.Scripts.Core/MGHelper.cs new file mode 100644 index 00000000..8702e9ba --- /dev/null +++ b/Assets.Scripts.Core/MGHelper.cs @@ -0,0 +1,440 @@ +using System; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.Core +{ + public static class MGHelper + { + public delegate bool InputHandler(); + + private static readonly byte[] Key = new byte[9] + { + 229, + 99, + 174, + 4, + 45, + 166, + 127, + 158, + 69 + }; + + private static string _savepath = string.Empty; + + private static bool isD3d9; + + private static bool typeCheck; + + public static Mesh CreateMeshWithOrigin(int width, int height, Vector2 origin) + { + Mesh mesh = new Mesh(); + float num = Mathf.Round((float)width / 2f); + float num2 = Mathf.Round((float)height / 2f); + origin.x -= num; + origin.y -= num2; + Vector3 vector = new Vector3(0f - num - origin.x, num2 + origin.y, 0f); + Vector3 vector2 = new Vector3(num - origin.x, num2 + origin.y, 0f); + Vector3 vector3 = new Vector3(num - origin.x, 0f - num2 + origin.y, 0f); + Vector3 vector4 = new Vector3(0f - num - origin.x, 0f - num2 + origin.y, 0f); + Vector3[] vertices = new Vector3[4] + { + vector2, + vector3, + vector, + vector4 + }; + Vector2[] uv = new Vector2[4] + { + new Vector2(1f, 1f), + new Vector2(1f, 0f), + new Vector2(0f, 1f), + new Vector2(0f, 0f) + }; + int[] triangles = new int[6] + { + 0, + 1, + 2, + 2, + 1, + 3 + }; + mesh.vertices = vertices; + mesh.uv = uv; + mesh.triangles = triangles; + mesh.RecalculateNormals(); + mesh.RecalculateBounds(); + return mesh; + } + + public static Mesh CreateMesh(int width, int height, LayerAlignment alignment) + { + Mesh mesh = new Mesh(); + float num = Mathf.Round((float)width / 2f); + float num2 = Mathf.Round((float)height / 2f); + Vector3 vector; + Vector3 vector2; + Vector3 vector3; + Vector3 vector4; + switch (alignment) + { + case LayerAlignment.AlignTopleft: + vector = new Vector3(0f, 0f, 0f); + vector2 = new Vector3((float)width, 0f, 0f); + vector3 = new Vector3((float)width, (float)(-height), 0f); + vector4 = new Vector3(0f, (float)(-height), 0f); + break; + case LayerAlignment.AlignBottomCenter: + vector = new Vector3(0f - num, (float)height, 0f); + vector2 = new Vector3(num, (float)height, 0f); + vector3 = new Vector3(num, 0f, 0f); + vector4 = new Vector3(0f - num, 0f, 0f); + break; + case LayerAlignment.AlignCenter: + vector = new Vector3(0f - num, num2, 0f); + vector2 = new Vector3(num, num2, 0f); + vector3 = new Vector3(num, 0f - num2, 0f); + vector4 = new Vector3(0f - num, 0f - num2, 0f); + break; + default: + Logger.LogError("Could not CreateMesh, unexpected alignment " + alignment); + return null; + } + Vector3[] vertices = new Vector3[4] + { + vector2, + vector3, + vector, + vector4 + }; + Vector2[] uv = new Vector2[4] + { + new Vector2(1f, 1f), + new Vector2(1f, 0f), + new Vector2(0f, 1f), + new Vector2(0f, 0f) + }; + int[] triangles = new int[6] + { + 0, + 1, + 2, + 2, + 1, + 3 + }; + mesh.vertices = vertices; + mesh.uv = uv; + mesh.triangles = triangles; + mesh.RecalculateNormals(); + mesh.RecalculateBounds(); + return mesh; + } + + public static void KeyEncode(byte[] b) + { + byte[] array = (byte[])Key.Clone(); + for (int i = 0; i < b.Length; i++) + { + b[i] = (byte)(b[i] ^ array[i % Key.Length]); + array[i % array.Length] += 27; + } + } + + public static void WriteVector3(BinaryWriter br, Vector3 v) + { + br.Write(v.x); + br.Write(v.y); + br.Write(v.z); + } + + public static Vector3 ReadVector3(BinaryReader br) + { + Vector3 result = default(Vector3); + result.x = br.ReadSingle(); + result.y = br.ReadSingle(); + result.z = br.ReadSingle(); + return result; + } + + public static void WriteColor(BinaryWriter br, Color c) + { + br.Write(c.r); + br.Write(c.g); + br.Write(c.b); + br.Write(c.a); + } + + public static Color ReadColor(BinaryReader br) + { + Color result = default(Color); + result.r = br.ReadSingle(); + result.g = br.ReadSingle(); + result.b = br.ReadSingle(); + result.a = br.ReadSingle(); + return result; + } + + public static string GetSavePath() + { + if (Application.platform == RuntimePlatform.OSXPlayer) + { + return Application.persistentDataPath; + } + if (Application.platform == RuntimePlatform.LinuxPlayer) + { + return Application.persistentDataPath; + } + if (_savepath == string.Empty) + { + string text = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + if (!Directory.Exists(text) || text == string.Empty) + { + text = Environment.ExpandEnvironmentVariables("%appdata%"); + } + _savepath = Path.Combine(text, "Mangagamer\\higurashi01"); + Directory.CreateDirectory(_savepath); + } + return _savepath; + } + + public static string GetDataPath() + { + if (Application.platform == RuntimePlatform.OSXPlayer) + { + return "Resources/GameData"; + } + if (Application.platform == RuntimePlatform.WindowsEditor) + { + return "ExternalAssets/Archives"; + } + return "GameData"; + } + + public static Vector3 GetReverseOffsetPosition(Vector3 pos) + { + return pos; + } + + public static Vector3 GetOffsetPosition(Vector3 pos) + { + return pos; + } + + public static int GetLoopPoint(string bgm) + { + string text = bgm; + if (Path.HasExtension(bgm)) + { + text = Path.GetFileNameWithoutExtension(bgm); + } + switch (text) + { + case "bgm_dd_011": + return 1152298; + case "bgm_dd_020": + return 194763; + case "bgm_dd_030": + return 1637632; + case "bgm_dd_040": + return 782606; + case "bgm_dd_050": + return 287424; + case "bgm_dd_060": + return 1360950; + case "bgm_dd_061": + return 1988958; + case "bgm_dd_070": + return 673727; + case "bgm_dd_080": + return 314858; + case "bgm_dd_081": + return 126326; + case "bgm_dd_090": + return 1849827; + case "bgm_dd_100": + return 267264; + case "bgm_dd_130": + return 243138; + case "bgm_dd_160": + return 0; + case "bgm_dd_170": + return 0; + case "bgm_dd_190": + return 724; + case "bgm_dd_200": + return 1210327; + case "bgm_kk_010": + return 1615391; + case "bgm_kk_020": + return 2118652; + case "bgm_kk_021": + return 188346; + case "bgm_kk_030": + return 1442255; + case "bgm_kk_040": + return 644216; + case "bgm_kk_050": + return 4498436; + case "bgm_kk_070": + return 269311; + case "bgm_kk_080": + return 0; + case "bgm_kk_090": + return 175389; + case "bgm_kk_091": + return 104493; + case "bgm_kk_110": + return 151411; + case "bgm_kk_120": + return 555457; + case "bgm_kk_130": + return 251693; + case "bgm_kk_140": + return 826890; + case "bgm_kk_210": + return 3611530; + case "bgm_kk_220": + return 2618304; + case "bgm_kk_240": + return 4814598; + case "bgm_kk_250": + return 376703; + case "bgm_kk_260": + return 366437; + case "bgm_kk_280": + return 1144466; + case "bgm_sys_dd_01": + return 2429215; + case "bgm_sys_dd_02": + return 2508024; + case "bgm_sys_dd_03": + return 665967; + case "bgm_sys_dd_03_2": + return 1163094; + case "bgm_sys_dd_04": + return 3040630; + case "bgm_sys_dd_05": + return 787193; + case "bgm_sys_dded_01": + return 1177981; + case "bgm_sys_dded_02": + return 1225806; + case "bgm_sys_dded_03": + return 4014307; + case "bgm_sys_dded_04": + return 709553; + case "bgm_sys_kk_01": + return 149919; + case "bgm_sys_kk_02": + return 418378; + case "bgm_sys_kk_03": + return 4174863; + case "bgm_sys_kk_04": + return 655403; + case "bgm_sys_kk_05": + return 1819877; + case "bgm_sys_kked_01": + return 364179; + case "bgm_sys_kked_02": + return 2429792; + case "bgm_sys_kked_03": + return 1893150; + case "bgm_sys_kked_04": + return 508168; + case "bgm_title": + return 4905424; + case "bsel0051": + return 3053760; + case "happycrossing": + return 5844753; + case "kankyo_25_d": + return 0; + case "se1011": + return 0; + case "se1015_d": + return 0; + case "se2020_d": + return 0; + case "se2110_d": + return 0; + case "se2111_d": + return 0; + case "sel0120_k": + return 0; + case "sel2040_d": + return 0; + case "sel2041": + return 0; + case "sel3010_d": + return 0; + case "sel_0120_d": + return 0; + case "sel_0220_d": + return 0; + case "sel_4050_d": + return 0; + case "sel_ashi_11_s": + return 0; + case "sel_dd_0010": + return 0; + case "sel_dd_0021": + return 0; + case "sel_dd_0030": + return 0; + case "sel_dd_0033": + return 0; + case "sel_dd_0035": + return 0; + case "sel_dd_0240": + return 0; + case "sel_dd_0245": + return 0; + case "sel_dd_1010": + return 0; + case "sel_dd_1021": + return 0; + case "sel_dd_2030": + return 0; + case "sel_dd_2700": + return 0; + case "sel_dvd_0080": + return 0; + case "sel_dvd_0100_02": + return 0; + case "sel_dvd_0110": + return 0; + case "sel_dvd_0120": + return 0; + case "sel_dvd_0160": + return 0; + case "sel_dvd_0170": + return 0; + case "sel_dvd_0180": + return 0; + case "sel_dvd_0190": + return 0; + case "sel_dvd_0250": + return 0; + case "sel_kk_0090": + return 0; + case "sel_ot_21_0010": + return 0; + case "sel_ot_21_0030": + return 0; + case "sel_ot_26_0010": + return 0; + case "selp_dd_0050": + return 88692; + case "selp_dd_0060": + return 417357; + case "selp_dd_0070": + return 71684; + default: + return 0; + } + } + } +} diff --git a/Assets.Scripts.Core/OnFinishWait.cs b/Assets.Scripts.Core/OnFinishWait.cs new file mode 100644 index 00000000..c2ec85a9 --- /dev/null +++ b/Assets.Scripts.Core/OnFinishWait.cs @@ -0,0 +1,4 @@ +namespace Assets.Scripts.Core +{ + public delegate void OnFinishWait(); +} diff --git a/Assets.Scripts.Core/PreparedAction.cs b/Assets.Scripts.Core/PreparedAction.cs new file mode 100644 index 00000000..d7085bbb --- /dev/null +++ b/Assets.Scripts.Core/PreparedAction.cs @@ -0,0 +1,4 @@ +namespace Assets.Scripts.Core +{ + public delegate void PreparedAction(); +} diff --git a/Assets.Scripts.Core/StateEntry.cs b/Assets.Scripts.Core/StateEntry.cs new file mode 100644 index 00000000..06ed817c --- /dev/null +++ b/Assets.Scripts.Core/StateEntry.cs @@ -0,0 +1,26 @@ +using Assets.Scripts.Core.State; + +namespace Assets.Scripts.Core +{ + internal class StateEntry + { + public MGHelper.InputHandler InputHandler; + + public GameState State; + + public IGameState StateObject; + + public StateEntry(MGHelper.InputHandler inputHandler, GameState state) + { + InputHandler = inputHandler; + State = state; + } + + public StateEntry(IGameState stateobj, GameState state) + { + StateObject = stateobj; + InputHandler = stateobj.InputHandler; + State = state; + } + } +} diff --git a/Assets.Scripts.Core/Wait.cs b/Assets.Scripts.Core/Wait.cs new file mode 100644 index 00000000..a7a2b049 --- /dev/null +++ b/Assets.Scripts.Core/Wait.cs @@ -0,0 +1,50 @@ +using UnityEngine; + +namespace Assets.Scripts.Core +{ + public class Wait + { + private OnFinishWait onFinish; + + public WaitTypes Type; + + private float time; + + public bool IsActive; + + public Wait(float length, WaitTypes type, OnFinishWait onFinishDelegate) + { + Type = type; + time = length; + onFinish = onFinishDelegate; + } + + public void Update() + { + time -= Time.deltaTime; + IsActive = true; + } + + public bool IsRunning() + { + if (Type == WaitTypes.WaitForInput) + { + return true; + } + if (time > 0f) + { + return true; + } + Finish(); + return false; + } + + public void Finish() + { + if (IsActive && onFinish != null) + { + onFinish(); + } + } + } +} diff --git a/Assets.Scripts.Core/WaitTypes.cs b/Assets.Scripts.Core/WaitTypes.cs new file mode 100644 index 00000000..e97eb219 --- /dev/null +++ b/Assets.Scripts.Core/WaitTypes.cs @@ -0,0 +1,14 @@ +namespace Assets.Scripts.Core +{ + public enum WaitTypes + { + WaitForTime, + WaitForText, + WaitForInput, + WaitForAudio, + WaitForVoice, + WaitForScene, + WaitForMove, + WaitForAuto + } +} diff --git a/Assets.Scripts.UI.CGGallery/GalleryButton.cs b/Assets.Scripts.UI.CGGallery/GalleryButton.cs new file mode 100644 index 00000000..accaaeae --- /dev/null +++ b/Assets.Scripts.UI.CGGallery/GalleryButton.cs @@ -0,0 +1,57 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Buriko; +using UnityEngine; + +namespace Assets.Scripts.UI.CGGallery +{ + public class GalleryButton : MonoBehaviour + { + private GameSystem gameSystem; + + private float time; + + private int cgslot; + + private void OnClick() + { + if (gameSystem == null) + { + gameSystem = GameSystem.Instance; + } + if (gameSystem.GameState == GameState.CGGallery && !(time > 0f) && UICamera.currentTouchID == -1) + { + gameSystem.PopStateStack(); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", cgslot); + time = 1f; + } + } + + private void OnHover(bool hover) + { + if (gameSystem == null) + { + gameSystem = GameSystem.Instance; + } + if (gameSystem.GameState == GameState.CGGallery) + { + } + } + + public void Prepare(GalleryManager manager, int slot) + { + cgslot = slot; + } + + private void Start() + { + } + + private void Update() + { + if (time > 0f) + { + time -= Time.deltaTime; + } + } + } +} diff --git a/Assets.Scripts.UI.CGGallery/GalleryManager.cs b/Assets.Scripts.UI.CGGallery/GalleryManager.cs new file mode 100644 index 00000000..80f9995f --- /dev/null +++ b/Assets.Scripts.UI.CGGallery/GalleryManager.cs @@ -0,0 +1,249 @@ +using Assets.Scripts.Core.Buriko; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.CGGallery +{ + public class GalleryManager : MonoBehaviour + { + public struct GalleryEntry + { + public string[] ViewCG; + + public string[] DisplayCG; + + public GalleryEntry(string[] a, string[] b) + { + ViewCG = a; + DisplayCG = b; + } + } + + public delegate void GalleryCloseCallback(); + + public UITweener GalleryHeader; + + public UITweener GalleryPanel; + + public UITweener Background; + + public UITweener BlackZone; + + public UIPanel RootPanel; + + public UIGrid CGGrid; + + public GalleryButton ReturnButton; + + private Dictionary galleryEntries = new Dictionary + { + { + 0, + new string[3] + { + "ev01", + "ev01_02", + "ev01_03" + } + }, + { + 1, + new string[1] + { + "ev02" + } + }, + { + 2, + new string[1] + { + "ev03" + } + }, + { + 3, + new string[3] + { + "cut_004_10_10", + "ev04a", + "ev04b" + } + }, + { + 4, + new string[2] + { + "ev05a", + "ev05b" + } + }, + { + 5, + new string[1] + { + "ev06" + } + }, + { + 6, + new string[3] + { + "ev07a", + "ev07b", + "ev07c" + } + }, + { + 7, + new string[1] + { + "ev08" + } + }, + { + 8, + new string[3] + { + "ev09_01", + "ev09_03", + "ev09" + } + }, + { + 9, + new string[1] + { + "evED01" + } + }, + { + 10, + new string[1] + { + "evED02" + } + }, + { + 11, + new string[1] + { + "evED03" + } + }, + { + 12, + new string[1] + { + "evED04" + } + }, + { + 13, + new string[1] + { + "evED05" + } + }, + { + 14, + new string[1] + { + "evED01_03" + } + }, + { + 15, + new string[4] + { + "ev10_01", + "ev10_02", + "ev10_03", + "ev10_04" + } + } + }; + + private IEnumerator DoClose(GalleryCloseCallback callback) + { + yield return (object)null; + yield return (object)null; + GalleryHeader.PlayReverse(); + GalleryPanel.PlayReverse(); + Background.PlayReverse(); + yield return (object)new WaitForSeconds(0.3f); + callback?.Invoke(); + Object.Destroy(base.gameObject); + } + + private IEnumerator DoHide() + { + yield return (object)null; + BlackZone.PlayForward(); + yield return (object)new WaitForSeconds(0.3f); + } + + private IEnumerator DoUnhide() + { + yield return (object)null; + BlackZone.PlayReverse(); + yield return (object)new WaitForSeconds(0.3f); + } + + public void Hide() + { + StartCoroutine(DoHide()); + } + + public void UnHide() + { + StartCoroutine(DoUnhide()); + } + + public void Close(GalleryCloseCallback callback) + { + StartCoroutine(DoClose(callback)); + } + + private IEnumerator DoOpen() + { + yield return (object)null; + yield return (object)null; + GalleryHeader.PlayForward(); + GalleryPanel.PlayForward(); + Background.PlayForward(); + } + + public void Open() + { + StartCoroutine(DoOpen()); + for (int i = 0; i < galleryEntries.Count; i++) + { + Transform child = CGGrid.transform.GetChild(i); + if (BurikoMemory.Instance.SeenCG(galleryEntries[i][0])) + { + child.GetComponent().Prepare(this, i + 1); + UISprite component = child.GetComponent(); + UIImageButton component2 = child.GetComponent(); + component2.normalSprite = "thum" + (i + 1).ToString("D3") + "-0"; + component2.hoverSprite = "thum" + (i + 1).ToString("D3") + "-1"; + component2.pressedSprite = "thum" + (i + 1).ToString("D3") + "-2"; + component.spriteName = "thum" + (i + 1).ToString("D3") + "-0"; + } + else + { + child.gameObject.SetActive(value: false); + } + } + ReturnButton.GetComponent().Prepare(this, 0); + } + + private void Start() + { + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.UI.ChapterJump/ChapterJumpButton.cs b/Assets.Scripts.UI.ChapterJump/ChapterJumpButton.cs new file mode 100644 index 00000000..c1950a09 --- /dev/null +++ b/Assets.Scripts.UI.ChapterJump/ChapterJumpButton.cs @@ -0,0 +1,78 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.UI.ChapterJump +{ + public class ChapterJumpButton : MonoBehaviour + { + public Material normalMaterial; + + public Material hoverMaterial; + + public MeshRenderer TextMesh; + + public string English; + + public string Japanese; + + public int ChapterNumber; + + public string BlockName; + + private bool isActive = true; + + public void Disable() + { + isActive = false; + TextMesh.material = normalMaterial; + } + + private void OnClick() + { + if (isActive && UICamera.currentTouchID == -1 && GameSystem.Instance.GameState == GameState.ChapterJumpScreen) + { + StateChapterJump stateChapterJump = GameSystem.Instance.GetStateObject() as StateChapterJump; + if (stateChapterJump != null) + { + stateChapterJump.RequestLeave(); + if (!(base.name == "Return")) + { + BurikoScriptSystem.Instance.JumpToBlock(BlockName); + } + } + } + } + + private void OnHover(bool isOver) + { + if (isActive) + { + if (isOver && GameSystem.Instance.GameState == GameState.ChapterJumpScreen) + { + TextMesh.material = hoverMaterial; + } + else + { + TextMesh.material = normalMaterial; + } + } + } + + private void Start() + { + TextMeshPro component = GetComponent(); + component.text = ((!GameSystem.Instance.UseEnglishText) ? Japanese : English); + if (!(base.name == "Return") && !BurikoMemory.Instance.GetGlobalFlag("GFlag_GameClear").BoolValue() && BurikoMemory.Instance.GetGlobalFlag("GOnikakushiDay").IntValue() < ChapterNumber) + { + base.gameObject.SetActive(value: false); + } + } + + private void LateUpdate() + { + } + } +} diff --git a/Assets.Scripts.UI.ChapterJump/ChapterJumpManager.cs b/Assets.Scripts.UI.ChapterJump/ChapterJumpManager.cs new file mode 100644 index 00000000..04f6ce4c --- /dev/null +++ b/Assets.Scripts.UI.ChapterJump/ChapterJumpManager.cs @@ -0,0 +1,55 @@ +using Assets.Scripts.Core.Buriko; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.ChapterJump +{ + public class ChapterJumpManager : MonoBehaviour + { + public UIPanel Panel; + + public Material TextMaterial; + + public List JumpButtons; + + public bool isActive = true; + + public void Show() + { + LeanTween.value(base.gameObject, SetFade, 0f, 1f, 0.8f); + } + + public void Hide(Action onFinish) + { + Debug.Log("Hide ChapterJumpScreen"); + isActive = false; + LTDescr lTDescr = LeanTween.value(base.gameObject, SetFade, 1f, 0f, 0.8f); + lTDescr.onComplete = onFinish; + LTDescr lTDescr2 = lTDescr; + lTDescr2.onComplete = (Action)Delegate.Combine(lTDescr2.onComplete, (Action)delegate + { + UnityEngine.Object.Destroy(base.gameObject); + }); + JumpButtons.ForEach(delegate(ChapterJumpButton a) + { + a.Disable(); + }); + } + + private void SetFade(float f) + { + Panel.alpha = f; + TextMaterial.SetColor("_FaceColor", new Color(1f, 1f, 1f, f)); + TextMaterial.SetColor("_UnderlayColor", new Color(0f, 0f, 0f, 0.8f * f)); + } + + public void Start() + { + if (base.name == "CastReview" && !BurikoMemory.Instance.GetGlobalFlag("GFlag_GameClear").BoolValue()) + { + base.gameObject.SetActive(value: false); + } + } + } +} diff --git a/Assets.Scripts.UI.ChapterPreview/ChapterPreviewButton.cs b/Assets.Scripts.UI.ChapterPreview/ChapterPreviewButton.cs new file mode 100644 index 00000000..32833761 --- /dev/null +++ b/Assets.Scripts.UI.ChapterPreview/ChapterPreviewButton.cs @@ -0,0 +1,37 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using UnityEngine; + +namespace Assets.Scripts.UI.ChapterPreview +{ + internal class ChapterPreviewButton : MonoBehaviour + { + public UIButton Button; + + public void Disable() + { + Button.isEnabled = false; + } + + public void OnClick() + { + if (UICamera.currentTouchID == -1 && GameSystem.Instance.GameState == GameState.ChapterPreview) + { + StateChapterPreview stateChapterPreview = GameSystem.Instance.GetStateObject() as StateChapterPreview; + if (stateChapterPreview != null) + { + if (base.gameObject.name == "StartButton") + { + BurikoScriptSystem.Instance.SetFlag("LOCALWORK_NO_RESULT", 1); + } + else + { + BurikoScriptSystem.Instance.SetFlag("LOCALWORK_NO_RESULT", 0); + } + stateChapterPreview.RequestLeave(); + } + } + } + } +} diff --git a/Assets.Scripts.UI.ChapterPreview/ChapterPreviewManager.cs b/Assets.Scripts.UI.ChapterPreview/ChapterPreviewManager.cs new file mode 100644 index 00000000..40aef4ac --- /dev/null +++ b/Assets.Scripts.UI.ChapterPreview/ChapterPreviewManager.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.ChapterPreview +{ + internal class ChapterPreviewManager : MonoBehaviour + { + public UIPanel Panel; + + public List ChapterPreviewButtons; + + public void Show() + { + Panel.alpha = 0f; + LeanTween.value(base.gameObject, delegate(float f) + { + Panel.alpha = f; + }, 0f, 1f, 0.8f); + } + + public void Hide(Action onFinish) + { + LTDescr lTDescr = LeanTween.value(base.gameObject, delegate(float f) + { + Panel.alpha = f; + }, 1f, 0f, 0.8f); + LTDescr lTDescr2 = lTDescr; + lTDescr2.onComplete = (Action)Delegate.Combine(lTDescr2.onComplete, (Action)delegate + { + UnityEngine.Object.Destroy(base.gameObject); + }); + onFinish?.Invoke(); + ChapterPreviewButtons.ForEach(delegate(ChapterPreviewButton a) + { + a.Disable(); + }); + } + } +} diff --git a/Assets.Scripts.UI.ChapterScreen/ChapterButton.cs b/Assets.Scripts.UI.ChapterScreen/ChapterButton.cs new file mode 100644 index 00000000..12105935 --- /dev/null +++ b/Assets.Scripts.UI.ChapterScreen/ChapterButton.cs @@ -0,0 +1,84 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using UnityEngine; + +namespace Assets.Scripts.UI.ChapterScreen +{ + public class ChapterButton : MonoBehaviour + { + public Material normalMaterial; + + public Material hoverMaterial; + + public MeshRenderer TextMesh; + + private UIButton button; + + private bool isActive = true; + + public void Disable() + { + isActive = false; + TextMesh.material = normalMaterial; + } + + private void OnClick() + { + if (isActive && UICamera.currentTouchID == -1 && GameSystem.Instance.GameState == GameState.ChapterScreen) + { + StateChapterScreen stateChapterScreen = GameSystem.Instance.GetStateObject() as StateChapterScreen; + if (stateChapterScreen != null) + { + switch (base.name) + { + case "NewTips": + stateChapterScreen.RequestLeave(); + BurikoMemory.Instance.SetFlag("TipsMode", 4); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 1); + break; + case "ViewAllTips": + stateChapterScreen.RequestLeave(); + BurikoMemory.Instance.SetFlag("TipsMode", 3); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 1); + break; + case "SaveLoad": + GameSystem.Instance.PushStateObject(new StateSaveLoad(restoreUI: false)); + break; + case "Continue": + stateChapterScreen.RequestLeave(); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 0); + AudioController.Instance.ClearTempAudio(); + break; + } + } + } + } + + private void OnHover(bool isOver) + { + if (isActive) + { + if (isOver && GameSystem.Instance.GameState == GameState.ChapterScreen) + { + TextMesh.material = hoverMaterial; + } + else + { + TextMesh.material = normalMaterial; + } + } + } + + private void Awake() + { + button = GetComponent(); + } + + private void LateUpdate() + { + button.isEnabled = (GameSystem.Instance.GameState == GameState.ChapterScreen); + } + } +} diff --git a/Assets.Scripts.UI.ChapterScreen/ChapterScreen.cs b/Assets.Scripts.UI.ChapterScreen/ChapterScreen.cs new file mode 100644 index 00000000..b98753a4 --- /dev/null +++ b/Assets.Scripts.UI.ChapterScreen/ChapterScreen.cs @@ -0,0 +1,57 @@ +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.UI.Tips; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.ChapterScreen +{ + public class ChapterScreen : MonoBehaviour + { + public UIPanel Panel; + + public Material TextMaterial; + + public List ChapterButtons; + + public bool isActive = true; + + public void Show() + { + LeanTween.value(base.gameObject, SetFade, 0f, 1f, 0.8f); + TipsManager.ReturnPage = 0; + } + + public void Hide(Action onFinish) + { + Debug.Log("Hide ChapterScreen"); + isActive = false; + LTDescr lTDescr = LeanTween.value(base.gameObject, SetFade, 1f, 0f, 0.8f); + lTDescr.onComplete = onFinish; + LTDescr lTDescr2 = lTDescr; + lTDescr2.onComplete = (Action)Delegate.Combine(lTDescr2.onComplete, (Action)delegate + { + UnityEngine.Object.Destroy(base.gameObject); + }); + ChapterButtons.ForEach(delegate(ChapterButton a) + { + a.Disable(); + }); + } + + private void SetFade(float f) + { + Panel.alpha = f; + TextMaterial.SetColor("_FaceColor", new Color(1f, 1f, 1f, f)); + TextMaterial.SetColor("_UnderlayColor", new Color(0f, 0f, 0f, 0.8f * f)); + } + + public void Start() + { + if (base.name == "CastReview" && !BurikoMemory.Instance.GetGlobalFlag("GFlag_GameClear").BoolValue()) + { + base.gameObject.SetActive(value: false); + } + } + } +} diff --git a/Assets.Scripts.UI.Choice/ChoiceButton.cs b/Assets.Scripts.UI.Choice/ChoiceButton.cs new file mode 100644 index 00000000..f5ff79f9 --- /dev/null +++ b/Assets.Scripts.UI.Choice/ChoiceButton.cs @@ -0,0 +1,76 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using UnityEngine; + +namespace Assets.Scripts.UI.Choice +{ + public class ChoiceButton : MonoBehaviour + { + public delegate void ClickCallback(); + + public UILabel ButtonText; + + public UITweener AlphaTweener; + + public UITweener ColorTweener; + + private float fadeInTime = 0.5f; + + private ClickCallback clickCallback; + + private bool isEnabled = true; + + private void OnClick() + { + if (GameSystem.Instance.GameState == GameState.ChoiceScreen && !(fadeInTime > 0f) && isEnabled && UICamera.currentTouchID == -1) + { + if (clickCallback != null) + { + clickCallback(); + } + AudioController.Instance.PlaySystemSound("sysse02.ogg"); + } + } + + private void OnHover(bool ishover) + { + if (GameSystem.Instance.GameState == GameState.ChoiceScreen) + { + if (ishover) + { + ColorTweener.PlayForward(); + } + else + { + ColorTweener.PlayReverse(); + } + } + } + + public void ChangeText(string newtxt) + { + ButtonText.text = newtxt; + } + + public void DisableButton() + { + isEnabled = false; + AlphaTweener.PlayReverse(); + } + + public void SetCallback(ChoiceController controller, ClickCallback callback) + { + clickCallback = callback; + } + + private void Start() + { + AlphaTweener.PlayForward(); + } + + private void Update() + { + fadeInTime -= Time.deltaTime; + } + } +} diff --git a/Assets.Scripts.UI.Choice/ChoiceController.cs b/Assets.Scripts.UI.Choice/ChoiceController.cs new file mode 100644 index 00000000..ce560b01 --- /dev/null +++ b/Assets.Scripts.UI.Choice/ChoiceController.cs @@ -0,0 +1,63 @@ +using Assets.Scripts.Core; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.Choice +{ + public class ChoiceController + { + private List options = new List(); + + public void Destroy() + { + foreach (ChoiceButton option in options) + { + UnityEngine.Object.Destroy(option.gameObject); + } + } + + private void FinishChoice() + { + foreach (ChoiceButton option in options) + { + option.DisableButton(); + } + GameSystem.Instance.LeaveChoices(); + } + + public void Create(List optstrings, int count) + { + GameObject gameObject = GameObject.FindGameObjectWithTag("PrimaryUIPanel"); + int num = Mathf.RoundToInt(120f / (float)(count - 1)); + int num2 = 0; + while (true) + { + if (num2 >= count) + { + return; + } + int id = num2; + GameObject gameObject2 = UnityEngine.Object.Instantiate(Resources.Load("ChoiceButton")) as GameObject; + if (gameObject2 == null) + { + break; + } + gameObject2.transform.parent = gameObject.transform; + gameObject2.transform.localScale = Vector3.one; + gameObject2.transform.localPosition = new Vector3(0f, (float)(170 - num * num2), 0f); + ChoiceButton component = gameObject2.GetComponent(); + component.ChangeText(optstrings[num2]); + component.SetCallback(this, delegate + { + GameSystem.Instance.ScriptSystem.SetFlag("LOCALWORK_NO_RESULT", id); + Debug.Log("ID: " + id); + FinishChoice(); + }); + options.Add(gameObject2.GetComponent()); + num2++; + } + throw new Exception("Failed to instantiate ChoiceButton!"); + } + } +} diff --git a/Assets.Scripts.UI.Config/ArrowButton.cs b/Assets.Scripts.UI.Config/ArrowButton.cs new file mode 100644 index 00000000..8e4c28f8 --- /dev/null +++ b/Assets.Scripts.UI.Config/ArrowButton.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + public class ArrowButton : MonoBehaviour + { + public ConfigSlider Slider; + + public float StepChange; + + private void OnClick() + { + if (UICamera.currentTouchID == -1) + { + Slider.Changestep(StepChange); + } + } + + private void OnHover(bool ishover) + { + } + + private void Start() + { + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.UI.Config/ButtonRefresher.cs b/Assets.Scripts.UI.Config/ButtonRefresher.cs new file mode 100644 index 00000000..46424d95 --- /dev/null +++ b/Assets.Scripts.UI.Config/ButtonRefresher.cs @@ -0,0 +1,55 @@ +using Assets.Scripts.Core; +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + internal class ButtonRefresher : MonoBehaviour + { + public string EnglishNormal; + + public string EnglishHover; + + public string EnglishDown; + + public string EnglishDisabled; + + public string JapaneseNormal; + + public string JapaneseHover; + + public string JapaneseDown; + + public string JapaneseDisabled; + + private UIButton button; + + private bool language; + + public void UpdateImage() + { + if (button == null) + { + button = GetComponent(); + } + button.normalSprite = ((!language) ? JapaneseNormal : EnglishNormal); + button.hoverSprite = ((!language) ? JapaneseHover : EnglishHover); + button.pressedSprite = ((!language) ? JapaneseDown : EnglishDown); + button.disabledSprite = ((!language) ? JapaneseDisabled : EnglishDisabled); + } + + public void Start() + { + language = GameSystem.Instance.UseEnglishText; + UpdateImage(); + } + + public void Update() + { + if (language != GameSystem.Instance.UseEnglishText) + { + language = GameSystem.Instance.UseEnglishText; + UpdateImage(); + } + } + } +} diff --git a/Assets.Scripts.UI.Config/ConfigButtonType.cs b/Assets.Scripts.UI.Config/ConfigButtonType.cs new file mode 100644 index 00000000..6c28217a --- /dev/null +++ b/Assets.Scripts.UI.Config/ConfigButtonType.cs @@ -0,0 +1,18 @@ +namespace Assets.Scripts.UI.Config +{ + public enum ConfigButtonType + { + SlowSkip, + SkipUnread, + UsePrompts, + ClickDuringAuto, + RightClickMode, + FullscreenMode, + ClickToCutVoice, + UseSystemSound, + Other, + ArtStyle, + AutoHideUI, + Language + } +} diff --git a/Assets.Scripts.UI.Config/ConfigManager.cs b/Assets.Scripts.UI.Config/ConfigManager.cs new file mode 100644 index 00000000..0518f75a --- /dev/null +++ b/Assets.Scripts.UI.Config/ConfigManager.cs @@ -0,0 +1,81 @@ +using Assets.Scripts.Core; +using System.Collections; +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + public class ConfigManager : MonoBehaviour + { + public delegate void LeaveConfigDelegate(); + + public GameObject Panel; + + public Material TextMaterial; + + private int screennum; + + private bool needShowMessageWindow; + + private UIPanel panel; + + private IEnumerator LeaveScreen(LeaveConfigDelegate callback) + { + panel = Panel.GetComponent(); + LeanTween.value(Panel, UpdateAlpha, 1f, 0f, 0.3f); + if (needShowMessageWindow) + { + GameSystem.Instance.MainUIController.FadeIn(0.3f); + GameSystem.Instance.SceneController.RevealFace(0.3f); + GameSystem.Instance.ExecuteActions(); + } + yield return (object)new WaitForSeconds(0.5f); + callback?.Invoke(); + Object.Destroy(base.gameObject); + } + + private void UpdateAlpha(float f) + { + panel.alpha = f; + TextMaterial.SetColor("_FaceColor", new Color(1f, 1f, 1f, f)); + TextMaterial.SetColor("_OutlineColor", new Color(0f, 0f, 0f, f)); + } + + public void Leave(LeaveConfigDelegate callback) + { + StartCoroutine(LeaveScreen(callback)); + } + + private IEnumerator DoOpen(int offscreen) + { + Panel.SetActive(value: true); + panel = Panel.GetComponent(); + UpdateAlpha(0f); + yield return (object)null; + yield return (object)null; + LeanTween.value(Panel, UpdateAlpha, 0f, 1f, 0.3f); + GameSystem.Instance.MainUIController.FadeOut(0.3f, isBlocking: false); + GameSystem.Instance.SceneController.HideFace(0.3f); + GameSystem.Instance.ExecuteActions(); + } + + public void Open(int screen, bool msgWindow) + { + needShowMessageWindow = msgWindow; + screennum = screen; + int offscreen = 0; + if (screennum == 0) + { + offscreen = 1; + } + StartCoroutine(DoOpen(offscreen)); + } + + private void Start() + { + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.UI.Config/ConfigSlider.cs b/Assets.Scripts.UI.Config/ConfigSlider.cs new file mode 100644 index 00000000..2bbee400 --- /dev/null +++ b/Assets.Scripts.UI.Config/ConfigSlider.cs @@ -0,0 +1,101 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Buriko; +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + public class ConfigSlider : MonoBehaviour + { + private UISlider slider; + + private float laststep = 0.5f; + + private bool isSet; + + public void Changestep(float change) + { + slider.value = Mathf.Clamp01(slider.value + change); + } + + private void Set() + { + if (slider == null) + { + slider = GetComponent(); + } + int num = 0; + switch (base.name) + { + case "0-TextSpeed": + num = GameSystem.Instance.TextController.TextSpeed; + break; + case "1-AutoSpeed": + num = GameSystem.Instance.TextController.AutoSpeed; + break; + case "2-AutoPageSpeed": + num = GameSystem.Instance.TextController.AutoPageSpeed; + break; + case "3-WindowOpacity": + num = (int)(GameSystem.Instance.MessageWindowOpacity * 100f); + break; + case "4-BGMVolume": + num = (int)(GameSystem.Instance.AudioController.BGMVolume * 100f); + break; + case "5-SEVolume": + num = (int)(GameSystem.Instance.AudioController.SoundVolume * 100f); + break; + } + slider.value = (float)num / 100f; + laststep = slider.value; + isSet = true; + } + + private void Update() + { + if (slider == null) + { + slider = GetComponent(); + } + if (!isSet) + { + Set(); + } + if (!Mathf.Approximately(laststep, slider.value)) + { + laststep = slider.value; + int num = (int)(100f * laststep); + switch (base.name) + { + case "0-TextSpeed": + GameSystem.Instance.TextController.TextSpeed = num; + BurikoMemory.Instance.SetGlobalFlag("GMessageSpeed", num); + break; + case "1-AutoSpeed": + GameSystem.Instance.TextController.AutoSpeed = num; + BurikoMemory.Instance.SetGlobalFlag("GAutoSpeed", num); + break; + case "2-AutoPageSpeed": + GameSystem.Instance.TextController.AutoPageSpeed = num; + BurikoMemory.Instance.SetGlobalFlag("GAutoAdvSpeed", num); + break; + case "3-WindowOpacity": + GameSystem.Instance.MessageWindowOpacity = laststep; + GameSystem.Instance.MainUIController.SetWindowOpacity(laststep); + BurikoMemory.Instance.SetGlobalFlag("GWindowOpacity", num); + break; + case "4-BGMVolume": + GameSystem.Instance.AudioController.BGMVolume = laststep; + GameSystem.Instance.AudioController.RefreshLayerVolumes(); + BurikoMemory.Instance.SetGlobalFlag("GBGMVolume", num); + break; + case "5-SEVolume": + GameSystem.Instance.AudioController.SoundVolume = laststep; + GameSystem.Instance.AudioController.SystemVolume = laststep; + GameSystem.Instance.AudioController.RefreshLayerVolumes(); + BurikoMemory.Instance.SetGlobalFlag("GSEVolume", num); + break; + } + } + } + } +} diff --git a/Assets.Scripts.UI.Config/ImageRefresher.cs b/Assets.Scripts.UI.Config/ImageRefresher.cs new file mode 100644 index 00000000..e939fd94 --- /dev/null +++ b/Assets.Scripts.UI.Config/ImageRefresher.cs @@ -0,0 +1,40 @@ +using Assets.Scripts.Core; +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + internal class ImageRefresher : MonoBehaviour + { + public Texture2D English; + + public Texture2D Japanese; + + private UITexture background; + + private bool language; + + public void UpdateImage() + { + if (background == null) + { + background = GetComponent(); + } + background.mainTexture = ((!language) ? Japanese : English); + } + + public void Start() + { + language = GameSystem.Instance.UseEnglishText; + UpdateImage(); + } + + public void Update() + { + if (language != GameSystem.Instance.UseEnglishText) + { + language = GameSystem.Instance.UseEnglishText; + UpdateImage(); + } + } + } +} diff --git a/Assets.Scripts.UI.Config/ScreenSwitcherButton.cs b/Assets.Scripts.UI.Config/ScreenSwitcherButton.cs new file mode 100644 index 00000000..1dc91632 --- /dev/null +++ b/Assets.Scripts.UI.Config/ScreenSwitcherButton.cs @@ -0,0 +1,83 @@ +using Assets.Scripts.Core; +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + public class ScreenSwitcherButton : MonoBehaviour + { + public int Width; + + public bool IsFullscreen; + + private UIButton button; + + private void OnClick() + { + if (IsFullscreen) + { + GameSystem.Instance.GoFullscreen(); + } + else + { + switch (Width) + { + case 640: + { + if (Application.platform == RuntimePlatform.OSXPlayer) + { + Screen.fullScreen = false; + } + int num2 = Mathf.RoundToInt(480f * GameSystem.Instance.AspectRatio); + Screen.SetResolution(num2, 480, fullscreen: false); + PlayerPrefs.SetInt("width", num2); + PlayerPrefs.SetInt("height", 480); + break; + } + case 800: + { + if (Application.platform == RuntimePlatform.OSXPlayer) + { + Screen.fullScreen = false; + } + int num3 = Mathf.RoundToInt(600f * GameSystem.Instance.AspectRatio); + Screen.SetResolution(num3, 600, fullscreen: false); + PlayerPrefs.SetInt("width", num3); + PlayerPrefs.SetInt("height", 600); + break; + } + case 1024: + { + if (Application.platform == RuntimePlatform.OSXPlayer) + { + Screen.fullScreen = false; + } + int num = Mathf.RoundToInt(768f * GameSystem.Instance.AspectRatio); + Screen.SetResolution(num, 768, fullscreen: false); + PlayerPrefs.SetInt("width", num); + PlayerPrefs.SetInt("height", 768); + break; + } + } + } + } + + private bool ShouldBeDown() + { + if (IsFullscreen) + { + return Screen.fullScreen; + } + return Width == Screen.width; + } + + private void Start() + { + button = GetComponent(); + } + + private void FixedUpdate() + { + button.isEnabled = !ShouldBeDown(); + } + } +} diff --git a/Assets.Scripts.UI.Config/SwitchButton.cs b/Assets.Scripts.UI.Config/SwitchButton.cs new file mode 100644 index 00000000..b4551942 --- /dev/null +++ b/Assets.Scripts.UI.Config/SwitchButton.cs @@ -0,0 +1,196 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Buriko; +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + public class SwitchButton : MonoBehaviour + { + public SwitchButtonObj Obj1; + + public SwitchButtonObj Obj2; + + public ConfigButtonType Type; + + public bool HideInactive; + + public bool IsVoiceSwitch; + + public string GlobalValue = string.Empty; + + private bool isReady; + + private void UpdateButtonValues() + { + bool flag = false; + switch (Type) + { + case ConfigButtonType.SlowSkip: + flag = GameSystem.Instance.SkipModeDelay; + break; + case ConfigButtonType.SkipUnread: + flag = GameSystem.Instance.SkipUnreadMessages; + break; + case ConfigButtonType.ClickDuringAuto: + flag = GameSystem.Instance.ClickDuringAuto; + break; + case ConfigButtonType.UsePrompts: + flag = GameSystem.Instance.UsePrompts; + break; + case ConfigButtonType.RightClickMode: + flag = GameSystem.Instance.RightClickMenu; + break; + case ConfigButtonType.FullscreenMode: + flag = Screen.fullScreen; + break; + case ConfigButtonType.ClickToCutVoice: + flag = GameSystem.Instance.StopVoiceOnClick; + break; + case ConfigButtonType.UseSystemSound: + flag = GameSystem.Instance.UseSystemSounds; + break; + case ConfigButtonType.ArtStyle: + flag = AssetManager.Instance.UseNewArt; + break; + case ConfigButtonType.Language: + flag = GameSystem.Instance.UseEnglishText; + break; + case ConfigButtonType.AutoHideUI: + flag = BurikoMemory.Instance.GetGlobalFlag("GHideButtons").BoolValue(); + break; + } + if (IsVoiceSwitch) + { + flag = BurikoMemory.Instance.GetGlobalFlag(GlobalValue).BoolValue(); + } + if (flag) + { + if (HideInactive) + { + Obj1.gameObject.SetActive(value: false); + Obj2.gameObject.SetActive(value: true); + } + else + { + Obj1.Button.isEnabled = false; + Obj2.Button.isEnabled = true; + } + } + else if (HideInactive) + { + Obj1.gameObject.SetActive(value: true); + Obj2.gameObject.SetActive(value: false); + } + else + { + Obj1.Button.isEnabled = true; + Obj2.Button.isEnabled = false; + } + } + + public void Click() + { + int val = 0; + switch (Type) + { + case ConfigButtonType.SlowSkip: + GameSystem.Instance.SkipModeDelay = !GameSystem.Instance.SkipModeDelay; + if (GameSystem.Instance.SkipModeDelay) + { + val = 1; + } + break; + case ConfigButtonType.SkipUnread: + GameSystem.Instance.SkipUnreadMessages = !GameSystem.Instance.SkipUnreadMessages; + if (GameSystem.Instance.SkipUnreadMessages) + { + val = 1; + } + break; + case ConfigButtonType.ClickDuringAuto: + GameSystem.Instance.ClickDuringAuto = !GameSystem.Instance.ClickDuringAuto; + if (GameSystem.Instance.ClickDuringAuto) + { + val = 1; + } + break; + case ConfigButtonType.UsePrompts: + GameSystem.Instance.UsePrompts = !GameSystem.Instance.UsePrompts; + if (GameSystem.Instance.UsePrompts) + { + val = 1; + } + break; + case ConfigButtonType.RightClickMode: + GameSystem.Instance.RightClickMenu = !GameSystem.Instance.RightClickMenu; + if (GameSystem.Instance.RightClickMenu) + { + val = 1; + } + break; + case ConfigButtonType.FullscreenMode: + GameSystem.Instance.GoFullscreen(); + break; + case ConfigButtonType.ClickToCutVoice: + GameSystem.Instance.StopVoiceOnClick = !GameSystem.Instance.StopVoiceOnClick; + if (GameSystem.Instance.StopVoiceOnClick) + { + val = 1; + } + break; + case ConfigButtonType.UseSystemSound: + GameSystem.Instance.UseSystemSounds = !GameSystem.Instance.UseSystemSounds; + if (GameSystem.Instance.UseSystemSounds) + { + val = 1; + } + break; + case ConfigButtonType.Language: + GameSystem.Instance.UseEnglishText = !GameSystem.Instance.UseEnglishText; + if (GameSystem.Instance.UseEnglishText) + { + val = 1; + } + GameSystem.Instance.TextController.SwapLanguages(); + break; + case ConfigButtonType.ArtStyle: + AssetManager.Instance.UseNewArt = !AssetManager.Instance.UseNewArt; + BurikoMemory.Instance.SetGlobalFlag("GArtStyle", AssetManager.Instance.UseNewArt ? 1 : 0); + GameSystem.Instance.SceneController.ReloadAllImages(); + break; + case ConfigButtonType.AutoHideUI: + { + bool flag = BurikoMemory.Instance.GetGlobalFlag("GHideButtons").BoolValue(); + BurikoMemory.Instance.SetGlobalFlag("GHideButtons", (!flag) ? 1 : 0); + break; + } + } + if (IsVoiceSwitch) + { + val = ((BurikoMemory.Instance.GetGlobalFlag(GlobalValue).IntValue() == 0) ? 1 : 0); + } + if (GlobalValue != string.Empty) + { + BurikoMemory.Instance.SetGlobalFlag(GlobalValue, val); + } + UpdateButtonValues(); + } + + private void Prepare() + { + Obj1.RegisterSwitchController(this); + Obj2.RegisterSwitchController(this); + UpdateButtonValues(); + isReady = true; + } + + private void Update() + { + if (!isReady) + { + Prepare(); + } + } + } +} diff --git a/Assets.Scripts.UI.Config/SwitchButtonObj.cs b/Assets.Scripts.UI.Config/SwitchButtonObj.cs new file mode 100644 index 00000000..53021de2 --- /dev/null +++ b/Assets.Scripts.UI.Config/SwitchButtonObj.cs @@ -0,0 +1,60 @@ +using Assets.Scripts.Core.Audio; +using UnityEngine; + +namespace Assets.Scripts.UI.Config +{ + public class SwitchButtonObj : MonoBehaviour + { + public UISprite Sprite; + + public UIButton Button; + + private float cooldown; + + private SwitchButton controller; + + private void OnClick() + { + if (!(cooldown > 0f) && UICamera.currentTouchID == -1) + { + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + controller.Click(); + cooldown = 0.2f; + } + } + + private void OnHover(bool ishover) + { + if (!(cooldown > 0f)) + { + } + } + + public void RegisterSwitchController(SwitchButton c) + { + controller = c; + } + + public void UpdateValue(bool isOn) + { + if (Sprite == null) + { + Start(); + } + } + + private void Start() + { + Sprite = GetComponent(); + Button = GetComponent(); + } + + private void Update() + { + if (cooldown > 0f) + { + cooldown -= Time.deltaTime; + } + } + } +} diff --git a/Assets.Scripts.UI.Extra/ExtraButton.cs b/Assets.Scripts.UI.Extra/ExtraButton.cs new file mode 100644 index 00000000..e4a951a4 --- /dev/null +++ b/Assets.Scripts.UI.Extra/ExtraButton.cs @@ -0,0 +1,93 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using UnityEngine; + +namespace Assets.Scripts.UI.Extra +{ + public class ExtraButton : MonoBehaviour + { + public Material normalMaterial; + + public Material hoverMaterial; + + public MeshRenderer TextMesh; + + private UIButton button; + + private bool isActive = true; + + public void Disable() + { + isActive = false; + TextMesh.material = normalMaterial; + } + + private void OnClick() + { + if (isActive && UICamera.currentTouchID == -1 && GameSystem.Instance.GameState == GameState.ExtraScreen) + { + StateExtraScreen stateExtraScreen = GameSystem.Instance.GetStateObject() as StateExtraScreen; + if (stateExtraScreen != null) + { + switch (base.name) + { + case "CastReview": + stateExtraScreen.RequestLeave(); + BurikoScriptSystem.Instance.CallScript("omake_01"); + break; + case "ChapterJump": + stateExtraScreen.RequestLeave(); + GameSystem.Instance.AddWait(new Wait(0.5f, WaitTypes.WaitForTime, delegate + { + GameSystem.Instance.PushStateObject(new StateChapterJump()); + })); + break; + case "ViewTips": + stateExtraScreen.RequestLeave(); + BurikoMemory.Instance.SetFlag("TipsMode", 5); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 1); + break; + case "Continue": + stateExtraScreen.RequestLeave(); + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 0); + AudioController.Instance.ClearTempAudio(); + AudioController.Instance.FadeOutBGM(0, 1000, waitForFade: false); + BurikoScriptSystem.Instance.JumpToBlock("Title"); + break; + } + } + } + } + + private void OnHover(bool isOver) + { + if (isActive) + { + if (isOver && GameSystem.Instance.GameState == GameState.ExtraScreen) + { + TextMesh.material = hoverMaterial; + } + else + { + TextMesh.material = normalMaterial; + } + } + } + + private void Awake() + { + button = GetComponent(); + if (base.name == "CastReview" && !BurikoMemory.Instance.GetGlobalFlag("GFlag_GameClear").BoolValue()) + { + base.gameObject.SetActive(value: false); + } + } + + private void LateUpdate() + { + button.isEnabled = (GameSystem.Instance.GameState == GameState.ExtraScreen); + } + } +} diff --git a/Assets.Scripts.UI.Extra/ExtraManager.cs b/Assets.Scripts.UI.Extra/ExtraManager.cs new file mode 100644 index 00000000..b8d69350 --- /dev/null +++ b/Assets.Scripts.UI.Extra/ExtraManager.cs @@ -0,0 +1,58 @@ +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.UI.Tips; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.Extra +{ + public class ExtraManager : MonoBehaviour + { + public UIPanel Panel; + + public Material TextMaterial; + + public UIGrid Grid; + + public List ExtraButtons; + + public bool isActive = true; + + public void Show() + { + if (!BurikoMemory.Instance.GetGlobalFlag("GFlag_GameClear").BoolValue()) + { + for (int i = 0; i < ExtraButtons.Count; i++) + { + ExtraButtons[i].transform.localPosition += new Vector3(0f, 30f, 0f); + } + } + LeanTween.value(base.gameObject, SetFade, 0f, 1f, 0.8f); + TipsManager.ReturnPage = 0; + } + + public void Hide(Action onFinish) + { + Debug.Log("Hide ExtraScreen"); + isActive = false; + LTDescr lTDescr = LeanTween.value(base.gameObject, SetFade, 1f, 0f, 0.8f); + lTDescr.onComplete = onFinish; + LTDescr lTDescr2 = lTDescr; + lTDescr2.onComplete = (Action)Delegate.Combine(lTDescr2.onComplete, (Action)delegate + { + UnityEngine.Object.Destroy(base.gameObject); + }); + ExtraButtons.ForEach(delegate(ExtraButton a) + { + a.Disable(); + }); + } + + private void SetFade(float f) + { + Panel.alpha = f; + TextMaterial.SetColor("_FaceColor", new Color(1f, 1f, 1f, f)); + TextMaterial.SetColor("_UnderlayColor", new Color(0f, 0f, 0f, 0.8f * f)); + } + } +} diff --git a/Assets.Scripts.UI.Menu/MenuUIButton.cs b/Assets.Scripts.UI.Menu/MenuUIButton.cs new file mode 100644 index 00000000..69b41a56 --- /dev/null +++ b/Assets.Scripts.UI.Menu/MenuUIButton.cs @@ -0,0 +1,94 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using Assets.Scripts.UI.Prompt; +using UnityEngine; + +namespace Assets.Scripts.UI.Menu +{ + internal class MenuUIButton : MonoBehaviour + { + private float time = 0.45f; + + public bool isEnabled = true; + + private GameSystem gameSystem; + + private void OnClick() + { + if (gameSystem == null) + { + gameSystem = GameSystem.Instance; + } + if (gameSystem.GameState == GameState.RightClickMenu && !(time > 0f) && UICamera.currentTouchID == -1 && isEnabled) + { + switch (base.name) + { + case "0-SaveLoad": + gameSystem.LeaveMenu(delegate + { + gameSystem.PushStateObject(new StateSaveLoad(restoreUI: true)); + }, doPop: true); + break; + case "1-Config": + gameSystem.LeaveMenu(delegate + { + gameSystem.SwitchToConfig(0, showMessageWindow: true); + }, doPop: true); + break; + case "2-HideWindow": + gameSystem.SwitchToHiddenWindow(); + break; + case "3-MainMenu": + gameSystem.LeaveMenu(null, doPop: false); + gameSystem.PopStateStack(); + GameSystem.Instance.PushStateObject(new StateDialogPrompt(PromptType.DialogTitle, delegate + { + gameSystem.ClearActions(); + gameSystem.ClearAllWaits(); + gameSystem.TextController.ClearText(); + gameSystem.MainUIController.FadeOut(0f, isBlocking: false); + gameSystem.SceneController.HideFace(0f); + gameSystem.MainUIController.HideMessageBox(); + gameSystem.ExecuteActions(); + BurikoScriptSystem.Instance.JumpToScript("flow"); + BurikoScriptSystem.Instance.JumpToBlock("Title"); + gameSystem.AudioController.StopAllAudio(); + BurikoMemory.Instance.ResetScope(); + }, delegate + { + gameSystem.RevealMessageBox(); + })); + break; + case "4-QuitGame": + gameSystem.LeaveMenu(null, doPop: false); + gameSystem.PopStateStack(); + GameSystem.Instance.PushStateObject(new StateDialogPrompt(PromptType.DialogExit, delegate + { + gameSystem.CanExit = true; + Application.Quit(); + }, delegate + { + gameSystem.RevealMessageBox(); + })); + break; + default: + Debug.Log("Button ID not found: " + base.name); + break; + } + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + isEnabled = false; + } + } + + private void OnHover(bool hover) + { + } + + private void Update() + { + time -= Time.deltaTime; + } + } +} diff --git a/Assets.Scripts.UI.Prompt/DialogCallback.cs b/Assets.Scripts.UI.Prompt/DialogCallback.cs new file mode 100644 index 00000000..9fb14087 --- /dev/null +++ b/Assets.Scripts.UI.Prompt/DialogCallback.cs @@ -0,0 +1,4 @@ +namespace Assets.Scripts.UI.Prompt +{ + public delegate void DialogCallback(); +} diff --git a/Assets.Scripts.UI.Prompt/PromptButton.cs b/Assets.Scripts.UI.Prompt/PromptButton.cs new file mode 100644 index 00000000..51a62805 --- /dev/null +++ b/Assets.Scripts.UI.Prompt/PromptButton.cs @@ -0,0 +1,61 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using UnityEngine; + +namespace Assets.Scripts.UI.Prompt +{ + public class PromptButton : MonoBehaviour + { + private PromptController promptController; + + private float time = 0.45f; + + public bool isEnabled = true; + + public void ChangeButtonImages(string normal, string hover, string down) + { + UIButton component = GetComponent(); + component.normalSprite = normal; + component.hoverSprite = hover; + component.pressedSprite = down; + } + + private void OnClick() + { + if (isEnabled && GameSystem.Instance.GameState == GameState.DialogPrompt && !(time > 0f) && UICamera.currentTouchID == -1) + { + switch (base.name) + { + case "_Yes": + promptController.Hide(affirmative: true); + break; + case "_No": + promptController.Hide(affirmative: false); + break; + default: + Debug.Log("Button ID not found: " + base.name); + break; + } + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + isEnabled = false; + } + } + + private void OnHover(bool hover) + { + if (isEnabled) + { + } + } + + private void Update() + { + time -= Time.deltaTime; + } + + public void RegisterController(PromptController controller) + { + promptController = controller; + } + } +} diff --git a/Assets.Scripts.UI.Prompt/PromptController.cs b/Assets.Scripts.UI.Prompt/PromptController.cs new file mode 100644 index 00000000..e6dc01bd --- /dev/null +++ b/Assets.Scripts.UI.Prompt/PromptController.cs @@ -0,0 +1,200 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.State; +using System.Collections; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.UI.Prompt +{ + public class PromptController : MonoBehaviour + { + public TextMeshPro TopBox; + + public TextMeshPro BottomBox; + + public UIPanel DialogPanel; + + public UITexture DialogPromptImage; + + public UITexture DialogScreenshot; + + public PromptButton ButtonYes; + + public PromptButton ButtonNo; + + public Material TextMaterial; + + public Texture2D TextureEdit; + + public Texture2D TextureExit; + + public Texture2D TextureLoad; + + public Texture2D TextureSave; + + public Texture2D TextureTitle; + + public Texture2D TextureDelete; + + public Texture2D TextureLanguage; + + public Texture2D TextureEditJapanese; + + public Texture2D TextureExitJapanese; + + public Texture2D TextureLoadJapanese; + + public Texture2D TextureSaveJapanese; + + public Texture2D TextureTitleJapanese; + + public Texture2D TextureDeleteJapanese; + + private DialogCallback yesCallback; + + private DialogCallback noCallback; + + private PromptType pType; + + private IEnumerator LeaveWindow(bool affirmative) + { + ButtonYes.enabled = false; + ButtonNo.enabled = false; + TweenAlpha a = DialogPanel.GetComponent(); + LeanTween.cancel(base.gameObject); + LeanTween.value(base.gameObject, delegate(float f) + { + this.TextMaterial.SetColor("_FaceColor", new Color(0f, 0f, 0f, f)); + }, 1f, 0f, 0.3f); + a.PlayReverse(); + if (!affirmative && noCallback != null) + { + noCallback(); + } + yield return (object)new WaitForSeconds(0.5f); + GameSystem.Instance.PopStateStack(); + if (affirmative && yesCallback != null) + { + yesCallback(); + } + Object.Destroy(base.gameObject); + } + + public void Hide(bool affirmative) + { + StartCoroutine(LeaveWindow(affirmative)); + (GameSystem.Instance.GetStateObject() as StateDialogPrompt)?.DisableInputActions(); + } + + public void SetScreenshotDetails(Texture2D image, string top, string bottom, string bottomjp) + { + Debug.Log("SetScreenshotDetails " + top); + DialogScreenshot.gameObject.SetActive(value: true); + DialogScreenshot.mainTexture = image; + TopBox.gameObject.SetActive(value: true); + BottomBox.gameObject.SetActive(value: true); + TopBox.text = top; + if (GameSystem.Instance.UseEnglishText) + { + BottomBox.text = bottom.Replace("\n", " ").TrimStart(' ', '\n'); + } + else + { + BottomBox.text = bottomjp.Replace("\n", " ").TrimStart(' ', '\n'); + } + } + + public void Open(PromptType type, DialogCallback onYes, DialogCallback onNo) + { + pType = type; + if (!GameSystem.Instance.UseEnglishText) + { + switch (type) + { + case PromptType.DialogEdit: + DialogPromptImage.mainTexture = TextureEditJapanese; + break; + case PromptType.DialogExit: + DialogPromptImage.mainTexture = TextureExitJapanese; + break; + case PromptType.DialogLoad: + DialogPromptImage.mainTexture = TextureLoadJapanese; + break; + case PromptType.DialogSave: + DialogPromptImage.mainTexture = TextureSaveJapanese; + break; + case PromptType.DialogTitle: + DialogPromptImage.mainTexture = TextureTitleJapanese; + break; + case PromptType.DialogDelete: + DialogPromptImage.mainTexture = TextureDeleteJapanese; + break; + case PromptType.DialogLanguage: + DialogPromptImage.mainTexture = TextureLanguage; + break; + } + } + else + { + switch (type) + { + case PromptType.DialogEdit: + DialogPromptImage.mainTexture = TextureEdit; + break; + case PromptType.DialogExit: + DialogPromptImage.mainTexture = TextureExit; + break; + case PromptType.DialogLoad: + DialogPromptImage.mainTexture = TextureLoad; + break; + case PromptType.DialogSave: + DialogPromptImage.mainTexture = TextureSave; + break; + case PromptType.DialogTitle: + DialogPromptImage.mainTexture = TextureTitle; + break; + case PromptType.DialogDelete: + DialogPromptImage.mainTexture = TextureDelete; + break; + case PromptType.DialogLanguage: + DialogPromptImage.mainTexture = TextureLanguage; + break; + } + } + DialogPromptImage.MakePixelPerfect(); + if (type == PromptType.DialogExit || type == PromptType.DialogTitle || type == PromptType.DialogDelete) + { + DialogScreenshot.gameObject.SetActive(value: false); + ButtonYes.transform.localPosition = new Vector3(-56f, -16f, 0f); + ButtonNo.transform.localPosition = new Vector3(56f, -16f, 0f); + } + if (type != 0 && type != PromptType.DialogSave) + { + Object.Destroy(BottomBox.GetComponent()); + } + TopBox.text = string.Empty; + BottomBox.text = string.Empty; + yesCallback = onYes; + noCallback = onNo; + if (type == PromptType.DialogLanguage) + { + DialogScreenshot.gameObject.SetActive(value: false); + ButtonYes.transform.localPosition = new Vector3(-56f, -66f, 0f); + ButtonNo.transform.localPosition = new Vector3(56f, -66f, 0f); + ButtonYes.ChangeButtonImages("btn_lang_normal", "btn_lang_hover", "btn_lang_down"); + ButtonNo.ChangeButtonImages("btn_lang_normal_jp", "btn_lang_hover_jp", "btn_lang_down_jp"); + } + ButtonYes.RegisterController(this); + ButtonNo.RegisterController(this); + } + + private void Start() + { + LeanTween.cancel(base.gameObject); + LeanTween.value(base.gameObject, delegate(float f) + { + TextMaterial.SetColor("_FaceColor", new Color(0f, 0f, 0f, f)); + }, 0f, 1f, 0.2f); + } + } +} diff --git a/Assets.Scripts.UI.Prompt/PromptType.cs b/Assets.Scripts.UI.Prompt/PromptType.cs new file mode 100644 index 00000000..83faea2c --- /dev/null +++ b/Assets.Scripts.UI.Prompt/PromptType.cs @@ -0,0 +1,13 @@ +namespace Assets.Scripts.UI.Prompt +{ + public enum PromptType + { + DialogEdit, + DialogExit, + DialogLoad, + DialogSave, + DialogTitle, + DialogDelete, + DialogLanguage + } +} diff --git a/Assets.Scripts.UI.SaveLoad/SaveLoadButton.cs b/Assets.Scripts.UI.SaveLoad/SaveLoadButton.cs new file mode 100644 index 00000000..2e20ba9b --- /dev/null +++ b/Assets.Scripts.UI.SaveLoad/SaveLoadButton.cs @@ -0,0 +1,166 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using Assets.Scripts.UI.Prompt; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.UI.SaveLoad +{ + public class SaveLoadButton : MonoBehaviour + { + private int slot; + + private float time = 0.45f; + + private bool isEnabled = true; + + private GameSystem gameSystem; + + private SaveLoadManager manager; + + private void OnClick() + { + if (gameSystem == null) + { + gameSystem = GameSystem.Instance; + } + if (gameSystem.GameState == GameState.SaveLoadScreen && !(time > 0f) && UICamera.currentTouchID == -1 && isEnabled) + { + StateSaveLoad state = gameSystem.GetStateObject() as StateSaveLoad; + if (state != null) + { + switch (base.name) + { + case "Save": + case "0-Save": + manager.Save(slot); + break; + case "Load": + case "1-Load": + { + SaveEntry d = BurikoScriptSystem.Instance.GetSaveInfo(slot); + if (d == null) + { + return; + } + StateDialogPrompt state2 = new StateDialogPrompt(PromptType.DialogLoad, delegate + { + state.Leave(delegate + { + StateTitle stateTitle = gameSystem.GetStateObject() as StateTitle; + if (!manager.CanSave()) + { + stateTitle?.RequestLeaveImmediate(); + } + (gameSystem.GetStateObject() as StateChapterScreen)?.RequestLeaveImmediate(); + GameSystem.Instance.ScriptSystem.LoadGame(slot); + }); + }, null); + gameSystem.PushStateObject(state2); + gameSystem.RegisterAction(delegate + { + PromptController promptController = state2.GetPromptController(); + if (!(promptController == null)) + { + string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(d.Path); + Texture2D image = AssetManager.Instance.LoadScreenshot(fileNameWithoutExtension + ".png"); + promptController.SetScreenshotDetails(image, d.Time.ToString("ddd MMM dd, yyyy h:mm tt"), d.Text, d.TextJp); + } + }); + gameSystem.ExecuteActions(); + break; + } + case "2-Edit": + { + SaveEntry d2 = BurikoScriptSystem.Instance.GetSaveInfo(slot); + if (d2 == null) + { + return; + } + SaveLoadManager.EditSlot = slot; + StateDialogPrompt state3 = new StateDialogPrompt(PromptType.DialogEdit, delegate + { + }, null); + gameSystem.PushStateObject(state3); + gameSystem.RegisterAction(delegate + { + PromptController promptController2 = state3.GetPromptController(); + if (!(promptController2 == null)) + { + string fileNameWithoutExtension2 = Path.GetFileNameWithoutExtension(d2.Path); + Texture2D image2 = AssetManager.Instance.LoadScreenshot(fileNameWithoutExtension2 + ".png"); + promptController2.SetScreenshotDetails(image2, d2.Time.ToString("ddd MMM dd, yyyy h:mm tt"), d2.Text, d2.TextJp); + } + }); + gameSystem.ExecuteActions(); + break; + } + case "3-Delete": + { + SaveEntry d3 = BurikoScriptSystem.Instance.GetSaveInfo(slot); + if (d3 == null) + { + return; + } + StateDialogPrompt prompt = new StateDialogPrompt(PromptType.DialogDelete, delegate + { + BurikoScriptSystem.Instance.DeleteSave(slot); + manager.RefreshList(); + }, null); + GameSystem.Instance.PushStateObject(prompt); + GameSystem.Instance.RegisterAction(delegate + { + PromptController promptController3 = prompt.GetPromptController(); + if (!(promptController3 == null)) + { + string fileNameWithoutExtension3 = Path.GetFileNameWithoutExtension(d3.Path); + Texture2D image3 = AssetManager.Instance.LoadScreenshot(fileNameWithoutExtension3 + ".png"); + promptController3.SetScreenshotDetails(image3, d3.Time.ToString("ddd MMM dd, yyyy h:mm tt"), d3.Text, d3.TextJp); + } + }); + break; + } + case "Return": + state.Leave(null); + break; + default: + Debug.LogWarning("Unhandled button action!"); + break; + } + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + time = 0.45f; + } + } + } + + private void OnHover(bool hover) + { + if (gameSystem == null) + { + gameSystem = GameSystem.Instance; + } + if (gameSystem.GameState == GameState.SaveLoadScreen && hover && time < 0f && isEnabled) + { + AudioController.Instance.PlaySystemSound("sysse01.ogg"); + } + } + + public void Prepare(int slotnum, SaveLoadManager mg) + { + manager = mg; + gameSystem = GameSystem.Instance; + slot = slotnum; + } + + private void Update() + { + if (time > 0f) + { + time -= Time.deltaTime; + } + } + } +} diff --git a/Assets.Scripts.UI.SaveLoad/SaveLoadEntry.cs b/Assets.Scripts.UI.SaveLoad/SaveLoadEntry.cs new file mode 100644 index 00000000..0002d24b --- /dev/null +++ b/Assets.Scripts.UI.SaveLoad/SaveLoadEntry.cs @@ -0,0 +1,102 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Buriko; +using System; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.UI.SaveLoad +{ + public class SaveLoadEntry : MonoBehaviour + { + public UIButton SaveButton; + + public UIButton LoadButton; + + public UIButton DeleteButton; + + public UILabel BottomLabel; + + public UITexture SaveTexture; + + private SaveLoadManager manager; + + private DateTime lastDate = DateTime.Now; + + private bool isEnabled = true; + + public void EnableEntry(SaveEntry entry) + { + SaveButton.isEnabled = manager.CanSave(); + LoadButton.isEnabled = true; + DeleteButton.isEnabled = true; + string empty = string.Empty; + if (GameSystem.Instance.UseEnglishText) + { + empty = entry.Text; + if (empty == string.Empty) + { + empty = entry.TextJp; + } + } + else + { + empty = entry.TextJp; + if (empty == string.Empty) + { + empty = entry.Text; + } + } + BottomLabel.text = empty.Replace("\n", " ").TrimStart(' ', '\n'); + SaveTexture.mainTexture = AssetManager.Instance.LoadScreenshot(Path.GetFileNameWithoutExtension(entry.Path) + ".png"); + } + + private void DisableButton() + { + SaveButton.isEnabled = manager.CanSave(); + LoadButton.isEnabled = false; + DeleteButton.isEnabled = false; + BottomLabel.text = string.Empty; + SaveTexture.mainTexture = AssetManager.Instance.LoadTexture("no_data"); + } + + public void LoadSlot(int slotnum) + { + SaveEntry saveInfo = BurikoScriptSystem.Instance.GetSaveInfo(slotnum); + SaveButton.GetComponent().Prepare(slotnum, manager); + if (saveInfo == null) + { + if (isEnabled) + { + isEnabled = false; + lastDate = DateTime.Now; + DisableButton(); + } + } + else + { + isEnabled = true; + if (!(saveInfo.Time == lastDate)) + { + lastDate = saveInfo.Time; + EnableEntry(saveInfo); + LoadButton.GetComponent().Prepare(slotnum, manager); + DeleteButton.GetComponent().Prepare(slotnum, manager); + } + } + } + + public void Prepare(SaveLoadManager mg) + { + manager = mg; + } + + private void Start() + { + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.UI.SaveLoad/SaveLoadManager.cs b/Assets.Scripts.UI.SaveLoad/SaveLoadManager.cs new file mode 100644 index 00000000..4e990728 --- /dev/null +++ b/Assets.Scripts.UI.SaveLoad/SaveLoadManager.cs @@ -0,0 +1,176 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using Assets.Scripts.UI.Prompt; +using System; +using System.Collections; +using UnityEngine; + +namespace Assets.Scripts.UI.SaveLoad +{ + public class SaveLoadManager : MonoBehaviour + { + public delegate void SaveLoadLeaveCallback(); + + public static int EditSlot; + + public UIGrid SaveGrid; + + public UIGrid PageGrid; + + public SaveLoadQSave[] QuickSaveSlots; + + public UIPanel Panel; + + private SaveLoadEntry[] saveEntries; + + private SaveLoadPage[] savePages; + + private int curPage; + + private bool restoreUI; + + private IEnumerator LeaveSaveLoad(SaveLoadLeaveCallback callback) + { + LeanTween.value(this.Panel.gameObject, delegate(float f) + { + this.Panel.alpha = f; + }, 1f, 0f, 0.5f); + if (restoreUI) + { + GameSystem.Instance.MainUIController.FadeIn(0.3f); + GameSystem.Instance.SceneController.RevealFace(0.3f); + GameSystem.Instance.ExecuteActions(); + } + yield return (object)new WaitForSeconds(0.5f); + callback?.Invoke(); + UnityEngine.Object.Destroy(base.gameObject); + UnityEngine.Object.Destroy(this); + } + + public void Leave(SaveLoadLeaveCallback callback) + { + StartCoroutine(LeaveSaveLoad(callback)); + } + + private IEnumerator SaveCoroutine() + { + yield return (object)null; + yield return (object)null; + ChangePage(curPage); + } + + private void DoSave(int slot) + { + Debug.Log("DoSave: " + slot); + BurikoScriptSystem.Instance.SaveGame(slot); + StartCoroutine(SaveCoroutine()); + } + + public void Save(int slot) + { + if (BurikoMemory.Instance.GetGlobalFlag("GUsePrompts").BoolValue()) + { + StateDialogPrompt prompt = new StateDialogPrompt(PromptType.DialogSave, delegate + { + DoSave(slot); + }, null); + GameSystem.Instance.PushStateObject(prompt); + GameSystem.Instance.RegisterAction(delegate + { + PromptController p = prompt.GetPromptController(); + if (p == null) + { + Debug.LogWarning("Prompt does not exist!"); + } + else + { + GameSystem.Instance.SceneController.GetScreenshot(delegate(Texture2D tex) + { + DateTime now = DateTime.Now; + string fullText = GameSystem.Instance.TextController.GetFullText(1); + string fullText2 = GameSystem.Instance.TextController.GetFullText(0); + p.SetScreenshotDetails(tex, now.ToString("ddd MMM dd, yyyy h:mm tt"), fullText, fullText2); + }); + } + }); + GameSystem.Instance.ExecuteActions(); + } + else + { + DoSave(slot); + } + } + + public void RefreshList() + { + int page = curPage; + ChangePage(-1); + ChangePage(page); + } + + public void ChangePage(int page) + { + curPage = page; + for (int i = 0; i < SaveGrid.transform.childCount; i++) + { + saveEntries[i].LoadSlot(page * 10 + i); + } + for (int j = 0; j < PageGrid.transform.childCount; j++) + { + if (j == page) + { + savePages[j].Disable(); + } + else + { + savePages[j].Enable(); + } + } + } + + public bool CanSave() + { + return GameSystem.Instance.CanSave; + } + + private IEnumerator DoOpen() + { + Panel.alpha = 0f; + yield return (object)null; + yield return (object)null; + LeanTween.value(this.Panel.gameObject, delegate(float f) + { + this.Panel.alpha = f; + }, 0f, 1f, 0.5f); + } + + public void Open(bool doRestoreUI) + { + restoreUI = doRestoreUI; + saveEntries = new SaveLoadEntry[10]; + for (int i = 0; i < SaveGrid.transform.childCount; i++) + { + saveEntries[i] = SaveGrid.transform.GetChild(i).GetComponent(); + saveEntries[i].Prepare(this); + saveEntries[i].LoadSlot(i); + } + for (int j = 0; j < QuickSaveSlots.Length; j++) + { + QuickSaveSlots[j].Prepare(this); + QuickSaveSlots[j].LoadSlot(BurikoScriptSystem.Instance.GetQSaveSlotByMostRecent(j)); + } + savePages = new SaveLoadPage[10]; + for (int k = 0; k < PageGrid.transform.childCount; k++) + { + savePages[k] = PageGrid.transform.GetChild(k).GetComponent(); + savePages[k].Setup(k + 1, this); + } + StartCoroutine(DoOpen()); + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.UI.SaveLoad/SaveLoadPage.cs b/Assets.Scripts.UI.SaveLoad/SaveLoadPage.cs new file mode 100644 index 00000000..642d18f9 --- /dev/null +++ b/Assets.Scripts.UI.SaveLoad/SaveLoadPage.cs @@ -0,0 +1,60 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using UnityEngine; + +namespace Assets.Scripts.UI.SaveLoad +{ + public class SaveLoadPage : MonoBehaviour + { + private UISprite sprite; + + private UIButton button; + + private SaveLoadManager manager; + + private int page; + + private void OnClick() + { + if (GameSystem.Instance.GameState == GameState.SaveLoadScreen) + { + manager.ChangePage(page); + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + } + } + + public void Enable() + { + button.isEnabled = true; + sprite.spriteName = button.normalSprite; + } + + public void Disable() + { + button.isEnabled = false; + sprite.spriteName = button.disabledSprite; + } + + public void Setup(int number, SaveLoadManager saveLoadManager) + { + manager = saveLoadManager; + page = number - 1; + button = GetComponent(); + sprite = GetComponent(); + string str = page.ToString("D1"); + button.normalSprite = "page" + str + "-normal"; + button.hoverSprite = "page" + str + "-hover"; + button.pressedSprite = "page" + str + "-hover"; + button.disabledSprite = "page" + str + "-down"; + if (page == 0) + { + button.isEnabled = false; + sprite.spriteName = button.disabledSprite; + } + else + { + sprite.spriteName = button.normalSprite; + } + } + } +} diff --git a/Assets.Scripts.UI.SaveLoad/SaveLoadQSave.cs b/Assets.Scripts.UI.SaveLoad/SaveLoadQSave.cs new file mode 100644 index 00000000..3ea5b4c0 --- /dev/null +++ b/Assets.Scripts.UI.SaveLoad/SaveLoadQSave.cs @@ -0,0 +1,65 @@ +using Assets.Scripts.Core.Buriko; +using UnityEngine; + +namespace Assets.Scripts.UI.SaveLoad +{ + public class SaveLoadQSave : MonoBehaviour + { + public UIButton SaveButton; + + public UIButton LoadButton; + + public UILabel BottomLabel; + + private SaveLoadManager manager; + + private bool isEnabled = true; + + public void EnableEntry(SaveEntry entry) + { + SaveButton.isEnabled = false; + LoadButton.isEnabled = true; + BottomLabel.text = entry.Time.ToString("MMM dd, yyyy h:mm tt"); + } + + private void DisableButton() + { + SaveButton.isEnabled = false; + LoadButton.isEnabled = false; + BottomLabel.text = string.Empty; + } + + public void LoadSlot(int slotnum) + { + SaveEntry saveInfo = BurikoScriptSystem.Instance.GetSaveInfo(slotnum); + SaveButton.GetComponent().Prepare(slotnum, manager); + if (saveInfo == null) + { + if (isEnabled) + { + DisableButton(); + isEnabled = false; + } + } + else + { + isEnabled = true; + EnableEntry(saveInfo); + LoadButton.GetComponent().Prepare(slotnum, manager); + } + } + + public void Prepare(SaveLoadManager mg) + { + manager = mg; + } + + private void Start() + { + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.UI.Tips/TipsButton.cs b/Assets.Scripts.UI.Tips/TipsButton.cs new file mode 100644 index 00000000..05c5e5ec --- /dev/null +++ b/Assets.Scripts.UI.Tips/TipsButton.cs @@ -0,0 +1,48 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.State; +using UnityEngine; + +namespace Assets.Scripts.UI.Tips +{ + public class TipsButton : MonoBehaviour + { + private TipsManager manager; + + private bool isEnabled = true; + + public void Setup(TipsManager mg) + { + manager = mg; + } + + public void Disable() + { + isEnabled = false; + } + + private void OnClick() + { + GameSystem instance = GameSystem.Instance; + if (instance.GameState == GameState.TipsScreen && isEnabled && manager.isActive && UICamera.currentTouchID == -1) + { + StateViewTips stateViewTips = instance.GetStateObject() as StateViewTips; + if (stateViewTips != null) + { + switch (base.name) + { + case "PageLeft": + manager.ChangePage(-1); + break; + case "PageRight": + manager.ChangePage(1); + break; + case "ExitButton": + stateViewTips.RequestLeave(); + instance.CanSave = true; + break; + } + } + } + } + } +} diff --git a/Assets.Scripts.UI.Tips/TipsData.cs b/Assets.Scripts.UI.Tips/TipsData.cs new file mode 100644 index 00000000..f0d826ab --- /dev/null +++ b/Assets.Scripts.UI.Tips/TipsData.cs @@ -0,0 +1,216 @@ +using Assets.Scripts.Core.Buriko; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.Tips +{ + public static class TipsData + { + public static List Tips = new List + { + new TipsDataEntry + { + Id = 0, + Script = "onik_tips_01", + UnlockChapter = 1, + Title = "We're a mixed grade?", + TitleJp = "うちって学年混在?" + }, + new TipsDataEntry + { + Id = 1, + Script = "onik_tips_02", + UnlockChapter = 1, + Title = "We don't have a uniform?", + TitleJp = "うちって制服自由?" + }, + new TipsDataEntry + { + Id = 2, + Script = "onik_tips_03", + UnlockChapter = 2, + Title = "The Maebara Manor", + TitleJp = "前原屋敷" + }, + new TipsDataEntry + { + Id = 3, + Script = "onik_tips_04", + UnlockChapter = 2, + Title = "The dam site murder/dismemberment (Newspaper edition)", + TitleJp = "ダム現場のバラバラ殺人(新聞版)" + }, + new TipsDataEntry + { + Id = 4, + Script = "onik_tips_05", + UnlockChapter = 3, + Title = "The Hinamizawa Dam Project", + TitleJp = "雛見沢ダム計画" + }, + new TipsDataEntry + { + Id = 5, + Script = "onik_tips_06", + UnlockChapter = 3, + Title = "Special tabloid report", + TitleJp = "週刊誌の特集記事" + }, + new TipsDataEntry + { + Id = 6, + Script = "onik_tips_07", + UnlockChapter = 4, + Title = "What kind of name is Rena?", + TitleJp = "レナってどういう名前だよ?" + }, + new TipsDataEntry + { + Id = 7, + Script = "onik_tips_08", + UnlockChapter = 5, + Title = "Community Notice", + TitleJp = "回覧板" + }, + new TipsDataEntry + { + Id = 8, + Script = "onik_tips_09", + UnlockChapter = 7, + Title = "Houjou couple's falling incident", + TitleJp = "北条両親の転落事故" + }, + new TipsDataEntry + { + Id = 9, + Script = "onik_tips_10", + UnlockChapter = 7, + Title = "The terminal illness death of Shinto Priest Furude", + TitleJp = "古手神社の神主の病死" + }, + new TipsDataEntry + { + Id = 10, + Script = "onik_tips_11", + UnlockChapter = 7, + Title = "Housewife murder", + TitleJp = "主婦殺人事件" + }, + new TipsDataEntry + { + Id = 11, + Script = "onik_tips_12", + UnlockChapter = 7, + Title = "Radio Log", + TitleJp = "無線記録" + }, + new TipsDataEntry + { + Id = 12, + Script = "onik_tips_13", + UnlockChapter = 8, + Title = "There are more than four perpetrators?", + TitleJp = "犯人は4人以上?" + }, + new TipsDataEntry + { + Id = 13, + Script = "onik_tips_14", + UnlockChapter = 8, + Title = "Search notice", + TitleJp = "捜査メモ" + }, + new TipsDataEntry + { + Id = 14, + Script = "onik_tips_15", + UnlockChapter = 9, + Title = "Notice from the police chief", + TitleJp = "本部長通達" + }, + new TipsDataEntry + { + Id = 15, + Script = "onik_tips_16", + UnlockChapter = 10, + Title = "What's a drug that makes you commit suicide?", + TitleJp = "自殺を誘発するクスリは?" + }, + new TipsDataEntry + { + Id = 16, + Script = "onik_tips_17", + UnlockChapter = 10, + Title = "Threat", + TitleJp = "脅迫" + }, + new TipsDataEntry + { + Id = 17, + Script = "onik_tips_18", + UnlockChapter = 11, + Title = "Not feeling so hot", + TitleJp = "元気ないね。" + }, + new TipsDataEntry + { + Id = 18, + Script = "onik_tips_19", + UnlockChapter = 13, + Title = "Split personality???", + TitleJp = "二重人格???" + }, + new TipsDataEntry + { + Id = 19, + Script = "onik_tips_20", + UnlockChapter = 13, + Title = "At the Seventh Mart", + TitleJp = "セブンスマ\u30fcトにて" + } + }; + + public static TipsDataGroup GetVisibleTips(bool onlyNew, bool global) + { + TipsDataGroup tipsDataGroup = new TipsDataGroup(); + BurikoMemory instance = BurikoMemory.Instance; + if (global) + { + int num = instance.GetGlobalFlag("GOnikakushiDay").IntValue(); + { + foreach (TipsDataEntry tip in Tips) + { + tipsDataGroup.TipsAvailable++; + if (tip.UnlockChapter <= num) + { + tipsDataGroup.TipsUnlocked++; + tipsDataGroup.Tips.Add(tip); + } + } + return tipsDataGroup; + } + } + int num2 = instance.GetFlag("LOnikakushiDay").IntValue(); + Debug.Log("current chapter " + num2); + foreach (TipsDataEntry tip2 in Tips) + { + if (onlyNew) + { + if (tip2.UnlockChapter == num2) + { + tipsDataGroup.TipsAvailable++; + tipsDataGroup.TipsUnlocked++; + tipsDataGroup.Tips.Add(tip2); + } + } + else if (tip2.UnlockChapter <= num2) + { + tipsDataGroup.TipsAvailable++; + tipsDataGroup.TipsUnlocked++; + tipsDataGroup.Tips.Add(tip2); + } + } + return tipsDataGroup; + } + } +} diff --git a/Assets.Scripts.UI.Tips/TipsDataEntry.cs b/Assets.Scripts.UI.Tips/TipsDataEntry.cs new file mode 100644 index 00000000..f335fccb --- /dev/null +++ b/Assets.Scripts.UI.Tips/TipsDataEntry.cs @@ -0,0 +1,15 @@ +namespace Assets.Scripts.UI.Tips +{ + public class TipsDataEntry + { + public int Id; + + public string Title; + + public string TitleJp; + + public string Script; + + public int UnlockChapter; + } +} diff --git a/Assets.Scripts.UI.Tips/TipsDataGroup.cs b/Assets.Scripts.UI.Tips/TipsDataGroup.cs new file mode 100644 index 00000000..0a67e55a --- /dev/null +++ b/Assets.Scripts.UI.Tips/TipsDataGroup.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace Assets.Scripts.UI.Tips +{ + public class TipsDataGroup + { + public int TipsUnlocked; + + public int TipsAvailable; + + public List Tips = new List(); + } +} diff --git a/Assets.Scripts.UI.Tips/TipsEntry.cs b/Assets.Scripts.UI.Tips/TipsEntry.cs new file mode 100644 index 00000000..e0062855 --- /dev/null +++ b/Assets.Scripts.UI.Tips/TipsEntry.cs @@ -0,0 +1,82 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.State; +using UnityEngine; + +namespace Assets.Scripts.UI.Tips +{ + public class TipsEntry : MonoBehaviour + { + private TipsDataEntry tip; + + private TipsManager manager; + + private UISprite sprite; + + private UIButton button; + + private bool isHover; + + public void Init(TipsDataEntry t, TipsManager mg) + { + tip = t; + manager = mg; + if (button == null) + { + button = GetComponent(); + sprite = GetComponent(); + } + string name = $"tips{t.Id:D3}na_normal"; + UISpriteData uISpriteData = sprite.atlas.GetSprite(name); + if (uISpriteData != null && AssetManager.Instance.UseNewArt) + { + button.normalSprite = $"tips{t.Id:D3}na_normal"; + button.hoverSprite = $"tips{t.Id:D3}na_hover"; + button.pressedSprite = $"tips{t.Id:D3}na_hover"; + button.disabledSprite = $"tips{t.Id:D3}na_normal"; + } + else + { + button.normalSprite = $"tips{t.Id:D3}_normal"; + button.hoverSprite = $"tips{t.Id:D3}_hover"; + button.pressedSprite = $"tips{t.Id:D3}_hover"; + button.disabledSprite = $"tips{t.Id:D3}_normal"; + } + } + + private void OnClick() + { + if (UICamera.currentTouchID == -1 && tip != null && manager.isActive && GameSystem.Instance.GameState == GameState.TipsScreen) + { + (GameSystem.Instance.GetStateObject() as StateViewTips)?.OpenTips(tip.Script); + } + } + + private void OnHover(bool hover) + { + isHover = hover; + if (tip != null) + { + if (!isHover) + { + manager.ClearTitle(); + } + else if (GameSystem.Instance.GameState == GameState.TipsScreen) + { + manager.ShowTitle((!GameSystem.Instance.UseEnglishText) ? tip.TitleJp : tip.Title); + } + } + } + + public void Reset() + { + tip = null; + button = GetComponent(); + sprite = GetComponent(); + button.normalSprite = "tipslocked"; + button.hoverSprite = "tipslocked"; + button.pressedSprite = "tipslocked"; + button.disabledSprite = "tipslocked"; + } + } +} diff --git a/Assets.Scripts.UI.Tips/TipsManager.cs b/Assets.Scripts.UI.Tips/TipsManager.cs new file mode 100644 index 00000000..aa21358a --- /dev/null +++ b/Assets.Scripts.UI.Tips/TipsManager.cs @@ -0,0 +1,162 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using System; +using System.Collections.Generic; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.UI.Tips +{ + public class TipsManager : MonoBehaviour + { + public UIPanel Panel; + + public Material TextMaterial; + + public TextMeshPro tipsTitleText; + + public TextMeshPro tipsPageText; + + public UIButton PageLeft; + + public UIButton PageRight; + + public List TipsButtons; + + public List TipsEntries; + + public bool isActive = true; + + private int page; + + private int numPages = 1; + + private TipsDataGroup tipsData; + + public static int ReturnPage; + + private void SetFade(float f) + { + Panel.alpha = f; + TextMaterial.SetColor("_FaceColor", new Color(1f, 1f, 1f, f)); + TextMaterial.SetColor("_UnderlayColor", new Color(0f, 0f, 0f, 0.8f * f)); + } + + public void ChangePage(int change) + { + if (page + change >= 0 && page + change <= numPages) + { + page += change; + UpdateEntries(); + } + } + + public void ShowTitle(string title) + { + tipsTitleText.text = title; + } + + public void ClearTitle() + { + tipsTitleText.text = string.Empty; + } + + public void UpdatePage() + { + if (numPages == 0) + { + tipsPageText.text = string.Empty; + } + else + { + tipsPageText.text = page + 1 + "/" + (numPages + 1); + } + PageLeft.isEnabled = (page != 0); + PageRight.isEnabled = (page != numPages); + } + + public void UpdateEntries() + { + for (int i = 0; i < TipsEntries.Count; i++) + { + int num = i + page * 8; + TipsEntries[i].Reset(); + TipsEntries[i].gameObject.name = "TipsEntry" + i; + if (num >= tipsData.TipsUnlocked) + { + TipsEntries[i].gameObject.SetActive(value: false); + } + if (num < tipsData.TipsUnlocked) + { + TipsEntries[i].gameObject.SetActive(value: true); + TipsEntries[i].Init(tipsData.Tips[num], this); + } + if (num < tipsData.TipsAvailable) + { + TipsEntries[i].gameObject.SetActive(value: true); + } + } + UpdatePage(); + ClearTitle(); + } + + public void Show(int tipstype) + { + LTDescr lTDescr = LeanTween.value(base.gameObject, SetFade, 0f, 1f, 0.8f); + lTDescr.onComplete = delegate + { + GameSystem.Instance.AudioController.PlayAudio("msys14.ogg", Assets.Scripts.Core.Audio.AudioType.BGM, 0, 0.7f, 0f); + }; + switch (tipstype) + { + case 0: + tipsData = TipsData.GetVisibleTips(onlyNew: false, global: false); + break; + case 1: + tipsData = TipsData.GetVisibleTips(onlyNew: true, global: false); + break; + case 2: + tipsData = TipsData.GetVisibleTips(onlyNew: false, global: true); + break; + default: + throw new ArgumentOutOfRangeException("tipstype for TipsManager.Show() must be between 0 and 2 (" + tipstype + " given)"); + } + page = 0; + numPages = tipsData.TipsAvailable / 8; + if (numPages >= ReturnPage) + { + page = ReturnPage; + } + UpdateEntries(); + TipsButtons.ForEach(delegate(TipsButton a) + { + a.Setup(this); + }); + } + + public void Hide(Action onFinish) + { + isActive = false; + LTDescr lTDescr = LeanTween.value(base.gameObject, SetFade, 1f, 0f, 0.8f); + lTDescr.onComplete = onFinish; + LTDescr lTDescr2 = lTDescr; + lTDescr2.onComplete = (Action)Delegate.Combine(lTDescr2.onComplete, (Action)delegate + { + UnityEngine.Object.Destroy(base.gameObject); + }); + TipsButtons.ForEach(delegate(TipsButton a) + { + a.Disable(); + }); + ReturnPage = page; + } + + private void Start() + { + } + + private void Update() + { + } + } +} diff --git a/Assets.Scripts.UI.TitleScreen/TitleScreen.cs b/Assets.Scripts.UI.TitleScreen/TitleScreen.cs new file mode 100644 index 00000000..a665ff04 --- /dev/null +++ b/Assets.Scripts.UI.TitleScreen/TitleScreen.cs @@ -0,0 +1,84 @@ +using Assets.Scripts.Core.Buriko; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Assets.Scripts.UI.TitleScreen +{ + public class TitleScreen : MonoBehaviour + { + public TweenAlpha BackgroundTween; + + public UITexture BackgroundTexture; + + public Texture2D BG1; + + public Texture2D BG2; + + public List Sprites; + + public bool IsActive = true; + + private IEnumerator LeaveMenuAnimation(MenuUIController.MenuCloseDelegate onClose) + { + BackgroundTween.PlayReverse(); + yield return (object)new WaitForSeconds(0.5f); + onClose?.Invoke(); + Object.Destroy(base.gameObject); + } + + public void FadeOut() + { + BackgroundTween.PlayReverse(); + } + + public void FadeIn() + { + BackgroundTween.PlayForward(); + } + + public void Leave(MenuUIController.MenuCloseDelegate onClose) + { + for (int i = 0; i < Sprites.Count; i++) + { + TitleScreenButton component = Sprites[i].GetComponent(); + if (component != null) + { + component.IsLeaving = true; + } + } + StartCoroutine(LeaveMenuAnimation(onClose)); + } + + private void OpeningAnimation() + { + for (int j = 0; j < Sprites.Count; j++) + { + int i = j; + LTDescr lTDescr = LeanTween.value(Sprites[j].gameObject, delegate(float f) + { + Sprites[i].color = new Color(1f, 1f, 1f, f); + }, 0f, 1f, 1f); + lTDescr.delay = (float)j * 0.25f; + } + } + + public void Enter() + { + BurikoVariable globalFlag = BurikoMemory.Instance.GetGlobalFlag("GFlag_GameClear"); + BackgroundTexture.mainTexture = (globalFlag.BoolValue() ? BG2 : BG1); + if (BurikoMemory.Instance.GetGlobalFlag("GOnikakushiDay").IntValue() < 1) + { + Sprites[4].transform.localPosition = new Vector3(0f, -224f, 0f); + UISprite uISprite = Sprites[3]; + Sprites.RemoveAt(3); + Object.Destroy(uISprite.gameObject); + } + foreach (UISprite sprite in Sprites) + { + sprite.color = new Color(1f, 1f, 1f, 0f); + } + OpeningAnimation(); + } + } +} diff --git a/Assets.Scripts.UI.TitleScreen/TitleScreenButton.cs b/Assets.Scripts.UI.TitleScreen/TitleScreenButton.cs new file mode 100644 index 00000000..48bf916f --- /dev/null +++ b/Assets.Scripts.UI.TitleScreen/TitleScreenButton.cs @@ -0,0 +1,123 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using Assets.Scripts.UI.Prompt; +using UnityEngine; + +namespace Assets.Scripts.UI.TitleScreen +{ + public class TitleScreenButton : MonoBehaviour + { + private float time = 2.25f; + + private UIButton button; + + private bool isReady; + + private bool isHover; + + public bool IsEnabled = true; + + public bool IsLeaving; + + private string hoverSprite; + + private string pressedSprite; + + private void OnClick() + { + GameSystem gameSystem = GameSystem.Instance; + if (gameSystem.GameState == GameState.TitleScreen && !(time > 0f) && UICamera.currentTouchID == -1) + { + StateTitle stateTitle = gameSystem.GetStateObject() as StateTitle; + if (stateTitle != null) + { + switch (base.name) + { + case "0-Start": + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 0); + stateTitle.RequestLeave(); + gameSystem.AudioController.StopAllAudio(); + gameSystem.AudioController.PlaySystemSound("wa_040.ogg"); + IsEnabled = false; + break; + case "1-Load": + gameSystem.PushStateObject(new StateSaveLoad(restoreUI: false)); + break; + case "2-Config": + gameSystem.SwitchToConfig(0, showMessageWindow: false); + break; + case "3-CGGallery": + BurikoMemory.Instance.SetFlag("LOCALWORK_NO_RESULT", 1); + BurikoMemory.Instance.SetFlag("TipsMode", 1); + stateTitle.RequestLeave(); + gameSystem.AudioController.FadeOutBGM(2, 1000, waitForFade: false); + BurikoScriptSystem.Instance.CallBlock("ViewTipsDisplay"); + gameSystem.SceneController.DrawScene("black", 0.5f); + gameSystem.ExecuteActions(); + break; + case "4-Exit": + GameSystem.Instance.PushStateObject(new StateDialogPrompt(PromptType.DialogExit, delegate + { + gameSystem.CanExit = true; + Application.Quit(); + }, null)); + break; + default: + Debug.Log("Button ID not found: " + base.name); + break; + } + if (base.name != "0-Start") + { + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + } + IsEnabled = false; + } + } + } + + private void OnHover(bool hover) + { + isHover = hover; + if (GameSystem.Instance.GameState == GameState.TitleScreen) + { + } + } + + private void Update() + { + time -= Time.deltaTime; + } + + private void Awake() + { + button = GetComponent(); + hoverSprite = button.hoverSprite; + pressedSprite = button.pressedSprite; + button.hoverSprite = button.normalSprite; + button.pressedSprite = button.normalSprite; + button.enabled = false; + } + + private void LateUpdate() + { + button.isEnabled = (GameSystem.Instance.GameState == GameState.TitleScreen && !IsLeaving); + if (!isReady && time < 0f) + { + if (!button.enabled) + { + button.enabled = true; + } + button.hoverSprite = hoverSprite; + button.pressedSprite = pressedSprite; + isReady = true; + if (isHover) + { + UISprite component = GetComponent(); + component.spriteName = button.hoverSprite; + } + } + } + } +} diff --git a/Assets.Scripts.UI/MainUIController.cs b/Assets.Scripts.UI/MainUIController.cs new file mode 100644 index 00000000..4fc42a4d --- /dev/null +++ b/Assets.Scripts.UI/MainUIController.cs @@ -0,0 +1,394 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Scene; +using System.Collections; +using TMPro; +using UnityEngine; + +namespace Assets.Scripts.UI +{ + [RequireComponent(typeof(UIPanel))] + public class MainUIController : MonoBehaviour + { + public LayerPool LayerPool; + + public GameObject QuickSaveIcon; + + public GameObject CarretPageSprite; + + public GameObject CarretLineSprite; + + public GameObject AutoMarker; + + public GameObject SkipMarker; + + public TextMeshPro TextWindow; + + public string[] FontList; + + public BlackBars[] Bars; + + private UIPanel panel; + + private GameObject mainuiPanel; + + private Layer bgLayer; + + private Layer bgLayer2; + + private bool carretVisible; + + private bool language; + + private int altFontId; + + private Animator carretAnimator; + + private GameSystem gameSystem; + + public void UpdateGuiPosition(int x, int y) + { + mainuiPanel.transform.localPosition = new Vector3((float)x, (float)y, 0f); + } + + public void UpdateBlackBars() + { + for (int i = 0; i < Bars.Length; i++) + { + Bars[i].UpdatePosition(); + } + } + + private void UpdateAlpha(float a) + { + panel.alpha = a; + gameSystem.TextController.TextArea.color = new Color(1f, 1f, 1f, a); + } + + public void StopShake() + { + Shaker component = mainuiPanel.gameObject.GetComponent(); + if (component != null) + { + component.StopShake(); + } + mainuiPanel.transform.localPosition = Vector3.zero; + } + + public void ShakeScene(float speed, int level, int attenuation, int vector, int loopcount, bool isblocking) + { + Shaker.ShakeObject(mainuiPanel.gameObject, speed, level, attenuation, vector, loopcount, isblocking); + } + + public void SetWindowOpacity(float alpha) + { + if (gameSystem.MessageBoxVisible) + { + bgLayer.SetRange(alpha); + bgLayer2.SetRange(alpha); + } + } + + private void ShowLayerBackground(float time) + { + if (carretVisible) + { + ShowCarret(); + } + if (bgLayer != null && bgLayer2 != null) + { + bgLayer.FadeTo(gameSystem.MessageWindowOpacity, time); + bgLayer2.FadeTo(gameSystem.MessageWindowOpacity, time); + } + else + { + if (bgLayer == null) + { + bgLayer = LayerPool.ActivateLayer(); + } + bgLayer.gameObject.layer = LayerMask.NameToLayer("Scene1"); + bgLayer.SetPriority(62); + bgLayer.name = "Window Background 1"; + bgLayer.IsStatic = true; + bgLayer.DrawLayer("windo_filter", 0, 0, 0, null, gameSystem.MessageWindowOpacity, /*isBustshot:*/ false, 0, time, /*isBlocking:*/ false); + if (bgLayer2 == null) + { + bgLayer2 = LayerPool.ActivateLayer(); + } + bgLayer2.gameObject.layer = LayerMask.NameToLayer("Scene2"); + bgLayer2.SetPriority(62); + bgLayer2.name = "Window Background 2"; + bgLayer2.IsStatic = true; + bgLayer2.DrawLayer("windo_filter", 0, 0, 0, null, gameSystem.MessageWindowOpacity, /*isBustshot:*/ false, 0, time, /*isBlocking:*/ false); + } + } + + private void HideLayerBackground(float time) + { + if (bgLayer == null || !bgLayer.IsInUse) + { + if (bgLayer != null) + { + bgLayer.FadeTo(0f, time); + } + if (bgLayer2 != null) + { + bgLayer2.FadeTo(0f, time); + } + } + else + { + if (Mathf.Approximately(time, 0f)) + { + if (bgLayer != null) + { + bgLayer.FadeTo(0f, time); + } + if (bgLayer2 != null) + { + bgLayer2.FadeTo(0f, time); + } + } + else + { + if (bgLayer != null) + { + bgLayer.FadeTo(0f, time); + } + if (bgLayer2 != null) + { + bgLayer2.FadeTo(0f, time); + } + } + HideCarret(); + } + } + + public void ShowMessageBox() + { + ShowLayerBackground(0f); + bgLayer.FinishAll(); + bgLayer2.FinishAll(); + iTween.Stop(base.gameObject); + UpdateAlpha(1f); + GameSystem.Instance.MessageBoxVisible = true; + if (carretVisible) + { + ShowCarret(); + } + } + + public void HideMessageBox() + { + if (bgLayer != null) + { + bgLayer.FinishAll(); + } + if (bgLayer2 != null) + { + bgLayer2.FinishAll(); + } + iTween.Stop(base.gameObject); + GameSystem.Instance.MessageBoxVisible = false; + UpdateAlpha(0f); + QuickSaveIcon.SetActive(value: false); + HideCarret(); + } + + public void FadeOut(float time, bool isBlocking) + { + HideLayerBackground(time); + HideCarret(); + GameSystem.Instance.MessageBoxVisible = false; + if (isBlocking || !Mathf.Approximately(time, 0f)) + { + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("name", "FadeOut", "from", panel.alpha, "to", 0, "time", time, "onupdate", "UpdateAlpha", "oncomplete", "HideMessageBox")); + if (isBlocking) + { + GameSystem.Instance.AddWait(new Wait(time, WaitTypes.WaitForScene, HideMessageBox)); + } + } + else + { + UpdateAlpha(0f); + } + gameSystem.ExecuteActions(); + } + + public void FadeIn(float time) + { + GameSystem.Instance.MessageBoxVisible = true; + ShowLayerBackground(time); + if (!Mathf.Approximately(time, 0f)) + { + iTween.Stop(base.gameObject); + iTween.ValueTo(base.gameObject, iTween.Hash("from", 0, "to", 1, "time", time, "onupdate", "UpdateAlpha", "oncomplete", "ShowMessageBox")); + GameSystem.Instance.AddWait(new Wait(time, WaitTypes.WaitForScene, ShowMessageBox)); + } + else + { + UpdateAlpha(1f); + } + gameSystem.ExecuteActions(); + } + + private IEnumerator QuickSaveAnimation() + { + QuickSaveIcon.SetActive(value: true); + TweenAlpha t = QuickSaveIcon.GetComponent(); + t.PlayForward(); + yield return (object)new WaitForSeconds(3f); + t.PlayReverse(); + yield return (object)new WaitForSeconds(0.5f); + QuickSaveIcon.SetActive(value: false); + } + + public void ShowQuickSaveIcon() + { + StartCoroutine(QuickSaveAnimation()); + } + + public void SetCharSpacing(int spacing) + { + TextWindow.characterSpacing = (float)spacing; + } + + public void SetLineSpacing(int spacing) + { + TextWindow.lineSpacing = (float)spacing; + } + + public void SetFontSize(int size) + { + TextWindow.fontSize = (float)size; + } + + public void SetWindowPos(int x, int y) + { + TextWindow.gameObject.transform.localPosition = new Vector3((float)x, (float)y, 0f); + } + + public void SetWindowSize(int x, int y) + { + TextContainer textContainer = TextWindow.textContainer; + textContainer.width = (float)x; + textContainer.height = (float)y; + } + + public void SetWindowMargins(int left, int top, int right, int bottom) + { + TextContainer textContainer = TextWindow.textContainer; + textContainer.margins.Set((float)left, (float)top, (float)right, (float)bottom); + } + + public void ChangeFontId(int id) + { + altFontId = id; + if (language) + { + TextWindow.font = Resources.Load(FontList[altFontId]); + } + else + { + TextWindow.font = Resources.Load(FontList[0]); + } + } + + private void Awake() + { + language = GameSystem.Instance.UseEnglishText; + if (language) + { + TextWindow.font = Resources.Load(FontList[altFontId]); + } + else + { + TextWindow.font = Resources.Load(FontList[0]); + } + } + + public void ShowCarret() + { + carretVisible = true; + if (!gameSystem.TextController.GetAppendState()) + { + CarretPageSprite.transform.localPosition = gameSystem.TextController.GetCarretPosition(); + if (!CarretPageSprite.activeSelf) + { + CarretPageSprite.SetActive(value: true); + } + CarretLineSprite.SetActive(value: false); + } + else + { + CarretLineSprite.transform.localPosition = gameSystem.TextController.GetCarretPosition(); + if (!CarretLineSprite.activeSelf) + { + CarretLineSprite.SetActive(value: true); + } + CarretPageSprite.SetActive(value: false); + } + } + + public void HideCarret() + { + carretVisible = false; + CarretPageSprite.SetActive(value: false); + CarretLineSprite.SetActive(value: false); + } + + private void Start() + { + panel = GetComponent(); + panel.enabled = false; + panel.alpha = 0f; + mainuiPanel = GameObject.FindGameObjectWithTag("PrimaryUIPanel"); + } + + private void Update() + { + if (gameSystem == null) + { + gameSystem = GameSystem.Instance; + } + int num = 402; + int num2 = 402; + if (gameSystem.IsSkipping && !gameSystem.IsForceSkip) + { + num = 334; + } + if (gameSystem.IsAuto) + { + num2 = 334; + } + Vector3 localPosition = SkipMarker.transform.localPosition; + float x = Mathf.Lerp(localPosition.x, (float)num, Time.deltaTime * 10f); + Vector3 localPosition2 = SkipMarker.transform.localPosition; + Vector3 localPosition3 = new Vector3(x, localPosition2.y, 0f); + Vector3 localPosition4 = AutoMarker.transform.localPosition; + float x2 = Mathf.Lerp(localPosition4.x, (float)num2, Time.deltaTime * 10f); + Vector3 localPosition5 = AutoMarker.transform.localPosition; + Vector3 localPosition6 = new Vector3(x2, localPosition5.y, 0f); + SkipMarker.transform.localPosition = localPosition3; + AutoMarker.transform.localPosition = localPosition6; + SkipMarker.SetActive(!(localPosition3.x > 400f)); + AutoMarker.SetActive(!(localPosition6.x > 400f)); + if (carretVisible) + { + ShowCarret(); + } + if (language != GameSystem.Instance.UseEnglishText) + { + language = GameSystem.Instance.UseEnglishText; + if (language) + { + TextWindow.font = Resources.Load(FontList[altFontId]); + } + else + { + TextWindow.font = Resources.Load(FontList[0]); + } + } + } + } +} diff --git a/Assets.Scripts.UI/MainWindowSlideBox.cs b/Assets.Scripts.UI/MainWindowSlideBox.cs new file mode 100644 index 00000000..3e203eb1 --- /dev/null +++ b/Assets.Scripts.UI/MainWindowSlideBox.cs @@ -0,0 +1,80 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Buriko; +using UnityEngine; + +namespace Assets.Scripts.UI +{ + public class MainWindowSlideBox : MonoBehaviour + { + public UIPanel Panel; + + private bool isOpen = true; + + private bool autoHide; + + private bool isoffset; + + private void OnHover(bool hover) + { + if (hover && !isOpen && (GameSystem.Instance.GameState == GameState.Normal || GameSystem.Instance.GameState == GameState.ChoiceScreen)) + { + LeanTween.cancel(Panel.gameObject); + LeanTween.value(Panel.gameObject, delegate(float f) + { + Panel.alpha = f; + }, Panel.alpha, 1f, 0.3f); + isOpen = true; + } + } + + private void CloseWindow() + { + LeanTween.cancel(Panel.gameObject); + LeanTween.value(Panel.gameObject, delegate(float f) + { + Panel.alpha = f; + }, Panel.alpha, 0f, 0.3f); + isOpen = false; + } + + private void Start() + { + } + + private void FixedUpdate() + { + if (BurikoMemory.Instance != null) + { + autoHide = BurikoMemory.Instance.GetGlobalFlag("GHideButtons").BoolValue(); + if (!autoHide && !isOpen) + { + LeanTween.cancel(Panel.gameObject); + LeanTween.value(Panel.gameObject, delegate(float f) + { + Panel.alpha = f; + }, Panel.alpha, 1f, 0.3f); + isOpen = true; + } + } + } + + private void Update() + { + if (autoHide) + { + GameObject hoveredObject = UICamera.hoveredObject; + if (isOpen) + { + if (hoveredObject == GameSystem.Instance.SceneController.SceneCameras || (GameSystem.Instance.GameState != GameState.Normal && GameSystem.Instance.GameState != GameState.ChoiceScreen)) + { + CloseWindow(); + } + else if (!(hoveredObject == null) && !hoveredObject.transform.IsChildOf(base.gameObject.transform)) + { + CloseWindow(); + } + } + } + } + } +} diff --git a/Assets.Scripts.UI/SlideBoxButton.cs b/Assets.Scripts.UI/SlideBoxButton.cs new file mode 100644 index 00000000..0a653cca --- /dev/null +++ b/Assets.Scripts.UI/SlideBoxButton.cs @@ -0,0 +1,97 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.AssetManagement; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.Core.Buriko; +using Assets.Scripts.Core.State; +using Assets.Scripts.UI.Prompt; +using System.IO; +using UnityEngine; + +namespace Assets.Scripts.UI +{ + public class SlideBoxButton : MonoBehaviour + { + public SlideButtonType Type; + + private float cooldown; + + private void OnClick() + { + if (UICamera.currentTouchID == -1 && !(cooldown > 0f)) + { + switch (Type) + { + case SlideButtonType.Log: + GameSystem.Instance.SwitchToHistoryScreen(); + break; + case SlideButtonType.Auto: + GameSystem.Instance.IsAuto = true; + break; + case SlideButtonType.Skip: + GameSystem.Instance.IsSkipping = true; + break; + case SlideButtonType.Menu: + GameSystem.Instance.SwitchToRightClickMenu(); + break; + case SlideButtonType.QuickSave: + if (!GameSystem.Instance.CanSave) + { + AudioController.Instance.PlaySystemSound("sysse04.ogg", 1); + return; + } + GameSystem.Instance.ScriptSystem.SaveQuickSave(); + break; + case SlideButtonType.QuickLoad: + { + if (!GameSystem.Instance.CanSave) + { + AudioController.Instance.PlaySystemSound("sysse04.ogg", 1); + return; + } + SaveEntry d = BurikoScriptSystem.Instance.GetQSaveInfo(); + if (d == null) + { + return; + } + StateDialogPrompt prompt = new StateDialogPrompt(PromptType.DialogLoad, delegate + { + GameSystem.Instance.ScriptSystem.LoadQuickSave(); + }, null); + GameSystem.Instance.PushStateObject(prompt); + GameSystem.Instance.RegisterAction(delegate + { + PromptController promptController = prompt.GetPromptController(); + if (!(promptController == null)) + { + string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(d.Path); + Texture2D image = AssetManager.Instance.LoadScreenshot(fileNameWithoutExtension + ".png"); + Debug.Log(promptController); + Debug.Log(d); + promptController.SetScreenshotDetails(image, d.Time.ToString("ddd MMM dd, yyyy h:mm tt"), d.Text, d.TextJp); + } + }); + GameSystem.Instance.ExecuteActions(); + break; + } + } + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + cooldown = 0.5f; + } + } + + private void OnHover(bool ishover) + { + if (!(cooldown > 0f) && GameSystem.Instance.MessageBoxVisible) + { + } + } + + private void Update() + { + if (cooldown > 0f) + { + cooldown -= Time.deltaTime; + } + } + } +} diff --git a/Assets.Scripts.UI/SlideButtonType.cs b/Assets.Scripts.UI/SlideButtonType.cs new file mode 100644 index 00000000..6860c62b --- /dev/null +++ b/Assets.Scripts.UI/SlideButtonType.cs @@ -0,0 +1,12 @@ +namespace Assets.Scripts.UI +{ + public enum SlideButtonType + { + Auto, + Skip, + Log, + Menu, + QuickSave, + QuickLoad + } +} diff --git a/BGICompiler.Compiler/BGIParameters.cs b/BGICompiler.Compiler/BGIParameters.cs new file mode 100644 index 00000000..02d36ec3 --- /dev/null +++ b/BGICompiler.Compiler/BGIParameters.cs @@ -0,0 +1,95 @@ +using Antlr.Runtime.Tree; +using Assets.Scripts.Core.Buriko; +using System.Collections.Generic; +using UnityEngine; + +namespace BGICompiler.Compiler +{ + public class BGIParameters + { + private readonly List values = new List(); + + public int Count => values.Count; + + public BGIParameters() + { + } + + public BGIParameters(ITree tree) + { + for (int i = 0; i < tree.ChildCount; i++) + { + values.Add(new BGIValue(tree.GetChild(i))); + } + } + + public BGIValue GetParam(int i) + { + return values[i]; + } + + public void OutputParam(int i) + { + values[i].Output(); + } + + public void OutputAllParams() + { + foreach (BGIValue value in values) + { + value.Output(); + } + } + + public bool CheckParamSig(string sig) + { + int num = 0; + if (sig.Length != values.Count) + { + return false; + } + foreach (char c in sig) + { + if (values[num].Type == BurikoValueType.Null) + { + num++; + } + else + { + switch (c) + { + case 'i': + if (values[num].Type != BurikoValueType.Int && values[num].Type != BurikoValueType.Bool && values[num].Type != BurikoValueType.Variable && values[num].Type != BurikoValueType.Operation && values[num].Type != BurikoValueType.Math) + { + Debug.LogWarning(values[num].Type); + return false; + } + break; + case 's': + if (values[num].Type != BurikoValueType.String && values[num].Type != BurikoValueType.Variable) + { + return false; + } + break; + case 'b': + if (values[num].Type != BurikoValueType.Bool) + { + return false; + } + break; + case 'v': + if (values[num].Type != BurikoValueType.Variable) + { + return false; + } + break; + default: + return false; + } + num++; + } + } + return true; + } + } +} diff --git a/BGICompiler.Compiler/BGIValue.cs b/BGICompiler.Compiler/BGIValue.cs new file mode 100644 index 00000000..6a602fd6 --- /dev/null +++ b/BGICompiler.Compiler/BGIValue.cs @@ -0,0 +1,214 @@ +using Antlr.Runtime.Tree; +using Assets.Scripts.Core.Buriko; +using System; +using System.IO; + +namespace BGICompiler.Compiler +{ + public class BGIValue + { + public BurikoValueType Type; + + private ITree baseTree; + + private ITree tree; + + private BurikoMathType mathType; + + public BGIValue(ITree treein) + { + baseTree = treein; + tree = treein.GetChild(0); + switch (treein.Text) + { + case "TYPEINT": + Type = BurikoValueType.Int; + break; + case "TYPESTRING": + Type = BurikoValueType.String; + break; + case "TYPEBOOL": + Type = BurikoValueType.Bool; + break; + case "TYPENULL": + Type = BurikoValueType.Null; + break; + case "TYPEFUNCTION": + Type = BurikoValueType.Operation; + break; + case "TYPEVARIABLE": + Type = BurikoValueType.Variable; + baseTree = tree; + tree = baseTree.GetChild(0); + break; + case "VAR": + Type = BurikoValueType.Variable; + break; + } + if (Type == BurikoValueType.None && IsMath(treein.Text)) + { + Type = BurikoValueType.Math; + } + } + + public bool GetBool() + { + if (Type != BurikoValueType.Bool) + { + throw new Exception("GetBool called for variable type " + Type); + } + if (tree.Text == "TRUE") + { + return true; + } + if (tree.Text == "FALSE") + { + return false; + } + throw new Exception("Unexpected type found for variable type Bool!"); + } + + public bool IsMath(string s) + { + switch (s) + { + case "==": + mathType = BurikoMathType.Equals; + return true; + case "!=": + mathType = BurikoMathType.NotEquals; + return true; + case "<=": + mathType = BurikoMathType.LessThanOrEquals; + return true; + case ">=": + mathType = BurikoMathType.GreaterThanOrEquals; + return true; + case ">": + mathType = BurikoMathType.GreaterThan; + return true; + case "<": + mathType = BurikoMathType.LessThan; + return true; + case "+": + mathType = BurikoMathType.Add; + return true; + case "-": + mathType = BurikoMathType.Subtract; + return true; + case "*": + mathType = BurikoMathType.Multiply; + return true; + case "/": + mathType = BurikoMathType.Divide; + return true; + case "%": + mathType = BurikoMathType.Modulus; + return true; + default: + return false; + } + } + + public void OutputMath(BinaryWriter output) + { + BGIValue bGIValue = new BGIValue(baseTree.GetChild(0)); + BGIValue bGIValue2 = new BGIValue(baseTree.GetChild(1)); + output.Write((short)Type); + output.Write((short)mathType); + bGIValue.Output(); + bGIValue2.Output(); + } + + public void OutputVar(BinaryWriter output) + { + output.Write((short)Type); + output.Write(tree.Text); + int num = 1; + if (baseTree.ChildCount <= 1) + { + output.Write((short)2); + output.Write(-1); + output.Write(value: false); + } + else + { + ITree child = baseTree.GetChild(num); + if (child.Text == "INDEX") + { + BGIValue bGIValue = new BGIValue(child.GetChild(0)); + bGIValue.Output(); + num++; + } + else + { + output.Write((short)2); + output.Write(-1); + } + if (baseTree.ChildCount <= num) + { + output.Write(value: false); + } + else + { + ITree child2 = baseTree.GetChild(num); + if (child2.Text == "MEMBER") + { + output.Write(value: true); + ITree child3 = child2.GetChild(0); + BGIValue bGIValue2 = new BGIValue(child3); + bGIValue2.Output(); + } + else + { + output.Write(value: false); + } + } + } + } + + public void Output() + { + BinaryWriter output = BGItoMG.Instance.Output; + switch (Type) + { + case BurikoValueType.Int: + { + int value = int.Parse(tree.Text); + output.Write((short)Type); + output.Write(value); + break; + } + case BurikoValueType.String: + { + string text = tree.Text; + output.Write((short)Type); + output.Write(text.Substring(1, text.Length - 2).Replace("\\\"", "\"")); + break; + } + case BurikoValueType.Bool: + output.Write((short)Type); + output.Write(GetBool()); + break; + case BurikoValueType.Null: + output.Write((short)Type); + break; + case BurikoValueType.Math: + OutputMath(output); + break; + case BurikoValueType.Operation: + { + output.Write((short)Type); + OperationHandler operationHandler = new OperationHandler(); + operationHandler.ParseOperation(tree); + break; + } + case BurikoValueType.Variable: + OutputVar(output); + break; + default: + throw new Exception("Unhandled Variable Type " + Type); + } + } + } +} diff --git a/BGICompiler.Compiler/BGItoMG.cs b/BGICompiler.Compiler/BGItoMG.cs new file mode 100644 index 00000000..62cacd20 --- /dev/null +++ b/BGICompiler.Compiler/BGItoMG.cs @@ -0,0 +1,281 @@ +using Antlr.Runtime; +using Antlr.Runtime.Tree; +using AntlrTest; +using Assets.Scripts.Core.Buriko; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; + +namespace BGICompiler.Compiler +{ + public class BGItoMG + { + private readonly string filename; + + public MemoryStream Mstream; + + public BinaryWriter Output; + + private Dictionary blockList = new Dictionary(); + + private Dictionary lineLookup = new Dictionary(); + + public static BGItoMG Instance; + + private int cmdnum; + + public BGItoMG(string scriptname, string outname) + { + Instance = this; + filename = scriptname; + cmdnum = 0; + string[] lines = LoadScriptLines(); + string script = Preprocessor(lines); + Compile(script); + OutputFile(outname); + Output.Close(); + Mstream.Close(); + } + + public void OutputFile(string outname) + { + byte[] array = Mstream.ToArray(); + MemoryStream memoryStream = new MemoryStream(); + BinaryWriter binaryWriter = new BinaryWriter(memoryStream); + binaryWriter.Write("MGSC".ToCharArray(0, 4)); + binaryWriter.Write(1); + binaryWriter.Write(blockList.Count); + binaryWriter.Write(lineLookup.Count); + binaryWriter.Write(array.Length); + foreach (KeyValuePair block in blockList) + { + binaryWriter.Write(block.Key); + binaryWriter.Write(block.Value); + } + foreach (KeyValuePair item in lineLookup) + { + binaryWriter.Write(item.Value); + } + binaryWriter.Write(array); + File.WriteAllBytes(outname, memoryStream.ToArray()); + } + + public void OutputCmd(BurikoCommands cmd) + { + Output.Write((short)cmd); + } + + public void Cmd_Return() + { + OutputCmd(BurikoCommands.Return); + } + + public void Cmd_LineNum(int line) + { + OutputCmd(BurikoCommands.LineNum); + Output.Write(cmdnum); + if (!lineLookup.ContainsKey(cmdnum)) + { + lineLookup.Add(cmdnum, (int)Mstream.Position); + } + cmdnum++; + } + + public void OutputTree(ITree tree, int start = 0) + { + for (int i = start; i < tree.ChildCount; i++) + { + ITree child = tree.GetChild(i); + switch (child.ToString()) + { + case "IF": + Cmd_LineNum(child.Line); + ParseIf(child); + break; + case "OPERATION": + { + Cmd_LineNum(child.Line); + OutputCmd(BurikoCommands.Operation); + OperationHandler operationHandler = new OperationHandler(); + operationHandler.ParseOperation(child); + break; + } + case "VARDECL": + ParseVarDecl(child); + break; + case "ASSIGN": + ParseAssignment(child); + break; + default: + Debug.LogError("Unhandled type " + child.ToString()); + break; + } + } + } + + public void ParseAssignment(ITree tree) + { + OutputCmd(BurikoCommands.Assignment); + ITree child = tree.GetChild(0); + BGIValue bGIValue = new BGIValue(child); + bGIValue.Output(); + ITree child2 = tree.GetChild(1); + BGIValue bGIValue2 = new BGIValue(child2); + bGIValue2.Output(); + } + + public void ParseVarDecl(ITree tree) + { + OutputCmd(BurikoCommands.Declaration); + string text = tree.GetChild(0).Text; + ITree child = tree.GetChild(1); + string text2 = child.GetChild(0).Text; + Output.Write(text); + Output.Write(text2); + if (child.ChildCount > 1) + { + ITree child2 = child.GetChild(1); + if (child2.Text != "INDEX") + { + throw new Exception($"{child2.Line}: Invalid variable declaration!"); + } + BGIValue bGIValue = new BGIValue(child2.GetChild(0)); + bGIValue.Output(); + } + else + { + Output.Write((short)1); + } + } + + public void ParseIf(ITree tree) + { + BGIValue bGIValue = new BGIValue(tree.GetChild(0)); + Output.Write((short)3); + bGIValue.Output(); + long position = Mstream.Position; + Output.Write(0); + OutputTree(tree.GetChild(1)); + Output.Write((short)6); + long position2 = Mstream.Position; + Output.Write(0); + long position3 = Mstream.Position; + Mstream.Seek(position, SeekOrigin.Begin); + Output.Write((int)position3); + Mstream.Seek(position3, SeekOrigin.Begin); + OutputTree(tree.GetChild(2)); + long position4 = Mstream.Position; + Mstream.Seek(position2, SeekOrigin.Begin); + Output.Write((int)position4); + Mstream.Seek(position4, SeekOrigin.Begin); + } + + public void ParseBlock(CommonTree tree) + { + if (tree is CommonErrorNode) + { + CommonErrorNode commonErrorNode = (CommonErrorNode)tree; + throw new Exception($"Failed to parse block! Line {commonErrorNode.stop.Line - 1}:{commonErrorNode.stop.CharPositionInLine}\nException: {commonErrorNode.trappedException}"); + } + if (tree.Token.Text != "BLOCK") + { + throw new Exception($"Line {tree.Line}: Expected token type BLOCK (function declaration), got token {tree.Token.Text}"); + } + string text = tree.Children[0].Text; + if (blockList.ContainsKey(text)) + { + throw new Exception($"Line {tree.Line}: Function name '{text}' already previously declared."); + } + blockList.Add(text, (int)Mstream.Position); + OutputTree(tree, 1); + Cmd_LineNum(0); + Cmd_Return(); + } + + public void Compile(string script) + { + ANTLRStringStream input = new ANTLRStringStream(script); + bgitestLexer tokenSource = new bgitestLexer(input); + CommonTokenStream input2 = new CommonTokenStream(tokenSource); + bgitestParser bgitestParser = new bgitestParser(input2); + AstParserRuleReturnScope astParserRuleReturnScope = bgitestParser.program(); + Mstream = new MemoryStream(); + Output = new BinaryWriter(Mstream); + CommonTree tree = astParserRuleReturnScope.Tree; + if (tree.Token != null) + { + ParseBlock(tree); + } + else + { + foreach (CommonTree child in tree.Children) + { + ParseBlock(child); + } + } + } + + public string[] LoadScriptLines() + { + if (!File.Exists(filename)) + { + throw new FileNotFoundException(filename); + } + return File.ReadAllLines(filename); + } + + public string Preprocessor(string[] lines) + { + string text = string.Empty; + int num = 0; + foreach (string text2 in lines) + { + text += "\r\n"; + if (!(text2 == string.Empty) && !text2.StartsWith("//") && (num != 0 || !text2.StartsWith("#"))) + { + num += text2.Count((char f) => f == '{'); + num -= text2.Count((char f) => f == '}'); + if (num > 0 && text2.Length > 0 && !text2.StartsWith("\t") && !text2.StartsWith("{") && !text2.StartsWith("}")) + { + string text3 = text2.Replace("\"", "\\\""); + text3 = text3.Replace(", )", " )"); + if (text3.StartsWith("..")) + { + text3 = text3.Substring(2); + } + BurikoTextModes burikoTextModes = BurikoTextModes.Normal; + if (text3.EndsWith(">")) + { + burikoTextModes = BurikoTextModes.Continue; + text3 = text3.Substring(0, text3.Length - 1); + } + if (text3.EndsWith("<")) + { + burikoTextModes = BurikoTextModes.WaitThenContinue; + text3 = text3.Substring(0, text3.Length - 1); + } + if (text3.EndsWith("@") || text3.EndsWith("&")) + { + burikoTextModes = BurikoTextModes.WaitForInput; + text3 = text3.Substring(0, text3.Length - 1); + } + text += string.Format("\tOutputLine(NULL, \"{0}\", NULL, \"{0}\", {1});", text3, (int)burikoTextModes); + } + else + { + string text4 = text2.Replace(", )", " )"); + text4 = text4.Replace(",)", " )"); + text4 = text4.Replace("Line_Normal", "0"); + text4 = text4.Replace("Line_ContinueAfterTyping", "3"); + text4 = text4.Replace("Line_WaitForInput", "2"); + text4 = text4.Replace("Line_Continue", "1"); + text += text4; + } + } + } + return text; + } + } +} diff --git a/BGICompiler.Compiler/OpType.cs b/BGICompiler.Compiler/OpType.cs new file mode 100644 index 00000000..daf9acc2 --- /dev/null +++ b/BGICompiler.Compiler/OpType.cs @@ -0,0 +1,17 @@ +using Assets.Scripts.Core.Buriko; + +namespace BGICompiler.Compiler +{ + public class OpType + { + public BurikoOperations OpCode; + + public string Parameters; + + public OpType(BurikoOperations op, string param) + { + OpCode = op; + Parameters = param; + } + } +} diff --git a/BGICompiler.Compiler/OperationHandler.cs b/BGICompiler.Compiler/OperationHandler.cs new file mode 100644 index 00000000..53be9720 --- /dev/null +++ b/BGICompiler.Compiler/OperationHandler.cs @@ -0,0 +1,201 @@ +using Antlr.Runtime.Tree; +using Assets.Scripts.Core.Buriko; +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace BGICompiler.Compiler +{ + public class OperationHandler + { + private BinaryWriter output; + + private static Dictionary paramLookup = new Dictionary(); + + private static bool _isReady = false; + + private int line; + + private string name; + + public OperationHandler() + { + output = BGItoMG.Instance.Output; + if (!_isReady) + { + FillParamValues(); + } + _isReady = true; + } + + public void FillParamValues() + { + paramLookup.Add("StoreValueToLocalWork", new OpType(BurikoOperations.StoreValueToLocalWork, "vi")); + paramLookup.Add("LoadValueFromLocalWork", new OpType(BurikoOperations.LoadValueFromLocalWork, "v")); + paramLookup.Add("SetLocalFlag", new OpType(BurikoOperations.SetLocalFlag, "vi")); + paramLookup.Add("SetGlobalFlag", new OpType(BurikoOperations.SetGlobalFlag, "vi")); + paramLookup.Add("GetLocalFlag", new OpType(BurikoOperations.GetLocalFlag, "v")); + paramLookup.Add("GetGlobalFlag", new OpType(BurikoOperations.GetGlobalFlag, "v")); + paramLookup.Add("CallScript", new OpType(BurikoOperations.CallScript, "s")); + paramLookup.Add("JumpScript", new OpType(BurikoOperations.JumpScript, "s")); + paramLookup.Add("CallSection", new OpType(BurikoOperations.CallSection, "s")); + paramLookup.Add("JumpSection", new OpType(BurikoOperations.JumpSection, "s")); + paramLookup.Add("Wait", new OpType(BurikoOperations.Wait, "i")); + paramLookup.Add("WaitForInput", new OpType(BurikoOperations.WaitForInput, string.Empty)); + paramLookup.Add("SetValidityOfInput", new OpType(BurikoOperations.SetValidityOfInput, "b")); + paramLookup.Add("SetValidityOfSkipping", new OpType(BurikoOperations.SetValidityOfSkipping, "b")); + paramLookup.Add("SetValidityOfSaving", new OpType(BurikoOperations.SetValidityOfSaving, "b")); + paramLookup.Add("SetValidityOfUserEffectSpeed", new OpType(BurikoOperations.SetValidityOfUserEffectSpeed, "b")); + paramLookup.Add("OutputLine", new OpType(BurikoOperations.OutputLine, "ssssi")); + paramLookup.Add("OutputLineAll", new OpType(BurikoOperations.OutputLineAll, "ssi")); + paramLookup.Add("ClearMessage", new OpType(BurikoOperations.ClearMessage, string.Empty)); + paramLookup.Add("SetFontOfMessage", new OpType(BurikoOperations.SetFontOfMessage, "iii")); + paramLookup.Add("SetSpeedOfMessage", new OpType(BurikoOperations.SetSpeedOfMessage, "bi")); + paramLookup.Add("SetStyleOfMessageSwinging", new OpType(BurikoOperations.SetStyleOfMessageSwinging, "i")); + paramLookup.Add("DisableWindow", new OpType(BurikoOperations.DisableWindow, string.Empty)); + paramLookup.Add("SpringText", new OpType(BurikoOperations.SpringText, "ii")); + paramLookup.Add("Select", new OpType(BurikoOperations.Select, "iv")); + paramLookup.Add("PlayBGM", new OpType(BurikoOperations.PlayBGM, "isii")); + paramLookup.Add("StopBGM", new OpType(BurikoOperations.StopBGM, "i")); + paramLookup.Add("ChangeVolumeOfBGM", new OpType(BurikoOperations.ChangeVolumeOfBGM, "iii")); + paramLookup.Add("FadeOutBGM", new OpType(BurikoOperations.FadeOutBGM, "iib")); + paramLookup.Add("FadeOutMultiBGM", new OpType(BurikoOperations.FadeOutMultiBGM, "iiib")); + paramLookup.Add("PlaySE", new OpType(BurikoOperations.PlaySE, "isii")); + paramLookup.Add("StopSE", new OpType(BurikoOperations.StopSE, "i")); + paramLookup.Add("FadeOutSE", new OpType(BurikoOperations.FadeOutSE, "ii")); + paramLookup.Add("WaitToFinishSEPlaying", new OpType(BurikoOperations.WaitToFinishSEPlaying, "i")); + paramLookup.Add("PlayVoice", new OpType(BurikoOperations.PlayVoice, "isi")); + paramLookup.Add("WaitToFinishVoicePlaying", new OpType(BurikoOperations.WaitToFinishVoicePlaying, "i")); + paramLookup.Add("PreloadBitmap", new OpType(BurikoOperations.PreloadBitmap, "s")); + paramLookup.Add("StartShakingOfAllObjects", new OpType(BurikoOperations.StartShakingOfAllObjects, "iiiiib")); + paramLookup.Add("TerminateShakingOfAllObjects", new OpType(BurikoOperations.TerminateShakingOfAllObjects, "ib")); + paramLookup.Add("StartShakingOfWindow", new OpType(BurikoOperations.StartShakingOfWindow, "iiiiib")); + paramLookup.Add("TerminateShakingOfWindow", new OpType(BurikoOperations.TerminateShakingOfWindow, "ib")); + paramLookup.Add("StartShakingOfBustshot", new OpType(BurikoOperations.StartShakingOfBustshot, "iiiiiib")); + paramLookup.Add("TerminateShakingOfBustshot", new OpType(BurikoOperations.TerminateShakingOfBustshot, "iib")); + paramLookup.Add("StartShakingOfSprite", new OpType(BurikoOperations.StartShakingOfSprite, "iiiiiib")); + paramLookup.Add("TerminateShakingOfSprite", new OpType(BurikoOperations.TerminateShakingOfSprite, "iib")); + paramLookup.Add("ShakeScreen", new OpType(BurikoOperations.ShakeScreen, "iiiii")); + paramLookup.Add("ShakeScreenSx", new OpType(BurikoOperations.ShakeScreenSx, "ii")); + paramLookup.Add("DrawBG", new OpType(BurikoOperations.DrawBG, "sib")); + paramLookup.Add("FadeBG", new OpType(BurikoOperations.FadeBG, "ib")); + paramLookup.Add("DrawBGWithMask", new OpType(BurikoOperations.DrawBGWithMask, "ssiib")); + paramLookup.Add("DrawScene", new OpType(BurikoOperations.DrawScene, "si")); + paramLookup.Add("DrawSceneWithMask", new OpType(BurikoOperations.DrawSceneWithMask, "ssiii")); + paramLookup.Add("ChangeScene", new OpType(BurikoOperations.ChangeScene, "sii")); + paramLookup.Add("FadeScene", new OpType(BurikoOperations.FadeScene, "i")); + paramLookup.Add("FadeSceneWithMask", new OpType(BurikoOperations.FadeSceneWithMask, "siii")); + paramLookup.Add("DrawBustshot", new OpType(BurikoOperations.DrawBustshot, "isiiibiiiiiiiiib")); + paramLookup.Add("MoveBustshot", new OpType(BurikoOperations.MoveBustshot, "isiiiiib")); + paramLookup.Add("FadeBustshot", new OpType(BurikoOperations.FadeBustshot, "ibiiiiib")); + paramLookup.Add("DrawBustshotWithFiltering", new OpType(BurikoOperations.DrawBustshotWithFiltering, "issiiibiiiiiiib")); + paramLookup.Add("DrawFace", new OpType(BurikoOperations.DrawFace, "sib")); + paramLookup.Add("FadeFace", new OpType(BurikoOperations.FadeFace, "ib")); + paramLookup.Add("ExecutePlannedControl", new OpType(BurikoOperations.ExecutePlannedControl, "b")); + paramLookup.Add("DrawSprite", new OpType(BurikoOperations.DrawSprite, "issiiiiiibbiiiib")); + paramLookup.Add("DrawSpriteWithFiltering", new OpType(BurikoOperations.DrawSpriteWithFiltering, "issiiibbiiiib")); + paramLookup.Add("FadeSprite", new OpType(BurikoOperations.FadeSprite, "iib")); + paramLookup.Add("FadeSpriteWithFiltering", new OpType(BurikoOperations.FadeSpriteWithFiltering, "isiib")); + paramLookup.Add("MoveSprite", new OpType(BurikoOperations.MoveSprite, "iiiiiiiiib")); + paramLookup.Add("MoveSpriteEx", new OpType(BurikoOperations.MoveSpriteEx, "isiiviiiiib")); + paramLookup.Add("ControlMotionOfSprite", new OpType(BurikoOperations.ControlMotionOfSprite, "iivi")); + paramLookup.Add("GetPositionOfSprite", new OpType(BurikoOperations.GetPositionOfSprite, "vi")); + paramLookup.Add("EnableHorizontalGradation", new OpType(BurikoOperations.EnableHorizontalGradation, "iib")); + paramLookup.Add("DisableGradation", new OpType(BurikoOperations.DisableGradation, "ib")); + paramLookup.Add("EnlargeScreen", new OpType(BurikoOperations.EnlargeScreen, "iiiibib")); + paramLookup.Add("DisableEffector", new OpType(BurikoOperations.DisableEffector, "ib")); + paramLookup.Add("EnableBlur", new OpType(BurikoOperations.EnableBlur, "iib")); + paramLookup.Add("DisableBlur", new OpType(BurikoOperations.DisableBlur, "ib")); + paramLookup.Add("DrawFilm", new OpType(BurikoOperations.DrawFilm, "iiiiiiib")); + paramLookup.Add("FadeFilm", new OpType(BurikoOperations.FadeFilm, "ib")); + paramLookup.Add("SetValidityOfFilmToFace", new OpType(BurikoOperations.SetValidityOfFilmToFace, "b")); + paramLookup.Add("FadeAllBustshots", new OpType(BurikoOperations.FadeAllBustshots, "ib")); + paramLookup.Add("FadeBustshotWithFiltering", new OpType(BurikoOperations.FadeBustshotWithFiltering, "isibiiib")); + paramLookup.Add("SetDrawingPointOfMessage", new OpType(BurikoOperations.SetDrawingPointOfMessage, "ii")); + paramLookup.Add("Negative", new OpType(BurikoOperations.Negative, "ib")); + paramLookup.Add("EnableJumpingOfReturnIcon", new OpType(BurikoOperations.EnableJumpingOfReturnIcon, string.Empty)); + paramLookup.Add("SetValidityOfWindowDisablingWhenGraphicsControl", new OpType(BurikoOperations.SetValidityOfWindowDisablingWhenGraphicsControl, "b")); + paramLookup.Add("SetValidityOfInterface", new OpType(BurikoOperations.SetValidityOfInterface, "b")); + paramLookup.Add("ShowExtras", new OpType(BurikoOperations.ViewExtras, string.Empty)); + paramLookup.Add("ShowChapterScreen", new OpType(BurikoOperations.ViewChapterScreen, string.Empty)); + paramLookup.Add("ShowTips", new OpType(BurikoOperations.ViewTips, "i")); + paramLookup.Add("ShowChapterPreview", new OpType(BurikoOperations.ChapterPreview, string.Empty)); + paramLookup.Add("SavePoint", new OpType(BurikoOperations.SavePoint, "ss")); + paramLookup.Add("SetValidityOfTextFade", new OpType(BurikoOperations.SetTextFade, "b")); + paramLookup.Add("LanguagePrompt", new OpType(BurikoOperations.LanguagePrompt, string.Empty)); + paramLookup.Add("GetAchievement", new OpType(BurikoOperations.GetAchievement, "s")); + paramLookup.Add("CheckTipsAchievements", new OpType(BurikoOperations.CheckTipsAchievements, string.Empty)); + paramLookup.Add("SetFontId", new OpType(BurikoOperations.SetFontId, "i")); + paramLookup.Add("SetCharSpacing", new OpType(BurikoOperations.SetCharSpacing, "i")); + paramLookup.Add("SetLineSpacing", new OpType(BurikoOperations.SetLineSpacing, "i")); + paramLookup.Add("SetFontSize", new OpType(BurikoOperations.SetFontSize, "i")); + paramLookup.Add("SetWindowPos", new OpType(BurikoOperations.SetWindowPos, "ii")); + paramLookup.Add("SetWindowSize", new OpType(BurikoOperations.SetWindowSize, "ii")); + paramLookup.Add("SetWindowMargins", new OpType(BurikoOperations.SetWindowMargins, "iiii")); + paramLookup.Add("PlaceViewTip", new OpType(BurikoOperations.PlaceViewTip, "i")); + paramLookup.Add("PlaceViewTip2", new OpType(BurikoOperations.PlaceViewTip2, "ii")); + paramLookup.Add("DrawStandgraphic", new OpType(BurikoOperations.DrawStandgraphic, "isbiib")); + paramLookup.Add("DrawBustFace", new OpType(BurikoOperations.DrawBustFace, "isbi")); + paramLookup.Add("PlusStandgraphic1", new OpType(BurikoOperations.PlusStandgraphic1, "is")); + paramLookup.Add("PlusStandgraphic2", new OpType(BurikoOperations.PlusStandgraphic2, "is")); + paramLookup.Add("PlusStandgraphic3", new OpType(BurikoOperations.PlusStandgraphic3, "is")); + paramLookup.Add("FadeAllBustshots2", new OpType(BurikoOperations.FadeAllBustshots2, "ib")); + paramLookup.Add("FadeAllBustshots3", new OpType(BurikoOperations.FadeAllBustshots3, "ib")); + paramLookup.Add("BlurOffOn", new OpType(BurikoOperations.BlurOffOn, "ii")); + paramLookup.Add("TitleScreen", new OpType(BurikoOperations.TitleScreen, string.Empty)); + paramLookup.Add("OpenGallery", new OpType(BurikoOperations.OpenGallery, string.Empty)); + paramLookup.Add("HideGallery", new OpType(BurikoOperations.HideGallery, string.Empty)); + paramLookup.Add("RevealGallery", new OpType(BurikoOperations.RevealGallery, string.Empty)); + paramLookup.Add("CloseGallery", new OpType(BurikoOperations.CloseGallery, string.Empty)); + paramLookup.Add("SetSkipAll", new OpType(BurikoOperations.SetSkipAll, "b")); + paramLookup.Add("SetNameFormat", new OpType(BurikoOperations.SetNameFormat, "s")); + paramLookup.Add("SetScreenAspect", new OpType(BurikoOperations.SetScreenAspect, "s")); + paramLookup.Add("SetGUIPosition", new OpType(BurikoOperations.SetGuiPosition, "ii")); + paramLookup.Add("Break", new OpType(BurikoOperations.Break, string.Empty)); + } + + public void ParamCheck(string op, BGIParameters param) + { + if (!paramLookup.TryGetValue(op, out OpType value) || param.CheckParamSig(value.Parameters)) + { + return; + } + throw new Exception(string.Format("{0}: {1} - {2}", line - 1, name, "Parameters were not of expected type!")); + } + + public void OutputOpType(OpType op) + { + output.Write((short)op.OpCode); + } + + public void CmdOpNull() + { + output.Write((short)(-1)); + } + + public void OutputCmd(string name, BGIParameters param) + { + OpType op = paramLookup[name]; + ParamCheck(name, param); + OutputOpType(op); + param.OutputAllParams(); + } + + public void ParseOperation(ITree tree) + { + name = tree.GetChild(0).Text; + line = tree.Line; + BGIParameters param = (tree.ChildCount <= 1) ? new BGIParameters() : new BGIParameters(tree.GetChild(1)); + if (paramLookup.ContainsKey(name)) + { + OutputCmd(name, param); + } + else + { + Debug.LogError("Unhandled Operation " + name); + CmdOpNull(); + } + } + } +} diff --git a/BMFont.cs b/BMFont.cs new file mode 100644 index 00000000..33621247 --- /dev/null +++ b/BMFont.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[Serializable] +public class BMFont +{ + [HideInInspector] + [SerializeField] + private int mSize = 16; + + [HideInInspector] + [SerializeField] + private int mBase; + + [HideInInspector] + [SerializeField] + private int mWidth; + + [HideInInspector] + [SerializeField] + private int mHeight; + + [HideInInspector] + [SerializeField] + private string mSpriteName; + + [HideInInspector] + [SerializeField] + private List mSaved = new List(); + + private Dictionary mDict = new Dictionary(); + + public bool isValid => mSaved.Count > 0; + + public int charSize + { + get + { + return mSize; + } + set + { + mSize = value; + } + } + + public int baseOffset + { + get + { + return mBase; + } + set + { + mBase = value; + } + } + + public int texWidth + { + get + { + return mWidth; + } + set + { + mWidth = value; + } + } + + public int texHeight + { + get + { + return mHeight; + } + set + { + mHeight = value; + } + } + + public int glyphCount => isValid ? mSaved.Count : 0; + + public string spriteName + { + get + { + return mSpriteName; + } + set + { + mSpriteName = value; + } + } + + public List glyphs => mSaved; + + public BMGlyph GetGlyph(int index, bool createIfMissing) + { + BMGlyph value = null; + if (mDict.Count == 0) + { + int i = 0; + for (int count = mSaved.Count; i < count; i++) + { + BMGlyph bMGlyph = mSaved[i]; + mDict.Add(bMGlyph.index, bMGlyph); + } + } + if (!mDict.TryGetValue(index, out value) && createIfMissing) + { + value = new BMGlyph(); + value.index = index; + mSaved.Add(value); + mDict.Add(index, value); + } + return value; + } + + public BMGlyph GetGlyph(int index) + { + return GetGlyph(index, createIfMissing: false); + } + + public void Clear() + { + mDict.Clear(); + mSaved.Clear(); + } + + public void Trim(int xMin, int yMin, int xMax, int yMax) + { + if (isValid) + { + int i = 0; + for (int count = mSaved.Count; i < count; i++) + { + mSaved[i]?.Trim(xMin, yMin, xMax, yMax); + } + } + } +} diff --git a/BMGlyph.cs b/BMGlyph.cs new file mode 100644 index 00000000..4907fe22 --- /dev/null +++ b/BMGlyph.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +[Serializable] +public class BMGlyph +{ + public int index; + + public int x; + + public int y; + + public int width; + + public int height; + + public int offsetX; + + public int offsetY; + + public int advance; + + public int channel; + + public List kerning; + + public int GetKerning(int previousChar) + { + if (kerning != null && previousChar != 0) + { + int i = 0; + for (int count = kerning.Count; i < count; i += 2) + { + if (kerning[i] == previousChar) + { + return kerning[i + 1]; + } + } + } + return 0; + } + + public void SetKerning(int previousChar, int amount) + { + if (kerning == null) + { + kerning = new List(); + } + for (int i = 0; i < kerning.Count; i += 2) + { + if (kerning[i] == previousChar) + { + kerning[i + 1] = amount; + return; + } + } + kerning.Add(previousChar); + kerning.Add(amount); + } + + public void Trim(int xMin, int yMin, int xMax, int yMax) + { + int num = x + width; + int num2 = y + height; + if (x < xMin) + { + int num3 = xMin - x; + x += num3; + width -= num3; + offsetX += num3; + } + if (y < yMin) + { + int num4 = yMin - y; + y += num4; + height -= num4; + offsetY += num4; + } + if (num > xMax) + { + width -= num - xMax; + } + if (num2 > yMax) + { + height -= num2 - yMax; + } + } +} diff --git a/BMSymbol.cs b/BMSymbol.cs new file mode 100644 index 00000000..53696399 --- /dev/null +++ b/BMSymbol.cs @@ -0,0 +1,93 @@ +using System; +using UnityEngine; + +[Serializable] +public class BMSymbol +{ + public string sequence; + + public string spriteName; + + private UISpriteData mSprite; + + private bool mIsValid; + + private int mLength; + + private int mOffsetX; + + private int mOffsetY; + + private int mWidth; + + private int mHeight; + + private int mAdvance; + + private Rect mUV; + + public int length + { + get + { + if (mLength == 0) + { + mLength = sequence.Length; + } + return mLength; + } + } + + public int offsetX => mOffsetX; + + public int offsetY => mOffsetY; + + public int width => mWidth; + + public int height => mHeight; + + public int advance => mAdvance; + + public Rect uvRect => mUV; + + public void MarkAsChanged() + { + mIsValid = false; + } + + public bool Validate(UIAtlas atlas) + { + if (atlas == null) + { + return false; + } + if (!mIsValid) + { + if (string.IsNullOrEmpty(spriteName)) + { + return false; + } + mSprite = ((!(atlas != null)) ? null : atlas.GetSprite(spriteName)); + if (mSprite != null) + { + Texture texture = atlas.texture; + if (texture == null) + { + mSprite = null; + } + else + { + mUV = new Rect((float)mSprite.x, (float)mSprite.y, (float)mSprite.width, (float)mSprite.height); + mUV = NGUIMath.ConvertToTexCoords(mUV, texture.width, texture.height); + mOffsetX = mSprite.paddingLeft; + mOffsetY = mSprite.paddingTop; + mWidth = mSprite.width; + mHeight = mSprite.height; + mAdvance = mSprite.width + (mSprite.paddingLeft + mSprite.paddingRight); + mIsValid = true; + } + } + } + return mSprite != null; + } +} diff --git a/Back.cs b/Back.cs new file mode 100644 index 00000000..40611402 --- /dev/null +++ b/Back.cs @@ -0,0 +1,43 @@ +internal class Back : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + double num = 1.70158; + return c * (t /= d) * t * ((num + 1.0) * t - num) + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + double num = 1.70158; + return c * ((t = t / d - 1.0) * t * ((num + 1.0) * t + num) + 1.0) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + double num = 1.70158; + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * (t * t * (((num *= 1.525) + 1.0) * t - num)) + b; + } + return c / 2.0 * ((t -= 2.0) * t * (((num *= 1.525) + 1.0) * t + num) + 2.0) + b; + } + + public static double EaseIn(double t, double b, double c, double d, double s) + { + return c * (t /= d) * t * ((s + 1.0) * t - s) + b; + } + + public static double EaseOut(double t, double b, double c, double d, double s) + { + return c * ((t = t / d - 1.0) * t * ((s + 1.0) * t + s) + 1.0) + b; + } + + public static double EaseInOut(double t, double b, double c, double d, double s) + { + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * (t * t * (((s *= 1.525) + 1.0) * t - s)) + b; + } + return c / 2.0 * ((t -= 2.0) * t * (((s *= 1.525) + 1.0) * t + s) + 2.0) + b; + } +} diff --git a/BetterList.cs b/BetterList.cs new file mode 100644 index 00000000..6754edca --- /dev/null +++ b/BetterList.cs @@ -0,0 +1,221 @@ +using System.Collections.Generic; +using System.Diagnostics; +using UnityEngine; + +public class BetterList +{ + public delegate int CompareFunc(T left, T right); + + public T[] buffer; + + public int size; + + [DebuggerHidden] + public T this[int i] + { + get + { + return buffer[i]; + } + set + { + buffer[i] = value; + } + } + + [DebuggerStepThrough] + public IEnumerator GetEnumerator() + { + if (buffer != null) + { + for (int i = 0; i < size; i++) + { + yield return buffer[i]; + } + } + } + + private void AllocateMore() + { + T[] array = (buffer == null) ? new T[32] : new T[Mathf.Max(buffer.Length << 1, 32)]; + if (buffer != null && size > 0) + { + buffer.CopyTo(array, 0); + } + buffer = array; + } + + private void Trim() + { + if (size > 0) + { + if (size < buffer.Length) + { + T[] array = new T[size]; + for (int i = 0; i < size; i++) + { + array[i] = buffer[i]; + } + buffer = array; + } + } + else + { + buffer = null; + } + } + + public void Clear() + { + size = 0; + } + + public void Release() + { + size = 0; + buffer = null; + } + + public void Add(T item) + { + if (buffer == null || size == buffer.Length) + { + AllocateMore(); + } + buffer[size++] = item; + } + + public void Insert(int index, T item) + { + if (buffer == null || size == buffer.Length) + { + AllocateMore(); + } + if (index > -1 && index < size) + { + for (int num = size; num > index; num--) + { + buffer[num] = buffer[num - 1]; + } + buffer[index] = item; + size++; + } + else + { + Add(item); + } + } + + public bool Contains(T item) + { + if (buffer == null) + { + return false; + } + for (int i = 0; i < size; i++) + { + if (buffer[i].Equals(item)) + { + return true; + } + } + return false; + } + + public int IndexOf(T item) + { + if (buffer == null) + { + return -1; + } + for (int i = 0; i < size; i++) + { + if (buffer[i].Equals(item)) + { + return i; + } + } + return -1; + } + + public bool Remove(T item) + { + if (buffer != null) + { + EqualityComparer @default = EqualityComparer.Default; + for (int i = 0; i < size; i++) + { + if (@default.Equals(buffer[i], item)) + { + size--; + buffer[i] = default(T); + for (int j = i; j < size; j++) + { + buffer[j] = buffer[j + 1]; + } + buffer[size] = default(T); + return true; + } + } + } + return false; + } + + public void RemoveAt(int index) + { + if (buffer != null && index > -1 && index < size) + { + size--; + buffer[index] = default(T); + for (int i = index; i < size; i++) + { + buffer[i] = buffer[i + 1]; + } + buffer[size] = default(T); + } + } + + public T Pop() + { + if (buffer != null && size != 0) + { + T result = buffer[--size]; + buffer[size] = default(T); + return result; + } + return default(T); + } + + public T[] ToArray() + { + Trim(); + return buffer; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public void Sort(CompareFunc comparer) + { + int num = 0; + int num2 = size - 1; + bool flag = true; + while (flag) + { + flag = false; + for (int i = num; i < num2; i++) + { + if (comparer(buffer[i], buffer[i + 1]) > 0) + { + T val = buffer[i]; + buffer[i] = buffer[i + 1]; + buffer[i + 1] = val; + flag = true; + } + else if (!flag) + { + num = ((i != 0) ? (i - 1) : 0); + } + } + } + } +} diff --git a/Bounce.cs b/Bounce.cs new file mode 100644 index 00000000..d56fa893 --- /dev/null +++ b/Bounce.cs @@ -0,0 +1,33 @@ +internal class Bounce : Ease +{ + public static double EaseOut(double t, double b, double c, double d) + { + if ((t /= d) < 0.36363636363636365) + { + return c * (7.5625 * t * t) + b; + } + if (t < 0.72727272727272729) + { + return c * (7.5625 * (t -= 0.54545454545454541) * t + 0.75) + b; + } + if (t < 0.90909090909090906) + { + return c * (7.5625 * (t -= 0.81818181818181823) * t + 0.9375) + b; + } + return c * (7.5625 * (t -= 0.95454545454545459) * t + 0.984375) + b; + } + + public static double EaseIn(double t, double b, double c, double d) + { + return c - EaseOut(d - t, 0.0, c, d) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if (t < d / 2.0) + { + return EaseIn(t * 2.0, 0.0, c, d) * 0.5 + b; + } + return EaseOut(t * 2.0 - d, 0.0, c, d) * 0.5 + c * 0.5 + b; + } +} diff --git a/ByteReader.cs b/ByteReader.cs new file mode 100644 index 00000000..4fded53e --- /dev/null +++ b/ByteReader.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEngine; + +public class ByteReader +{ + private byte[] mBuffer; + + private int mOffset; + + private static BetterList mTemp = new BetterList(); + + public bool canRead => mBuffer != null && mOffset < mBuffer.Length; + + public ByteReader(byte[] bytes) + { + mBuffer = bytes; + } + + public ByteReader(TextAsset asset) + { + mBuffer = asset.bytes; + } + + public static ByteReader Open(string path) + { + FileStream fileStream = File.OpenRead(path); + if (fileStream != null) + { + fileStream.Seek(0L, SeekOrigin.End); + byte[] array = new byte[fileStream.Position]; + fileStream.Seek(0L, SeekOrigin.Begin); + fileStream.Read(array, 0, array.Length); + fileStream.Close(); + return new ByteReader(array); + } + return null; + } + + private static string ReadLine(byte[] buffer, int start, int count) + { + return Encoding.UTF8.GetString(buffer, start, count); + } + + public string ReadLine() + { + return ReadLine(skipEmptyLines: true); + } + + public string ReadLine(bool skipEmptyLines) + { + int num = mBuffer.Length; + if (skipEmptyLines) + { + while (mOffset < num && mBuffer[mOffset] < 32) + { + mOffset++; + } + } + int num2 = mOffset; + if (num2 < num) + { + int num4; + do + { + if (num2 >= num) + { + num2++; + break; + } + num4 = mBuffer[num2++]; + } + while (num4 != 10 && num4 != 13); + string result = ReadLine(mBuffer, mOffset, num2 - mOffset - 1); + mOffset = num2; + return result; + } + mOffset = num; + return null; + } + + public Dictionary ReadDictionary() + { + Dictionary dictionary = new Dictionary(); + char[] separator = new char[1] + { + '=' + }; + while (canRead) + { + string text = ReadLine(); + if (text == null) + { + break; + } + if (!text.StartsWith("//")) + { + string[] array = text.Split(separator, 2, StringSplitOptions.RemoveEmptyEntries); + if (array.Length == 2) + { + string key = array[0].Trim(); + string text3 = dictionary[key] = array[1].Trim().Replace("\\n", "\n"); + } + } + } + return dictionary; + } + + public BetterList ReadCSV() + { + mTemp.Clear(); + string text = string.Empty; + bool flag = false; + int num = 0; + while (canRead) + { + if (flag) + { + string text2 = ReadLine(skipEmptyLines: false); + if (text2 == null) + { + return null; + } + text2 = text2.Replace("\\n", "\n"); + text = text + "\n" + text2; + } + else + { + text = ReadLine(skipEmptyLines: true); + if (text == null) + { + return null; + } + text = text.Replace("\\n", "\n"); + num = 0; + } + int i = num; + for (int length = text.Length; i < length; i++) + { + switch (text[i]) + { + case ',': + if (!flag) + { + mTemp.Add(text.Substring(num, i - num)); + num = i + 1; + } + break; + case '"': + if (flag) + { + if (i + 1 >= length) + { + mTemp.Add(text.Substring(num, i - num).Replace("\"\"", "\"")); + return mTemp; + } + if (text[i + 1] != '"') + { + mTemp.Add(text.Substring(num, i - num).Replace("\"\"", "\"")); + flag = false; + if (text[i + 1] == ',') + { + i++; + num = i + 1; + } + } + else + { + i++; + } + } + else + { + num = i + 1; + flag = true; + } + break; + } + } + if (num < text.Length) + { + if (flag) + { + continue; + } + mTemp.Add(text.Substring(num, text.Length - num)); + } + return mTemp; + } + return null; + } +} diff --git a/CLZF2.cs b/CLZF2.cs new file mode 100644 index 00000000..c81fe0aa --- /dev/null +++ b/CLZF2.cs @@ -0,0 +1,201 @@ +using System; + +public static class CLZF2 +{ + private static readonly uint HLOG = 14u; + + private static readonly uint HSIZE = 16384u; + + private static readonly uint MAX_LIT = 32u; + + private static readonly uint MAX_OFF = 8192u; + + private static readonly uint MAX_REF = 264u; + + private static readonly long[] HashTable = new long[HSIZE]; + + public static byte[] Compress(byte[] inputBytes) + { + int num = inputBytes.Length * 2; + byte[] output = new byte[num]; + int num2; + for (num2 = lzf_compress(inputBytes, ref output); num2 == 0; num2 = lzf_compress(inputBytes, ref output)) + { + num *= 2; + output = new byte[num]; + } + byte[] array = new byte[num2]; + Buffer.BlockCopy(output, 0, array, 0, num2); + return array; + } + + public static byte[] Decompress(byte[] inputBytes) + { + int num = inputBytes.Length * 2; + byte[] output = new byte[num]; + int num2; + for (num2 = lzf_decompress(inputBytes, ref output); num2 == 0; num2 = lzf_decompress(inputBytes, ref output)) + { + num *= 2; + output = new byte[num]; + } + byte[] array = new byte[num2]; + Buffer.BlockCopy(output, 0, array, 0, num2); + return array; + } + + public static int lzf_compress(byte[] input, ref byte[] output) + { + int num = input.Length; + int num2 = output.Length; + Array.Clear(HashTable, 0, (int)HSIZE); + uint num3 = 0u; + uint num4 = 0u; + uint num5 = (uint)((input[num3] << 8) | input[num3 + 1]); + int num6 = 0; + while (true) + { + if (num3 < num - 2) + { + num5 = ((num5 << 8) | input[num3 + 2]); + long num7 = ((num5 ^ (num5 << 5)) >> (int)(24 - HLOG - num5 * 5)) & (HSIZE - 1); + long num8 = HashTable[num7]; + HashTable[num7] = num3; + long num9; + if ((num9 = num3 - num8 - 1) < MAX_OFF && num3 + 4 < num && num8 > 0 && input[num8] == input[num3] && input[num8 + 1] == input[num3 + 1] && input[num8 + 2] == input[num3 + 2]) + { + uint num10 = 2u; + uint num11 = (uint)(num - (int)num3 - (int)num10); + num11 = ((num11 <= MAX_REF) ? num11 : MAX_REF); + if (num4 + num6 + 1 + 3 >= num2) + { + return 0; + } + do + { + num10++; + } + while (num10 < num11 && input[num8 + num10] == input[num3 + num10]); + if (num6 != 0) + { + output[num4++] = (byte)(num6 - 1); + num6 = -num6; + do + { + output[num4++] = input[num3 + num6]; + } + while (++num6 != 0); + } + num10 -= 2; + num3++; + if (num10 < 7) + { + output[num4++] = (byte)((num9 >> 8) + (num10 << 5)); + } + else + { + output[num4++] = (byte)((num9 >> 8) + 224); + output[num4++] = (byte)(num10 - 7); + } + output[num4++] = (byte)num9; + num3 += num10 - 1; + num5 = (uint)((input[num3] << 8) | input[num3 + 1]); + num5 = ((num5 << 8) | input[num3 + 2]); + HashTable[((num5 ^ (num5 << 5)) >> (int)(24 - HLOG - num5 * 5)) & (HSIZE - 1)] = num3; + num3++; + num5 = ((num5 << 8) | input[num3 + 2]); + HashTable[((num5 ^ (num5 << 5)) >> (int)(24 - HLOG - num5 * 5)) & (HSIZE - 1)] = num3; + num3++; + continue; + } + } + else if (num3 == num) + { + break; + } + num6++; + num3++; + if (num6 == MAX_LIT) + { + if (num4 + 1 + MAX_LIT >= num2) + { + return 0; + } + output[num4++] = (byte)(MAX_LIT - 1); + num6 = -num6; + do + { + output[num4++] = input[num3 + num6]; + } + while (++num6 != 0); + } + } + if (num6 != 0) + { + if (num4 + num6 + 1 >= num2) + { + return 0; + } + output[num4++] = (byte)(num6 - 1); + num6 = -num6; + do + { + output[num4++] = input[num3 + num6]; + } + while (++num6 != 0); + } + return (int)num4; + } + + public static int lzf_decompress(byte[] input, ref byte[] output) + { + int num = input.Length; + int num2 = output.Length; + uint num3 = 0u; + uint num4 = 0u; + do + { + uint num6 = input[num3++]; + if (num6 < 32) + { + num6++; + if (num4 + num6 > num2) + { + return 0; + } + do + { + output[num4++] = input[num3++]; + } + while (--num6 != 0); + } + else + { + uint num9 = num6 >> 5; + int num10 = (int)(num4 - ((num6 & 0x1F) << 8) - 1); + if (num9 == 7) + { + num9 += input[num3++]; + } + num10 -= input[num3++]; + if (num4 + num9 + 2 > num2) + { + return 0; + } + if (num10 < 0) + { + return 0; + } + output[num4++] = output[num10++]; + output[num4++] = output[num10++]; + do + { + output[num4++] = output[num10++]; + } + while (--num9 != 0); + } + } + while (num3 < num); + return (int)num4; + } +} diff --git a/Circ.cs b/Circ.cs new file mode 100644 index 00000000..6a45f3ca --- /dev/null +++ b/Circ.cs @@ -0,0 +1,23 @@ +using System; + +internal class Circ : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return (0.0 - c) * (Math.Sqrt(1.0 - (t /= d) * t) - 1.0) + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return c * Math.Sqrt(1.0 - (t = t / d - 1.0) * t) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if ((t /= d / 2.0) < 1.0) + { + return (0.0 - c) / 2.0 * (Math.Sqrt(1.0 - t * t) - 1.0) + b; + } + return c / 2.0 * (Math.Sqrt(1.0 - (t -= 2.0) * t) + 1.0) + b; + } +} diff --git a/ConfigButton.cs b/ConfigButton.cs new file mode 100644 index 00000000..7efc8a4b --- /dev/null +++ b/ConfigButton.cs @@ -0,0 +1,45 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using Assets.Scripts.UI.Config; +using UnityEngine; + +public class ConfigButton : MonoBehaviour +{ + public ConfigManager ConfigManager; + + private float cooldown; + + private void OnClick() + { + if (!(cooldown > 0f) && UICamera.currentTouchID == -1) + { + switch (base.name) + { + case "Return": + GameSystem.Instance.LeaveConfigScreen(null); + break; + } + AudioController.Instance.PlaySystemSound("wa_038.ogg", 1); + cooldown = 1f; + } + } + + private void OnHover(bool ishover) + { + if (!(cooldown > 0f)) + { + } + } + + private void Start() + { + } + + private void Update() + { + if (cooldown > 0f) + { + cooldown -= Time.deltaTime; + } + } +} diff --git a/Cubic.cs b/Cubic.cs new file mode 100644 index 00000000..aee3304e --- /dev/null +++ b/Cubic.cs @@ -0,0 +1,21 @@ +internal class Cubic : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return c * (t /= d) * t * t + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return c * ((t = t / d - 1.0) * t * t + 1.0) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * t * t * t + b; + } + return c / 2.0 * ((t -= 2.0) * t * t + 2.0) + b; + } +} diff --git a/DLLs/Antlr3.Runtime.dll b/DLLs/Antlr3.Runtime.dll new file mode 100644 index 00000000..a3ea1d36 Binary files /dev/null and b/DLLs/Antlr3.Runtime.dll differ diff --git a/DLLs/Assembly-CSharp-firstpass.dll b/DLLs/Assembly-CSharp-firstpass.dll new file mode 100644 index 00000000..c1174d54 Binary files /dev/null and b/DLLs/Assembly-CSharp-firstpass.dll differ diff --git a/DLLs/NVorbis.dll b/DLLs/NVorbis.dll new file mode 100644 index 00000000..13b79e6a Binary files /dev/null and b/DLLs/NVorbis.dll differ diff --git a/DLLs/System.Core.dll b/DLLs/System.Core.dll new file mode 100644 index 00000000..dbe2f999 Binary files /dev/null and b/DLLs/System.Core.dll differ diff --git a/DLLs/UnityEngine.UI.dll b/DLLs/UnityEngine.UI.dll new file mode 100644 index 00000000..0dd0f7fa Binary files /dev/null and b/DLLs/UnityEngine.UI.dll differ diff --git a/DLLs/UnityEngine.dll b/DLLs/UnityEngine.dll new file mode 100644 index 00000000..88d3d57e Binary files /dev/null and b/DLLs/UnityEngine.dll differ diff --git a/DestroySelf.cs b/DestroySelf.cs new file mode 100644 index 00000000..3a1ae82b --- /dev/null +++ b/DestroySelf.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +public class DestroySelf : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + Object.Destroy(base.gameObject); + } +} diff --git a/Ease.cs b/Ease.cs new file mode 100644 index 00000000..ce219a59 --- /dev/null +++ b/Ease.cs @@ -0,0 +1,6 @@ +internal abstract class Ease +{ + protected const double TWO_PI = 6.2831853071795862; + + protected const double HALF_PI = 1.5707963267948966; +} diff --git a/EaseDelegate.cs b/EaseDelegate.cs new file mode 100644 index 00000000..65162d52 --- /dev/null +++ b/EaseDelegate.cs @@ -0,0 +1 @@ +public delegate double EaseDelegate(double t, double b, double c, double d); diff --git a/Elastic.cs b/Elastic.cs new file mode 100644 index 00000000..a98968ca --- /dev/null +++ b/Elastic.cs @@ -0,0 +1,168 @@ +using System; + +internal class Elastic : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + double num = 0.0; + double num2 = d * 0.3; + if (t == 0.0) + { + return b; + } + if ((t /= d) == 1.0) + { + return b + c; + } + double num3; + if (num < Math.Abs(c)) + { + num = c; + num3 = num2 / 4.0; + } + else + { + num3 = num2 / 6.2831853071795862 * Math.Asin(c / num); + } + return 0.0 - num * Math.Pow(2.0, 10.0 * (t -= 1.0)) * Math.Sin((t * d - num3) * 6.2831853071795862 / num2) + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + double num = 0.0; + double num2 = d * 0.3; + if (t == 0.0) + { + return b; + } + if ((t /= d) == 1.0) + { + return b + c; + } + double num3; + if (num < Math.Abs(c)) + { + num = c; + num3 = num2 / 4.0; + } + else + { + num3 = num2 / 6.2831853071795862 * Math.Asin(c / num); + } + return num * Math.Pow(2.0, -10.0 * t) * Math.Sin((t * d - num3) * 6.2831853071795862 / num2) + c + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + double num = 0.0; + double num2 = d * 0.44999999999999996; + if (t == 0.0) + { + return b; + } + if ((t /= d / 2.0) == 2.0) + { + return b + c; + } + double num3; + if (num < Math.Abs(c)) + { + num = c; + num3 = num2 / 4.0; + } + else + { + num3 = num2 / 6.2831853071795862 * Math.Asin(c / num); + } + if (t < 1.0) + { + return -0.5 * (num * Math.Pow(2.0, 10.0 * (t -= 1.0)) * Math.Sin((t * d - num3) * 6.2831853071795862 / num2)) + b; + } + return num * Math.Pow(2.0, -10.0 * (t -= 1.0)) * Math.Sin((t * d - num3) * 6.2831853071795862 / num2) * 0.5 + c + b; + } + + public static double EaseIn(double t, double b, double c, double d, double a, double p) + { + if (t == 0.0) + { + return b; + } + if ((t /= d) == 1.0) + { + return b + c; + } + if (p == 0.0) + { + p = d * 0.3; + } + double num; + if (a < Math.Abs(c)) + { + a = c; + num = p / 4.0; + } + else + { + num = p / 6.2831853071795862 * Math.Asin(c / a); + } + return 0.0 - a * Math.Pow(2.0, 10.0 * (t -= 1.0)) * Math.Sin((t * d - num) * 6.2831853071795862 / p) + b; + } + + public static double EaseOut(double t, double b, double c, double d, double a, double p) + { + if (t == 0.0) + { + return b; + } + if ((t /= d) == 1.0) + { + return b + c; + } + if (p == 0.0) + { + p = d * 0.3; + } + double num; + if (a < Math.Abs(c)) + { + a = c; + num = p / 4.0; + } + else + { + num = p / 6.2831853071795862 * Math.Asin(c / a); + } + return a * Math.Pow(2.0, -10.0 * t) * Math.Sin((t * d - num) * 6.2831853071795862 / p) + c + b; + } + + public static double EaseInOut(double t, double b, double c, double d, double a, double p) + { + if (t == 0.0) + { + return b; + } + if ((t /= d / 2.0) == 2.0) + { + return b + c; + } + if (p == 0.0) + { + p = d * 0.44999999999999996; + } + double num; + if (a < Math.Abs(c)) + { + a = c; + num = p / 4.0; + } + else + { + num = p / 6.2831853071795862 * Math.Asin(c / a); + } + if (t < 1.0) + { + return -0.5 * (a * Math.Pow(2.0, 10.0 * (t -= 1.0)) * Math.Sin((t * d - num) * 6.2831853071795862 / p)) + b; + } + return a * Math.Pow(2.0, -10.0 * (t -= 1.0)) * Math.Sin((t * d - num) * 6.2831853071795862 / p) * 0.5 + c + b; + } +} diff --git a/EnableCameraDepthInForward.cs b/EnableCameraDepthInForward.cs new file mode 100644 index 00000000..a3c1a3d8 --- /dev/null +++ b/EnableCameraDepthInForward.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +[RequireComponent(typeof(Camera))] +public class EnableCameraDepthInForward : MonoBehaviour +{ + private void Start() + { + Set(); + } + + private void Set() + { + if (GetComponent().depthTextureMode == DepthTextureMode.None) + { + GetComponent().depthTextureMode = DepthTextureMode.Depth; + } + } +} diff --git a/EventDelegate.cs b/EventDelegate.cs new file mode 100644 index 00000000..f881d7d4 --- /dev/null +++ b/EventDelegate.cs @@ -0,0 +1,661 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; + +[Serializable] +public class EventDelegate +{ + [Serializable] + public class Parameter + { + public UnityEngine.Object obj; + + public string field; + + [NonSerialized] + private object mValue; + + [NonSerialized] + public Type expectedType = typeof(void); + + [NonSerialized] + public bool cached; + + [NonSerialized] + public PropertyInfo propInfo; + + [NonSerialized] + public FieldInfo fieldInfo; + + public object value + { + get + { + if (mValue != null) + { + return mValue; + } + if (!cached) + { + cached = true; + fieldInfo = null; + propInfo = null; + if (obj != null && !string.IsNullOrEmpty(field)) + { + Type type = obj.GetType(); + propInfo = type.GetProperty(field); + if (propInfo == null) + { + fieldInfo = type.GetField(field); + } + } + } + if (propInfo != null) + { + return propInfo.GetValue(obj, null); + } + if (fieldInfo != null) + { + return fieldInfo.GetValue(obj); + } + if (obj != null) + { + return obj; + } + if (expectedType != null && expectedType.IsValueType) + { + return null; + } + return Convert.ChangeType(null, expectedType); + } + set + { + mValue = value; + } + } + + public Type type + { + get + { + if (mValue != null) + { + return mValue.GetType(); + } + if (obj == null) + { + return typeof(void); + } + return obj.GetType(); + } + } + + public Parameter() + { + } + + public Parameter(UnityEngine.Object obj, string field) + { + this.obj = obj; + this.field = field; + } + + public Parameter(object val) + { + mValue = val; + } + } + + public delegate void Callback(); + + [SerializeField] + private MonoBehaviour mTarget; + + [SerializeField] + private string mMethodName; + + [SerializeField] + private Parameter[] mParameters; + + public bool oneShot; + + [NonSerialized] + private Callback mCachedCallback; + + [NonSerialized] + private bool mRawDelegate; + + [NonSerialized] + private bool mCached; + + [NonSerialized] + private MethodInfo mMethod; + + [NonSerialized] + private object[] mArgs; + + private static int s_Hash = "EventDelegate".GetHashCode(); + + public MonoBehaviour target + { + get + { + return mTarget; + } + set + { + mTarget = value; + mCachedCallback = null; + mRawDelegate = false; + mCached = false; + mMethod = null; + mParameters = null; + } + } + + public string methodName + { + get + { + return mMethodName; + } + set + { + mMethodName = value; + mCachedCallback = null; + mRawDelegate = false; + mCached = false; + mMethod = null; + mParameters = null; + } + } + + public Parameter[] parameters + { + get + { + if (!mCached) + { + Cache(); + } + return mParameters; + } + } + + public bool isValid + { + get + { + if (!mCached) + { + Cache(); + } + return (mRawDelegate && mCachedCallback != null) || (mTarget != null && !string.IsNullOrEmpty(mMethodName)); + } + } + + public bool isEnabled + { + get + { + if (!mCached) + { + Cache(); + } + if (mRawDelegate && mCachedCallback != null) + { + return true; + } + if (mTarget == null) + { + return false; + } + MonoBehaviour monoBehaviour = mTarget; + return monoBehaviour == null || monoBehaviour.enabled; + } + } + + public EventDelegate() + { + } + + public EventDelegate(Callback call) + { + Set(call); + } + + public EventDelegate(MonoBehaviour target, string methodName) + { + Set(target, methodName); + } + + private static string GetMethodName(Callback callback) + { + return callback.Method.Name; + } + + private static bool IsValid(Callback callback) + { + return callback != null && callback.Method != null; + } + + public override bool Equals(object obj) + { + if (obj == null) + { + return !isValid; + } + if (obj is Callback) + { + Callback callback = obj as Callback; + if (callback.Equals(mCachedCallback)) + { + return true; + } + MonoBehaviour y = callback.Target as MonoBehaviour; + return mTarget == y && string.Equals(mMethodName, GetMethodName(callback)); + } + if (obj is EventDelegate) + { + EventDelegate eventDelegate = obj as EventDelegate; + return mTarget == eventDelegate.mTarget && string.Equals(mMethodName, eventDelegate.mMethodName); + } + return false; + } + + public override int GetHashCode() + { + return s_Hash; + } + + private void Set(Callback call) + { + Clear(); + if (call != null && IsValid(call)) + { + mTarget = (call.Target as MonoBehaviour); + if (mTarget == null) + { + mRawDelegate = true; + mCachedCallback = call; + mMethodName = null; + } + else + { + mMethodName = GetMethodName(call); + mRawDelegate = false; + } + } + } + + public void Set(MonoBehaviour target, string methodName) + { + Clear(); + mTarget = target; + mMethodName = methodName; + } + + private void Cache() + { + mCached = true; + if (!mRawDelegate && (mCachedCallback == null || mCachedCallback.Target as MonoBehaviour != mTarget || GetMethodName(mCachedCallback) != mMethodName) && mTarget != null && !string.IsNullOrEmpty(mMethodName)) + { + Type type = mTarget.GetType(); + mMethod = null; + while (type != null) + { + try + { + mMethod = type.GetMethod(mMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + if (mMethod != null) + { + break; + } + } + catch (Exception) + { + } + type = type.BaseType; + } + if (mMethod == null) + { + Debug.LogError("Could not find method '" + mMethodName + "' on " + mTarget.GetType(), mTarget); + } + else if (mMethod.ReturnType != typeof(void)) + { + Debug.LogError(mTarget.GetType() + "." + mMethodName + " must have a 'void' return type.", mTarget); + } + else + { + ParameterInfo[] parameters = mMethod.GetParameters(); + if (parameters.Length == 0) + { + mCachedCallback = (Callback)Delegate.CreateDelegate(typeof(Callback), mTarget, mMethodName); + mArgs = null; + mParameters = null; + } + else + { + mCachedCallback = null; + if (mParameters == null || mParameters.Length != parameters.Length) + { + mParameters = new Parameter[parameters.Length]; + int i = 0; + for (int num = mParameters.Length; i < num; i++) + { + mParameters[i] = new Parameter(); + } + } + int j = 0; + for (int num2 = mParameters.Length; j < num2; j++) + { + mParameters[j].expectedType = parameters[j].ParameterType; + } + } + } + } + } + + public bool Execute() + { + if (!mCached) + { + Cache(); + } + if (mCachedCallback != null) + { + mCachedCallback(); + return true; + } + if (mMethod != null) + { + if (mParameters == null || mParameters.Length == 0) + { + mMethod.Invoke(mTarget, null); + } + else + { + if (mArgs == null || mArgs.Length != mParameters.Length) + { + mArgs = new object[mParameters.Length]; + } + int i = 0; + for (int num = mParameters.Length; i < num; i++) + { + mArgs[i] = mParameters[i].value; + } + try + { + mMethod.Invoke(mTarget, mArgs); + } + catch (ArgumentException ex) + { + string text = "Error calling "; + if (mTarget == null) + { + text += mMethod.Name; + } + else + { + string text2 = text; + text = text2 + mTarget.GetType() + "." + mMethod.Name; + } + text = text + ": " + ex.Message; + text += "\n Expected: "; + ParameterInfo[] parameters = mMethod.GetParameters(); + if (parameters.Length == 0) + { + text += "no arguments"; + } + else + { + text += parameters[0]; + for (int j = 1; j < parameters.Length; j++) + { + text = text + ", " + parameters[j].ParameterType; + } + } + text += "\n Received: "; + if (mParameters.Length == 0) + { + text += "no arguments"; + } + else + { + text += mParameters[0].type; + for (int k = 1; k < mParameters.Length; k++) + { + text = text + ", " + mParameters[k].type; + } + } + text += "\n"; + Debug.LogError(text); + } + int l = 0; + for (int num2 = mArgs.Length; l < num2; l++) + { + mArgs[l] = null; + } + } + return true; + } + return false; + } + + public void Clear() + { + mTarget = null; + mMethodName = null; + mRawDelegate = false; + mCachedCallback = null; + mParameters = null; + mCached = false; + mMethod = null; + mArgs = null; + } + + public override string ToString() + { + if (mTarget != null) + { + string text = mTarget.GetType().ToString(); + int num = text.LastIndexOf('.'); + if (num > 0) + { + text = text.Substring(num + 1); + } + if (!string.IsNullOrEmpty(methodName)) + { + return text + "/" + methodName; + } + return text + "/[delegate]"; + } + return (!mRawDelegate) ? null : "[delegate]"; + } + + public static void Execute(List list) + { + if (list != null) + { + int num = 0; + while (num < list.Count) + { + EventDelegate eventDelegate = list[num]; + if (eventDelegate != null) + { + try + { + eventDelegate.Execute(); + } + catch (Exception ex) + { + if (ex.InnerException != null) + { + Debug.LogError(ex.InnerException.Message); + } + else + { + Debug.LogError(ex.Message); + } + } + if (num >= list.Count) + { + break; + } + if (list[num] != eventDelegate) + { + continue; + } + if (eventDelegate.oneShot) + { + list.RemoveAt(num); + continue; + } + } + num++; + } + } + } + + public static bool IsValid(List list) + { + if (list != null) + { + int i = 0; + for (int count = list.Count; i < count; i++) + { + EventDelegate eventDelegate = list[i]; + if (eventDelegate != null && eventDelegate.isValid) + { + return true; + } + } + } + return false; + } + + public static EventDelegate Set(List list, Callback callback) + { + if (list != null) + { + EventDelegate eventDelegate = new EventDelegate(callback); + list.Clear(); + list.Add(eventDelegate); + return eventDelegate; + } + return null; + } + + public static void Set(List list, EventDelegate del) + { + if (list != null) + { + list.Clear(); + list.Add(del); + } + } + + public static EventDelegate Add(List list, Callback callback) + { + return Add(list, callback, oneShot: false); + } + + public static EventDelegate Add(List list, Callback callback, bool oneShot) + { + if (list != null) + { + int i = 0; + for (int count = list.Count; i < count; i++) + { + EventDelegate eventDelegate = list[i]; + if (eventDelegate != null && eventDelegate.Equals(callback)) + { + return eventDelegate; + } + } + EventDelegate eventDelegate2 = new EventDelegate(callback); + eventDelegate2.oneShot = oneShot; + list.Add(eventDelegate2); + return eventDelegate2; + } + Debug.LogWarning("Attempting to add a callback to a list that's null"); + return null; + } + + public static void Add(List list, EventDelegate ev) + { + Add(list, ev, ev.oneShot); + } + + public static void Add(List list, EventDelegate ev, bool oneShot) + { + if (ev.mRawDelegate || ev.target == null || string.IsNullOrEmpty(ev.methodName)) + { + Add(list, ev.mCachedCallback, oneShot); + } + else if (list != null) + { + int i = 0; + for (int count = list.Count; i < count; i++) + { + EventDelegate eventDelegate = list[i]; + if (eventDelegate != null && eventDelegate.Equals(ev)) + { + return; + } + } + EventDelegate eventDelegate2 = new EventDelegate(ev.target, ev.methodName); + eventDelegate2.oneShot = oneShot; + if (ev.mParameters != null && ev.mParameters.Length > 0) + { + eventDelegate2.mParameters = new Parameter[ev.mParameters.Length]; + for (int j = 0; j < ev.mParameters.Length; j++) + { + eventDelegate2.mParameters[j] = ev.mParameters[j]; + } + } + list.Add(eventDelegate2); + } + else + { + Debug.LogWarning("Attempting to add a callback to a list that's null"); + } + } + + public static bool Remove(List list, Callback callback) + { + if (list != null) + { + int i = 0; + for (int count = list.Count; i < count; i++) + { + EventDelegate eventDelegate = list[i]; + if (eventDelegate != null && eventDelegate.Equals(callback)) + { + list.RemoveAt(i); + return true; + } + } + } + return false; + } + + public static bool Remove(List list, EventDelegate ev) + { + if (list != null) + { + int i = 0; + for (int count = list.Count; i < count; i++) + { + EventDelegate eventDelegate = list[i]; + if (eventDelegate != null && eventDelegate.Equals(ev)) + { + list.RemoveAt(i); + return true; + } + } + } + return false; + } +} diff --git a/Expo.cs b/Expo.cs new file mode 100644 index 00000000..e7c5c0a8 --- /dev/null +++ b/Expo.cs @@ -0,0 +1,31 @@ +using System; + +internal class Expo : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return (t != 0.0) ? (c * Math.Pow(2.0, 10.0 * (t / d - 1.0)) + b - c * 0.001) : b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return (t != d) ? (c * (0.0 - Math.Pow(2.0, -10.0 * t / d) + 1.0) + b) : (b + c); + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if (t == 0.0) + { + return b; + } + if (t == d) + { + return b + c; + } + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * Math.Pow(2.0, 10.0 * (t - 1.0)) + b; + } + return c / 2.0 * (0.0 - Math.Pow(2.0, -10.0 * (t -= 1.0)) + 2.0) + b; + } +} diff --git a/LTBezier.cs b/LTBezier.cs new file mode 100644 index 00000000..5f1c5bca --- /dev/null +++ b/LTBezier.cs @@ -0,0 +1,78 @@ +using UnityEngine; + +public class LTBezier +{ + public float length; + + private Vector3 a; + + private Vector3 aa; + + private Vector3 bb; + + private Vector3 cc; + + private float len; + + private float[] arcLengths; + + public LTBezier(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float precision) + { + this.a = a; + aa = -a + 3f * (b - c) + d; + bb = 3f * (a + c) - 6f * b; + cc = 3f * (b - a); + len = 1f / precision; + arcLengths = new float[(int)len + 1]; + arcLengths[0] = 0f; + Vector3 vector = a; + float num = 0f; + for (int i = 1; (float)i <= len; i++) + { + Vector3 vector2 = bezierPoint((float)i * precision); + num += (vector - vector2).magnitude; + arcLengths[i] = num; + vector = vector2; + } + length = num; + } + + private float map(float u) + { + float num = u * arcLengths[(int)len]; + int num2 = 0; + int num3 = (int)len; + int num4 = 0; + while (num2 < num3) + { + num4 = num2 + ((int)((float)(num3 - num2) / 2f) | 0); + if (arcLengths[num4] < num) + { + num2 = num4 + 1; + } + else + { + num3 = num4; + } + } + if (arcLengths[num4] > num) + { + num4--; + } + if (num4 < 0) + { + num4 = 0; + } + return ((float)num4 + (num - arcLengths[num4]) / (arcLengths[num4 + 1] - arcLengths[num4])) / len; + } + + private Vector3 bezierPoint(float t) + { + return ((aa * t + bb) * t + cc) * t + a; + } + + public Vector3 point(float t) + { + return bezierPoint(map(t)); + } +} diff --git a/LTBezierPath.cs b/LTBezierPath.cs new file mode 100644 index 00000000..1703d2d7 --- /dev/null +++ b/LTBezierPath.cs @@ -0,0 +1,94 @@ +using UnityEngine; + +public class LTBezierPath +{ + public Vector3[] pts; + + public float length; + + public bool orientToPath; + + private LTBezier[] beziers; + + private float[] lengthRatio; + + public LTBezierPath() + { + } + + public LTBezierPath(Vector3[] pts_) + { + setPoints(pts_); + } + + public void setPoints(Vector3[] pts_) + { + if (pts_.Length < 4) + { + LeanTween.logError("LeanTween - When passing values for a vector path, you must pass four or more values!"); + } + if (pts_.Length % 4 != 0) + { + LeanTween.logError("LeanTween - When passing values for a vector path, they must be in sets of four: controlPoint1, controlPoint2, endPoint2, controlPoint2, controlPoint2..."); + } + pts = pts_; + int num = 0; + beziers = new LTBezier[pts.Length / 4]; + lengthRatio = new float[beziers.Length]; + length = 0f; + for (int i = 0; i < pts.Length; i += 4) + { + beziers[num] = new LTBezier(pts[i], pts[i + 2], pts[i + 1], pts[i + 3], 0.05f); + length += beziers[num].length; + num++; + } + for (int i = 0; i < beziers.Length; i++) + { + lengthRatio[i] = beziers[i].length / length; + } + } + + public Vector3 point(float ratio) + { + float num = 0f; + for (int i = 0; i < lengthRatio.Length; i++) + { + num += lengthRatio[i]; + if (num >= ratio) + { + return beziers[i].point((ratio - (num - lengthRatio[i])) / lengthRatio[i]); + } + } + return beziers[lengthRatio.Length - 1].point(1f); + } + + public void place(Transform transform, float ratio) + { + place(transform, ratio, Vector3.up); + } + + public void place(Transform transform, float ratio, Vector3 worldUp) + { + transform.position = point(ratio); + ratio += 0.001f; + if (ratio <= 1f) + { + transform.LookAt(point(ratio), worldUp); + } + } + + public void placeLocal(Transform transform, float ratio) + { + placeLocal(transform, ratio, Vector3.up); + } + + public void placeLocal(Transform transform, float ratio, Vector3 worldUp) + { + transform.localPosition = point(ratio); + ratio += 0.001f; + if (ratio <= 1f) + { + transform.LookAt(transform.parent.TransformPoint(point(ratio)), worldUp); + } + } +} diff --git a/LTDescr.cs b/LTDescr.cs new file mode 100644 index 00000000..6826b9d8 --- /dev/null +++ b/LTDescr.cs @@ -0,0 +1,383 @@ +using System; +using System.Collections; +using UnityEngine; + +public class LTDescr +{ + public bool toggle; + + public bool useEstimatedTime; + + public bool useFrames; + + public bool hasInitiliazed; + + public bool hasPhysics; + + public float passed; + + public float delay; + + public float time; + + public float lastVal; + + private uint _id; + + public int loopCount; + + public uint counter; + + public float direction; + + public bool destroyOnComplete; + + public Transform trans; + + public LTRect ltRect; + + public Vector3 from; + + public Vector3 to; + + public Vector3 diff; + + public Vector3 point; + + public Vector3 axis; + + public Vector3 origRotation; + + public LTBezierPath path; + + public LTSpline spline; + + public TweenAction type; + + public LeanTweenType tweenType; + + public AnimationCurve animationCurve; + + public LeanTweenType loopType; + + public Action onUpdateFloat; + + public Action onUpdateFloatObject; + + public Action onUpdateVector3; + + public Action onUpdateVector3Object; + + public Action onComplete; + + public Action onCompleteObject; + + public object onCompleteParam; + + public object onUpdateParam; + + public Hashtable optional; + + private static uint global_counter; + + public int uniqueId => (int)(_id | (counter << 16)); + + public int id => uniqueId; + + public override string ToString() + { + return ((!(trans != null)) ? "gameObject:null" : ("gameObject:" + trans.gameObject)) + " toggle:" + toggle + " passed:" + passed + " time:" + time + " delay:" + delay + " from:" + from + " to:" + to + " type:" + type + " useEstimatedTime:" + useEstimatedTime + " id:" + id + " hasInitiliazed:" + hasInitiliazed; + } + + public LTDescr cancel() + { + LeanTween.removeTween((int)_id); + return this; + } + + public void reset() + { + toggle = true; + optional = null; + destroyOnComplete = false; + passed = (delay = 0f); + useEstimatedTime = (useFrames = (hasInitiliazed = false)); + animationCurve = null; + tweenType = LeanTweenType.linear; + loopType = LeanTweenType.once; + loopCount = 0; + direction = (lastVal = 1f); + onUpdateFloat = null; + onUpdateVector3 = null; + onUpdateFloatObject = null; + onUpdateVector3Object = null; + onComplete = null; + onCompleteObject = null; + onCompleteParam = null; + point = Vector3.zero; + global_counter++; + } + + public LTDescr pause() + { + if (direction != 0f) + { + lastVal = direction; + direction = 0f; + } + return this; + } + + public LTDescr resume() + { + direction = lastVal; + return this; + } + + public LTDescr setAxis(Vector3 axis) + { + this.axis = axis; + return this; + } + + public LTDescr setDelay(float delay) + { + if (useEstimatedTime) + { + this.delay = delay; + } + else + { + this.delay = delay * Time.timeScale; + } + return this; + } + + public LTDescr setEase(LeanTweenType easeType) + { + tweenType = easeType; + return this; + } + + public LTDescr setEase(AnimationCurve easeCurve) + { + animationCurve = easeCurve; + return this; + } + + public LTDescr setTo(Vector3 to) + { + this.to = to; + return this; + } + + public LTDescr setFrom(Vector3 from) + { + this.from = from; + hasInitiliazed = true; + diff = to - this.from; + return this; + } + + public LTDescr setId(uint id) + { + _id = id; + counter = global_counter; + return this; + } + + public LTDescr setRepeat(int repeat) + { + loopCount = repeat; + if ((repeat > 1 && loopType == LeanTweenType.once) || (repeat < 0 && loopType == LeanTweenType.once)) + { + loopType = LeanTweenType.clamp; + } + return this; + } + + public LTDescr setLoopType(LeanTweenType loopType) + { + this.loopType = loopType; + return this; + } + + public LTDescr setUseEstimatedTime(bool useEstimatedTime) + { + this.useEstimatedTime = useEstimatedTime; + return this; + } + + public LTDescr setUseFrames(bool useFrames) + { + this.useFrames = useFrames; + return this; + } + + public LTDescr setLoopCount(int loopCount) + { + this.loopCount = loopCount; + return this; + } + + public LTDescr setLoopOnce() + { + loopType = LeanTweenType.once; + return this; + } + + public LTDescr setLoopClamp() + { + loopType = LeanTweenType.clamp; + if (loopCount == 0) + { + loopCount = -1; + } + return this; + } + + public LTDescr setLoopPingPong() + { + loopType = LeanTweenType.pingPong; + if (loopCount == 0) + { + loopCount = -1; + } + return this; + } + + public LTDescr setOnComplete(Action onComplete) + { + this.onComplete = onComplete; + return this; + } + + public LTDescr setOnComplete(Action onComplete) + { + onCompleteObject = onComplete; + return this; + } + + public LTDescr setOnComplete(Action onComplete, object onCompleteParam) + { + onCompleteObject = onComplete; + if (onCompleteParam != null) + { + this.onCompleteParam = onCompleteParam; + } + return this; + } + + public LTDescr setOnCompleteParam(object onCompleteParam) + { + this.onCompleteParam = onCompleteParam; + return this; + } + + public LTDescr setOnUpdate(Action onUpdate) + { + onUpdateFloat = onUpdate; + return this; + } + + public LTDescr setOnUpdateObject(Action onUpdate) + { + onUpdateFloatObject = onUpdate; + return this; + } + + public LTDescr setOnUpdateVector3(Action onUpdate) + { + onUpdateVector3 = onUpdate; + return this; + } + + public LTDescr setOnUpdate(Action onUpdate, object onUpdateParam = null) + { + onUpdateFloatObject = onUpdate; + if (onUpdateParam != null) + { + this.onUpdateParam = onUpdateParam; + } + return this; + } + + public LTDescr setOnUpdate(Action onUpdate, object onUpdateParam = null) + { + onUpdateVector3Object = onUpdate; + if (onUpdateParam != null) + { + this.onUpdateParam = onUpdateParam; + } + return this; + } + + public LTDescr setOnUpdate(Action onUpdate, object onUpdateParam = null) + { + onUpdateVector3 = onUpdate; + if (onUpdateParam != null) + { + this.onUpdateParam = onUpdateParam; + } + return this; + } + + public LTDescr setOnUpdateParam(object onUpdateParam) + { + this.onUpdateParam = onUpdateParam; + return this; + } + + public LTDescr setOrientToPath(bool doesOrient) + { + if (type == TweenAction.MOVE_CURVED || type == TweenAction.MOVE_CURVED_LOCAL) + { + if (path == null) + { + path = new LTBezierPath(); + } + path.orientToPath = doesOrient; + } + else + { + spline.orientToPath = doesOrient; + } + return this; + } + + public LTDescr setRect(LTRect rect) + { + ltRect = rect; + return this; + } + + public LTDescr setRect(Rect rect) + { + ltRect = new LTRect(rect); + return this; + } + + public LTDescr setPath(LTBezierPath path) + { + this.path = path; + return this; + } + + public LTDescr setPoint(Vector3 point) + { + this.point = point; + return this; + } + + public LTDescr setDestroyOnComplete(bool doesDestroy) + { + destroyOnComplete = doesDestroy; + return this; + } + + public LTDescr setAudio(object audio) + { + onCompleteParam = audio; + return this; + } +} diff --git a/LTEvent.cs b/LTEvent.cs new file mode 100644 index 00000000..b4a177a0 --- /dev/null +++ b/LTEvent.cs @@ -0,0 +1,12 @@ +public class LTEvent +{ + public int id; + + public object data; + + public LTEvent(int id, object data) + { + this.id = id; + this.data = data; + } +} diff --git a/LTGUI.cs b/LTGUI.cs new file mode 100644 index 00000000..fc22a0a7 --- /dev/null +++ b/LTGUI.cs @@ -0,0 +1,277 @@ +using UnityEngine; + +public class LTGUI +{ + public enum Element_Type + { + Texture, + Label + } + + public static int RECT_LEVELS = 5; + + public static int RECTS_PER_LEVEL = 10; + + public static int BUTTONS_MAX = 24; + + private static LTRect[] levels; + + private static int[] levelDepths; + + private static Rect[] buttons; + + private static int[] buttonLevels; + + private static int[] buttonLastFrame; + + private static LTRect r; + + private static Color color = Color.white; + + private static bool isGUIEnabled = false; + + private static int global_counter = 0; + + public static void init() + { + if (levels == null) + { + levels = new LTRect[RECT_LEVELS * RECTS_PER_LEVEL]; + levelDepths = new int[RECT_LEVELS]; + } + } + + public static void initRectCheck() + { + if (buttons == null) + { + buttons = new Rect[BUTTONS_MAX]; + buttonLevels = new int[BUTTONS_MAX]; + buttonLastFrame = new int[BUTTONS_MAX]; + for (int i = 0; i < buttonLevels.Length; i++) + { + buttonLevels[i] = -1; + } + } + } + + public static void reset() + { + if (isGUIEnabled) + { + isGUIEnabled = false; + for (int i = 0; i < levels.Length; i++) + { + levels[i] = null; + } + for (int j = 0; j < levelDepths.Length; j++) + { + levelDepths[j] = 0; + } + } + } + + public static void update(int updateLevel) + { + if (isGUIEnabled) + { + init(); + if (levelDepths[updateLevel] > 0) + { + color = GUI.color; + int num = updateLevel * RECTS_PER_LEVEL; + int num2 = num + levelDepths[updateLevel]; + for (int i = num; i < num2; i++) + { + r = levels[i]; + if (r != null) + { + if (r.useColor) + { + GUI.color = r.color; + } + if (r.type == Element_Type.Label) + { + if (r.style != null) + { + GUI.skin.label = r.style; + } + if (r.useSimpleScale) + { + GUI.Label(new Rect((r.rect.x + r.margin.x + r.relativeRect.x) * r.relativeRect.width, (r.rect.y + r.margin.y + r.relativeRect.y) * r.relativeRect.height, r.rect.width * r.relativeRect.width, r.rect.height * r.relativeRect.height), r.labelStr); + } + else + { + GUI.Label(new Rect(r.rect.x + r.margin.x, r.rect.y + r.margin.y, r.rect.width, r.rect.height), r.labelStr); + } + } + else if (r.type == Element_Type.Texture && r.texture != null) + { + Vector2 vector = (!r.useSimpleScale) ? new Vector2(r.rect.width, r.rect.height) : new Vector2(0f, r.rect.height * r.relativeRect.height); + if (r.sizeByHeight) + { + vector.x = (float)r.texture.width / (float)r.texture.height * vector.y; + } + if (r.useSimpleScale) + { + GUI.DrawTexture(new Rect((r.rect.x + r.margin.x + r.relativeRect.x) * r.relativeRect.width, (r.rect.y + r.margin.y + r.relativeRect.y) * r.relativeRect.height, vector.x, vector.y), r.texture); + } + else + { + GUI.DrawTexture(new Rect(r.rect.x + r.margin.x, r.rect.y + r.margin.y, vector.x, vector.y), r.texture); + } + } + } + } + GUI.color = color; + } + } + } + + public static bool checkOnScreen(Rect rect) + { + bool flag = rect.x + rect.width < 0f; + bool flag2 = rect.x > (float)Screen.width; + bool flag3 = rect.y > (float)Screen.height; + bool flag4 = rect.y + rect.height < 0f; + return !flag && !flag2 && !flag3 && !flag4; + } + + public static void destroy(int id) + { + int num = id & 0xFFFF; + int num2 = id >> 16; + if (id >= 0 && levels[num] != null && levels[num].hasInitiliazed && levels[num].counter == num2) + { + levels[num] = null; + } + } + + public static LTRect label(Rect rect, string label, int depth) + { + return LTGUI.label(new LTRect(rect), label, depth); + } + + public static LTRect label(LTRect rect, string label, int depth) + { + rect.type = Element_Type.Label; + rect.labelStr = label; + return element(rect, depth); + } + + public static LTRect texture(Rect rect, Texture texture, int depth) + { + return LTGUI.texture(new LTRect(rect), texture, depth); + } + + public static LTRect texture(LTRect rect, Texture texture, int depth) + { + rect.type = Element_Type.Texture; + rect.texture = texture; + return element(rect, depth); + } + + public static LTRect element(LTRect rect, int depth) + { + isGUIEnabled = true; + init(); + int num = depth * RECTS_PER_LEVEL + RECTS_PER_LEVEL; + int num2 = 0; + if (rect != null) + { + destroy(rect.id); + } + if (rect.type == Element_Type.Label && rect.style != null) + { + Color textColor = rect.style.normal.textColor; + if (textColor.a <= 0f) + { + Debug.LogWarning("Your GUI normal color has an alpha of zero, and will not be rendered."); + } + } + if (rect.relativeRect.width == float.PositiveInfinity) + { + rect.relativeRect = new Rect(0f, 0f, (float)Screen.width, (float)Screen.height); + } + for (int i = depth * RECTS_PER_LEVEL; i < num; i++) + { + r = levels[i]; + if (r == null) + { + r = rect; + r.rotateEnabled = true; + r.alphaEnabled = true; + r.setId(i, global_counter); + levels[i] = r; + if (num2 >= levelDepths[depth]) + { + levelDepths[depth] = num2 + 1; + } + global_counter++; + return r; + } + num2++; + } + Debug.LogError("You ran out of GUI Element spaces"); + return null; + } + + public static bool hasNoOverlap(Rect rect, int depth) + { + initRectCheck(); + bool result = true; + bool flag = false; + for (int i = 0; i < buttonLevels.Length; i++) + { + if (buttonLevels[i] >= 0) + { + if (buttonLastFrame[i] + 1 < Time.frameCount) + { + buttonLevels[i] = -1; + } + else if (buttonLevels[i] > depth && pressedWithinRect(buttons[i])) + { + result = false; + } + } + if (!flag && buttonLevels[i] < 0) + { + flag = true; + buttonLevels[i] = depth; + buttons[i] = rect; + buttonLastFrame[i] = Time.frameCount; + } + } + return result; + } + + public static bool pressedWithinRect(Rect rect) + { + Vector2 vector = firstTouch(); + if (vector.x < 0f) + { + return false; + } + float num = (float)Screen.height - vector.y; + return vector.x > rect.x && vector.x < rect.x + rect.width && num > rect.y && num < rect.y + rect.height; + } + + public static bool checkWithinRect(Vector2 vec2, Rect rect) + { + vec2.y = (float)Screen.height - vec2.y; + return vec2.x > rect.x && vec2.x < rect.x + rect.width && vec2.y > rect.y && vec2.y < rect.y + rect.height; + } + + public static Vector2 firstTouch() + { + if (Input.touchCount > 0) + { + return Input.touches[0].position; + } + if (Input.GetMouseButton(0)) + { + return Input.mousePosition; + } + return new Vector2(float.NegativeInfinity, float.NegativeInfinity); + } +} diff --git a/LTRect.cs b/LTRect.cs new file mode 100644 index 00000000..5bc65a73 --- /dev/null +++ b/LTRect.cs @@ -0,0 +1,281 @@ +using System; +using UnityEngine; + +[Serializable] +public class LTRect +{ + public Rect _rect; + + public float alpha = 1f; + + public float rotation; + + public Vector2 pivot; + + public Vector2 margin; + + public Rect relativeRect = new Rect(0f, 0f, float.PositiveInfinity, float.PositiveInfinity); + + public bool rotateEnabled; + + [HideInInspector] + public bool rotateFinished; + + public bool alphaEnabled; + + public string labelStr; + + public LTGUI.Element_Type type; + + public GUIStyle style; + + public bool useColor; + + public Color color = Color.white; + + public bool fontScaleToFit; + + public bool useSimpleScale; + + public bool sizeByHeight; + + public Texture texture; + + private int _id = -1; + + [HideInInspector] + public int counter; + + public static bool colorTouched; + + public bool hasInitiliazed => _id != -1; + + public int id => _id | (counter << 16); + + public float x + { + get + { + return _rect.x; + } + set + { + _rect.x = value; + } + } + + public float y + { + get + { + return _rect.y; + } + set + { + _rect.y = value; + } + } + + public float width + { + get + { + return _rect.width; + } + set + { + _rect.width = value; + } + } + + public float height + { + get + { + return _rect.height; + } + set + { + _rect.height = value; + } + } + + public Rect rect + { + get + { + if (colorTouched) + { + colorTouched = false; + Color color = GUI.color; + float r = color.r; + Color color2 = GUI.color; + float g = color2.g; + Color color3 = GUI.color; + GUI.color = new Color(r, g, color3.b, 1f); + } + if (rotateEnabled) + { + if (rotateFinished) + { + rotateFinished = false; + rotateEnabled = false; + pivot = Vector2.zero; + } + else + { + GUIUtility.RotateAroundPivot(rotation, pivot); + } + } + if (alphaEnabled) + { + Color color4 = GUI.color; + float r2 = color4.r; + Color color5 = GUI.color; + float g2 = color5.g; + Color color6 = GUI.color; + GUI.color = new Color(r2, g2, color6.b, alpha); + colorTouched = true; + } + if (fontScaleToFit) + { + if (useSimpleScale) + { + style.fontSize = (int)(_rect.height * relativeRect.height); + } + else + { + style.fontSize = (int)_rect.height; + } + } + return _rect; + } + set + { + _rect = value; + } + } + + public LTRect() + { + reset(); + rotateEnabled = (alphaEnabled = true); + _rect = new Rect(0f, 0f, 1f, 1f); + } + + public LTRect(Rect rect) + { + _rect = rect; + reset(); + } + + public LTRect(float x, float y, float width, float height) + { + _rect = new Rect(x, y, width, height); + alpha = 1f; + rotation = 0f; + rotateEnabled = (alphaEnabled = false); + } + + public LTRect(float x, float y, float width, float height, float alpha) + { + _rect = new Rect(x, y, width, height); + this.alpha = alpha; + rotation = 0f; + rotateEnabled = (alphaEnabled = false); + } + + public LTRect(float x, float y, float width, float height, float alpha, float rotation) + { + _rect = new Rect(x, y, width, height); + this.alpha = alpha; + this.rotation = rotation; + rotateEnabled = (alphaEnabled = false); + if (rotation != 0f) + { + rotateEnabled = true; + resetForRotation(); + } + } + + public void setId(int id, int counter) + { + _id = id; + this.counter = counter; + } + + public void reset() + { + alpha = 1f; + rotation = 0f; + rotateEnabled = (alphaEnabled = false); + margin = Vector2.zero; + sizeByHeight = false; + useColor = false; + } + + public void resetForRotation() + { + Vector3 vector = new Vector3(GUI.matrix[0, 0], GUI.matrix[1, 1], GUI.matrix[2, 2]); + if (pivot == Vector2.zero) + { + pivot = new Vector2((_rect.x + _rect.width * 0.5f) * vector.x + GUI.matrix[0, 3], (_rect.y + _rect.height * 0.5f) * vector.y + GUI.matrix[1, 3]); + } + } + + public LTRect setStyle(GUIStyle style) + { + this.style = style; + return this; + } + + public LTRect setFontScaleToFit(bool fontScaleToFit) + { + this.fontScaleToFit = fontScaleToFit; + return this; + } + + public LTRect setColor(Color color) + { + this.color = color; + useColor = true; + return this; + } + + public LTRect setAlpha(float alpha) + { + this.alpha = alpha; + return this; + } + + public LTRect setLabel(string str) + { + labelStr = str; + return this; + } + + public LTRect setUseSimpleScale(bool useSimpleScale, Rect relativeRect) + { + this.useSimpleScale = useSimpleScale; + this.relativeRect = relativeRect; + return this; + } + + public LTRect setUseSimpleScale(bool useSimpleScale) + { + this.useSimpleScale = useSimpleScale; + relativeRect = new Rect(0f, 0f, (float)Screen.width, (float)Screen.height); + return this; + } + + public LTRect setSizeByHeight(bool sizeByHeight) + { + this.sizeByHeight = sizeByHeight; + return this; + } + + public override string ToString() + { + return "x:" + _rect.x + " y:" + _rect.y + " width:" + _rect.width + " height:" + _rect.height; + } +} diff --git a/LTSpline.cs b/LTSpline.cs new file mode 100644 index 00000000..bce2fb80 --- /dev/null +++ b/LTSpline.cs @@ -0,0 +1,139 @@ +using System; +using UnityEngine; + +[Serializable] +public class LTSpline +{ + public Vector3[] pts; + + public bool orientToPath; + + private float[] lengthRatio; + + private float[] lengths; + + private int numSections; + + private int currPt; + + private float totalLength; + + public LTSpline(params Vector3[] pts) + { + this.pts = new Vector3[pts.Length]; + Array.Copy(pts, this.pts, pts.Length); + numSections = pts.Length - 3; + int num = 20; + lengthRatio = new float[num]; + lengths = new float[num]; + Vector3 b = new Vector3(float.PositiveInfinity, 0f, 0f); + totalLength = 0f; + for (int i = 0; i < num; i++) + { + float t = (float)i * 1f / (float)num; + Vector3 vector = interp(t); + if (i >= 1) + { + lengths[i] = (vector - b).magnitude; + } + totalLength += lengths[i]; + b = vector; + } + float num2 = 0f; + for (int j = 0; j < lengths.Length; j++) + { + float num3 = (float)j * 1f / (float)(lengths.Length - 1); + currPt = Mathf.Min(Mathf.FloorToInt(num3 * (float)numSections), numSections - 1); + float num4 = lengths[j] / totalLength; + num2 += num4; + lengthRatio[j] = num2; + } + } + + public float map(float t) + { + for (int i = 0; i < lengthRatio.Length; i++) + { + if (lengthRatio[i] >= t) + { + return lengthRatio[i] + (t - lengthRatio[i]); + } + } + return 1f; + } + + public Vector3 interp(float t) + { + currPt = Mathf.Min(Mathf.FloorToInt(t * (float)numSections), numSections - 1); + float num = t * (float)numSections - (float)currPt; + Vector3 a = pts[currPt]; + Vector3 a2 = pts[currPt + 1]; + Vector3 vector = pts[currPt + 2]; + Vector3 b = pts[currPt + 3]; + return 0.5f * ((-a + 3f * a2 - 3f * vector + b) * (num * num * num) + (2f * a - 5f * a2 + 4f * vector - b) * (num * num) + (-a + vector) * num + 2f * a2); + } + + public Vector3 point(float ratio) + { + float t = map(ratio); + return interp(t); + } + + public void place(Transform transform, float ratio) + { + place(transform, ratio, Vector3.up); + } + + public void place(Transform transform, float ratio, Vector3 worldUp) + { + transform.position = point(ratio); + ratio += 0.001f; + if (ratio <= 1f) + { + transform.LookAt(point(ratio), worldUp); + } + } + + public void placeLocal(Transform transform, float ratio) + { + placeLocal(transform, ratio, Vector3.up); + } + + public void placeLocal(Transform transform, float ratio, Vector3 worldUp) + { + transform.localPosition = point(ratio); + ratio += 0.001f; + if (ratio <= 1f) + { + transform.LookAt(transform.parent.TransformPoint(point(ratio)), worldUp); + } + } + + public void gizmoDraw(float t = -1f) + { + if (lengthRatio != null && lengthRatio.Length > 0) + { + Vector3 to = point(0f); + for (int i = 1; i <= 120; i++) + { + float ratio = (float)i / 120f; + Vector3 vector = point(ratio); + Gizmos.DrawLine(vector, to); + to = vector; + } + } + } + + public Vector3 Velocity(float t) + { + t = map(t); + int num = pts.Length - 3; + int num2 = Mathf.Min(Mathf.FloorToInt(t * (float)num), num - 1); + float num3 = t * (float)num - (float)num2; + Vector3 a = pts[num2]; + Vector3 a2 = pts[num2 + 1]; + Vector3 a3 = pts[num2 + 2]; + Vector3 b = pts[num2 + 3]; + return 1.5f * (-a + 3f * a2 - 3f * a3 + b) * (num3 * num3) + (2f * a - 5f * a2 + 4f * a3 - b) * num3 + 0.5f * a3 - 0.5f * a; + } +} diff --git a/LanguageSelection.cs b/LanguageSelection.cs new file mode 100644 index 00000000..f388b062 --- /dev/null +++ b/LanguageSelection.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Language Selection")] +[RequireComponent(typeof(UIPopupList))] +public class LanguageSelection : MonoBehaviour +{ + private UIPopupList mList; + + private void Start() + { + mList = GetComponent(); + if (Localization.knownLanguages != null) + { + mList.items.Clear(); + int i = 0; + for (int num = Localization.knownLanguages.Length; i < num; i++) + { + mList.items.Add(Localization.knownLanguages[i]); + } + mList.value = Localization.language; + } + EventDelegate.Add(mList.onChange, OnChange); + } + + private void OnChange() + { + Localization.language = UIPopupList.current.value; + } +} diff --git a/LeanTween.cs b/LeanTween.cs new file mode 100644 index 00000000..2c247a61 --- /dev/null +++ b/LeanTween.cs @@ -0,0 +1,2721 @@ +using System; +using System.Collections; +using UnityEngine; + +public class LeanTween : MonoBehaviour +{ + public static bool throwErrors = true; + + private static LTDescr[] tweens; + + private static int tweenMaxSearch = 0; + + private static int maxTweens = 400; + + private static int frameRendered = -1; + + private static GameObject _tweenEmpty; + + private static float dtEstimated; + + private static float previousRealTime; + + private static float dt; + + private static float dtActual; + + private static LTDescr tween; + + private static int i; + + private static int j; + + private static AnimationCurve punch = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.112586f, 0.9976035f), new Keyframe(0.3120486f, -0.1720615f), new Keyframe(0.4316337f, 0.07030682f), new Keyframe(0.5524869f, -0.03141804f), new Keyframe(0.6549395f, 0.003909959f), new Keyframe(0.770987f, -0.009817753f), new Keyframe(0.8838775f, 0.001939224f), new Keyframe(1f, 0f)); + + private static AnimationCurve shake = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.25f, 1f), new Keyframe(0.75f, -1f), new Keyframe(1f, 0f)); + + private static Transform trans; + + private static float timeTotal; + + private static TweenAction tweenAction; + + private static float ratioPassed; + + private static float from; + + private static float to; + + private static float val; + + private static Vector3 newVect; + + private static bool isTweenFinished; + + private static GameObject target; + + private static GameObject customTarget; + + public static int startSearch = 0; + + public static LTDescr descr; + + private static Action[] eventListeners; + + private static GameObject[] goListeners; + + private static int eventsMaxSearch = 0; + + public static int EVENTS_MAX = 10; + + public static int LISTENERS_MAX = 10; + + public static GameObject tweenEmpty + { + get + { + init(maxTweens); + return _tweenEmpty; + } + } + + public static void init() + { + init(maxTweens); + } + + public static void init(int maxSimultaneousTweens) + { + if (tweens == null) + { + maxTweens = maxSimultaneousTweens; + tweens = new LTDescr[maxTweens]; + _tweenEmpty = new GameObject(); + _tweenEmpty.name = "~LeanTween"; + _tweenEmpty.AddComponent(typeof(LeanTween)); + _tweenEmpty.isStatic = true; + _tweenEmpty.hideFlags = HideFlags.HideAndDontSave; + UnityEngine.Object.DontDestroyOnLoad(_tweenEmpty); + for (int i = 0; i < maxTweens; i++) + { + tweens[i] = new LTDescr(); + } + } + } + + public static void reset() + { + tweens = null; + } + + public void Update() + { + update(); + } + + public void OnLevelWasLoaded(int lvl) + { + LTGUI.reset(); + } + + public static void update() + { + if (frameRendered != Time.frameCount) + { + init(); + dtEstimated = Time.realtimeSinceStartup - previousRealTime; + if (dtEstimated > 0.2f) + { + dtEstimated = 0.2f; + } + previousRealTime = Time.realtimeSinceStartup; + dtActual = Time.deltaTime * Time.timeScale; + for (int i = 0; i < tweenMaxSearch && i < maxTweens; i++) + { + if (tweens[i].toggle) + { + tween = tweens[i]; + trans = tween.trans; + timeTotal = tween.time; + tweenAction = tween.type; + dt = dtActual; + if (tween.useEstimatedTime) + { + dt = dtEstimated; + timeTotal = tween.time; + } + else if (tween.useFrames) + { + dt = 1f; + } + else if (tween.direction == 0f) + { + dt = 0f; + } + if (trans == null) + { + removeTween(i); + } + else + { + isTweenFinished = false; + if (tween.delay <= 0f) + { + if (tween.passed + dt > timeTotal && tween.direction > 0f) + { + isTweenFinished = true; + tween.passed = tween.time; + } + else if (tween.direction < 0f && tween.passed - dt < 0f) + { + isTweenFinished = true; + tween.passed = Mathf.Epsilon; + } + } + if (!tween.hasInitiliazed && (((double)tween.passed == 0.0 && (double)tween.delay == 0.0) || (double)tween.passed > 0.0)) + { + tween.hasInitiliazed = true; + if (!tween.useEstimatedTime) + { + tween.time *= Time.timeScale; + } + switch (tweenAction) + { + case TweenAction.MOVE: + tween.from = trans.position; + break; + case TweenAction.MOVE_X: + { + ref Vector3 reference7 = ref tween.from; + Vector3 position2 = trans.position; + reference7.x = position2.x; + break; + } + case TweenAction.MOVE_Y: + { + ref Vector3 reference8 = ref tween.from; + Vector3 position3 = trans.position; + reference8.x = position3.y; + break; + } + case TweenAction.MOVE_Z: + { + ref Vector3 reference = ref tween.from; + Vector3 position = trans.position; + reference.x = position.z; + break; + } + case TweenAction.MOVE_LOCAL_X: + { + ref Vector3 reference2 = ref tweens[i].from; + Vector3 localPosition = trans.localPosition; + reference2.x = localPosition.x; + break; + } + case TweenAction.MOVE_LOCAL_Y: + { + ref Vector3 reference13 = ref tweens[i].from; + Vector3 localPosition3 = trans.localPosition; + reference13.x = localPosition3.y; + break; + } + case TweenAction.MOVE_LOCAL_Z: + { + ref Vector3 reference12 = ref tweens[i].from; + Vector3 localPosition2 = trans.localPosition; + reference12.x = localPosition2.z; + break; + } + case TweenAction.SCALE_X: + { + ref Vector3 reference11 = ref tween.from; + Vector3 localScale3 = trans.localScale; + reference11.x = localScale3.x; + break; + } + case TweenAction.SCALE_Y: + { + ref Vector3 reference10 = ref tween.from; + Vector3 localScale2 = trans.localScale; + reference10.x = localScale2.y; + break; + } + case TweenAction.SCALE_Z: + { + ref Vector3 reference9 = ref tween.from; + Vector3 localScale = trans.localScale; + reference9.x = localScale.z; + break; + } + case TweenAction.ALPHA: + { + SpriteRenderer component = trans.gameObject.GetComponent(); + ref Vector3 reference6 = ref tween.from; + float a; + if (component != null) + { + Color color = component.color; + a = color.a; + } + else + { + Color color2 = trans.gameObject.GetComponent().material.color; + a = color2.a; + } + reference6.x = a; + break; + } + case TweenAction.MOVE_LOCAL: + tween.from = trans.localPosition; + break; + case TweenAction.MOVE_CURVED: + case TweenAction.MOVE_CURVED_LOCAL: + case TweenAction.MOVE_SPLINE: + case TweenAction.MOVE_SPLINE_LOCAL: + tween.from.x = 0f; + break; + case TweenAction.ROTATE: + tween.from = trans.eulerAngles; + tween.to = new Vector3(closestRot(tween.from.x, tween.to.x), closestRot(tween.from.y, tween.to.y), closestRot(tween.from.z, tween.to.z)); + break; + case TweenAction.ROTATE_X: + { + ref Vector3 reference5 = ref tween.from; + Vector3 eulerAngles3 = trans.eulerAngles; + reference5.x = eulerAngles3.x; + tween.to.x = closestRot(tween.from.x, tween.to.x); + break; + } + case TweenAction.ROTATE_Y: + { + ref Vector3 reference4 = ref tween.from; + Vector3 eulerAngles2 = trans.eulerAngles; + reference4.x = eulerAngles2.y; + tween.to.x = closestRot(tween.from.x, tween.to.x); + break; + } + case TweenAction.ROTATE_Z: + { + ref Vector3 reference3 = ref tween.from; + Vector3 eulerAngles = trans.eulerAngles; + reference3.x = eulerAngles.z; + tween.to.x = closestRot(tween.from.x, tween.to.x); + break; + } + case TweenAction.ROTATE_AROUND: + tween.lastVal = 0f; + tween.origRotation = trans.eulerAngles; + break; + case TweenAction.ROTATE_LOCAL: + tween.from = trans.localEulerAngles; + tween.to = new Vector3(closestRot(tween.from.x, tween.to.x), closestRot(tween.from.y, tween.to.y), closestRot(tween.from.z, tween.to.z)); + break; + case TweenAction.SCALE: + tween.from = trans.localScale; + break; + case TweenAction.GUI_MOVE: + tween.from = new Vector3(tween.ltRect.rect.x, tween.ltRect.rect.y, 0f); + break; + case TweenAction.GUI_MOVE_MARGIN: + tween.from = new Vector2(tween.ltRect.margin.x, tween.ltRect.margin.y); + break; + case TweenAction.GUI_SCALE: + tween.from = new Vector3(tween.ltRect.rect.width, tween.ltRect.rect.height, 0f); + break; + case TweenAction.GUI_ALPHA: + tween.from.x = tween.ltRect.alpha; + break; + case TweenAction.GUI_ROTATE: + if (!tween.ltRect.rotateEnabled) + { + tween.ltRect.rotateEnabled = true; + tween.ltRect.resetForRotation(); + } + tween.from.x = tween.ltRect.rotation; + break; + case TweenAction.ALPHA_VERTEX: + tween.from.x = (float)(int)trans.GetComponent().mesh.colors32[0].a; + break; + } + tween.diff = tween.to - tween.from; + } + if (tween.delay <= 0f) + { + if (timeTotal <= 0f) + { + ratioPassed = 0f; + } + else + { + ratioPassed = tween.passed / timeTotal; + } + if (ratioPassed > 1f) + { + ratioPassed = 1f; + } + else if (ratioPassed < 0f) + { + ratioPassed = 0f; + } + if (tweenAction >= TweenAction.MOVE_X && tweenAction <= TweenAction.CALLBACK) + { + if (tween.animationCurve == null) + { + switch (tween.tweenType) + { + case LeanTweenType.linear: + val = tween.from.x + tween.diff.x * ratioPassed; + break; + case LeanTweenType.easeOutQuad: + val = easeOutQuadOpt(tween.from.x, tween.diff.x, ratioPassed); + break; + case LeanTweenType.easeInQuad: + val = easeInQuadOpt(tween.from.x, tween.diff.x, ratioPassed); + break; + case LeanTweenType.easeInOutQuad: + val = easeInOutQuadOpt(tween.from.x, tween.diff.x, ratioPassed); + break; + case LeanTweenType.easeInCubic: + val = easeInCubic(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutCubic: + val = easeOutCubic(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutCubic: + val = easeInOutCubic(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInQuart: + val = easeInQuart(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutQuart: + val = easeOutQuart(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutQuart: + val = easeInOutQuart(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInQuint: + val = easeInQuint(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutQuint: + val = easeOutQuint(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutQuint: + val = easeInOutQuint(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInSine: + val = easeInSine(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutSine: + val = easeOutSine(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutSine: + val = easeInOutSine(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInExpo: + val = easeInExpo(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutExpo: + val = easeOutExpo(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutExpo: + val = easeInOutExpo(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInCirc: + val = easeInCirc(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutCirc: + val = easeOutCirc(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutCirc: + val = easeInOutCirc(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInBounce: + val = easeInBounce(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutBounce: + val = easeOutBounce(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutBounce: + val = easeInOutBounce(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInBack: + val = easeInBack(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutBack: + val = easeOutBack(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutBack: + val = easeInOutElastic(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInElastic: + val = easeInElastic(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeOutElastic: + val = easeOutElastic(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeInOutElastic: + val = easeInOutElastic(tween.from.x, tween.to.x, ratioPassed); + break; + case LeanTweenType.easeShake: + case LeanTweenType.punch: + if (tween.tweenType == LeanTweenType.punch) + { + tween.animationCurve = punch; + } + else if (tween.tweenType == LeanTweenType.easeShake) + { + tween.animationCurve = shake; + } + tween.to.x = tween.from.x + tween.to.x; + tween.diff.x = tween.to.x - tween.from.x; + val = tweenOnCurve(tween, ratioPassed); + break; + case LeanTweenType.easeSpring: + val = spring(tween.from.x, tween.to.x, ratioPassed); + break; + default: + val = tween.from.x + tween.diff.x * ratioPassed; + break; + } + } + else + { + val = tweenOnCurve(tween, ratioPassed); + } + if (tweenAction == TweenAction.MOVE_X) + { + Transform transform = trans; + float x = val; + Vector3 position4 = trans.position; + float y = position4.y; + Vector3 position5 = trans.position; + transform.position = new Vector3(x, y, position5.z); + } + else if (tweenAction == TweenAction.MOVE_Y) + { + Transform transform2 = trans; + Vector3 position6 = trans.position; + float x2 = position6.x; + float y2 = val; + Vector3 position7 = trans.position; + transform2.position = new Vector3(x2, y2, position7.z); + } + else if (tweenAction == TweenAction.MOVE_Z) + { + Transform transform3 = trans; + Vector3 position8 = trans.position; + float x3 = position8.x; + Vector3 position9 = trans.position; + transform3.position = new Vector3(x3, position9.y, val); + } + if (tweenAction == TweenAction.MOVE_LOCAL_X) + { + Transform transform4 = trans; + float x4 = val; + Vector3 localPosition4 = trans.localPosition; + float y3 = localPosition4.y; + Vector3 localPosition5 = trans.localPosition; + transform4.localPosition = new Vector3(x4, y3, localPosition5.z); + } + else if (tweenAction == TweenAction.MOVE_LOCAL_Y) + { + Transform transform5 = trans; + Vector3 localPosition6 = trans.localPosition; + float x5 = localPosition6.x; + float y4 = val; + Vector3 localPosition7 = trans.localPosition; + transform5.localPosition = new Vector3(x5, y4, localPosition7.z); + } + else if (tweenAction == TweenAction.MOVE_LOCAL_Z) + { + Transform transform6 = trans; + Vector3 localPosition8 = trans.localPosition; + float x6 = localPosition8.x; + Vector3 localPosition9 = trans.localPosition; + transform6.localPosition = new Vector3(x6, localPosition9.y, val); + } + else if (tweenAction == TweenAction.MOVE_CURVED) + { + if (tween.path.orientToPath) + { + tween.path.place(trans, val); + } + else + { + trans.position = tween.path.point(val); + } + } + else if (tweenAction == TweenAction.MOVE_CURVED_LOCAL) + { + if (tween.path.orientToPath) + { + tween.path.placeLocal(trans, val); + } + else + { + trans.localPosition = tween.path.point(val); + } + } + else if (tweenAction == TweenAction.MOVE_SPLINE) + { + if (tween.spline.orientToPath) + { + tween.spline.place(trans, val); + } + else + { + trans.position = tween.spline.point(val); + } + } + else if (tweenAction == TweenAction.MOVE_SPLINE_LOCAL) + { + if (tween.spline.orientToPath) + { + tween.spline.placeLocal(trans, val); + } + else + { + trans.localPosition = tween.spline.point(val); + } + } + else if (tweenAction == TweenAction.SCALE_X) + { + Transform transform7 = trans; + float x7 = val; + Vector3 localScale4 = trans.localScale; + float y5 = localScale4.y; + Vector3 localScale5 = trans.localScale; + transform7.localScale = new Vector3(x7, y5, localScale5.z); + } + else if (tweenAction == TweenAction.SCALE_Y) + { + Transform transform8 = trans; + Vector3 localScale6 = trans.localScale; + float x8 = localScale6.x; + float y6 = val; + Vector3 localScale7 = trans.localScale; + transform8.localScale = new Vector3(x8, y6, localScale7.z); + } + else if (tweenAction == TweenAction.SCALE_Z) + { + Transform transform9 = trans; + Vector3 localScale8 = trans.localScale; + float x9 = localScale8.x; + Vector3 localScale9 = trans.localScale; + transform9.localScale = new Vector3(x9, localScale9.y, val); + } + else if (tweenAction == TweenAction.ROTATE_X) + { + Transform transform10 = trans; + float x10 = val; + Vector3 eulerAngles4 = trans.eulerAngles; + float y7 = eulerAngles4.y; + Vector3 eulerAngles5 = trans.eulerAngles; + transform10.eulerAngles = new Vector3(x10, y7, eulerAngles5.z); + } + else if (tweenAction == TweenAction.ROTATE_Y) + { + Transform transform11 = trans; + Vector3 eulerAngles6 = trans.eulerAngles; + float x11 = eulerAngles6.x; + float y8 = val; + Vector3 eulerAngles7 = trans.eulerAngles; + transform11.eulerAngles = new Vector3(x11, y8, eulerAngles7.z); + } + else if (tweenAction == TweenAction.ROTATE_Z) + { + Transform transform12 = trans; + Vector3 eulerAngles8 = trans.eulerAngles; + float x12 = eulerAngles8.x; + Vector3 eulerAngles9 = trans.eulerAngles; + transform12.eulerAngles = new Vector3(x12, eulerAngles9.y, val); + } + else if (tweenAction == TweenAction.ROTATE_AROUND) + { + float angle = val - tween.lastVal; + if (isTweenFinished) + { + trans.eulerAngles = tween.origRotation; + trans.RotateAround(trans.TransformPoint(tween.point), tween.axis, tween.to.x); + } + else + { + trans.RotateAround(trans.TransformPoint(tween.point), tween.axis, angle); + tween.lastVal = val; + } + } + else if (tweenAction == TweenAction.ALPHA) + { + SpriteRenderer component2 = trans.gameObject.GetComponent(); + if (component2 != null) + { + SpriteRenderer spriteRenderer = component2; + Color color3 = component2.color; + float r = color3.r; + Color color4 = component2.color; + float g = color4.g; + Color color5 = component2.color; + spriteRenderer.color = new Color(r, g, color5.b, val); + } + else + { + Material[] materials = trans.gameObject.GetComponent().materials; + foreach (Material material in materials) + { + Material material2 = material; + Color color6 = material.color; + float r2 = color6.r; + Color color7 = material.color; + float g2 = color7.g; + Color color8 = material.color; + material2.color = new Color(r2, g2, color8.b, val); + } + } + } + else if (tweenAction == TweenAction.ALPHA_VERTEX) + { + Mesh mesh = trans.GetComponent().mesh; + Vector3[] vertices = mesh.vertices; + Color32[] array = new Color32[vertices.Length]; + Color32 color9 = mesh.colors32[0]; + color9 = new Color((float)(int)color9.r, (float)(int)color9.g, (float)(int)color9.b, val); + for (int k = 0; k < vertices.Length; k++) + { + array[k] = color9; + } + mesh.colors32 = array; + } + } + else if (tweenAction >= TweenAction.MOVE) + { + if (tween.animationCurve != null) + { + newVect = tweenOnCurveVector(tween, ratioPassed); + } + else if (tween.tweenType == LeanTweenType.linear) + { + newVect = new Vector3(tween.from.x + tween.diff.x * ratioPassed, tween.from.y + tween.diff.y * ratioPassed, tween.from.z + tween.diff.z * ratioPassed); + } + else if (tween.tweenType >= LeanTweenType.linear) + { + switch (tween.tweenType) + { + case LeanTweenType.easeOutQuad: + newVect = new Vector3(easeOutQuadOpt(tween.from.x, tween.diff.x, ratioPassed), easeOutQuadOpt(tween.from.y, tween.diff.y, ratioPassed), easeOutQuadOpt(tween.from.z, tween.diff.z, ratioPassed)); + break; + case LeanTweenType.easeInQuad: + newVect = new Vector3(easeInQuadOpt(tween.from.x, tween.diff.x, ratioPassed), easeInQuadOpt(tween.from.y, tween.diff.y, ratioPassed), easeInQuadOpt(tween.from.z, tween.diff.z, ratioPassed)); + break; + case LeanTweenType.easeInOutQuad: + newVect = new Vector3(easeInOutQuadOpt(tween.from.x, tween.diff.x, ratioPassed), easeInOutQuadOpt(tween.from.y, tween.diff.y, ratioPassed), easeInOutQuadOpt(tween.from.z, tween.diff.z, ratioPassed)); + break; + case LeanTweenType.easeInCubic: + newVect = new Vector3(easeInCubic(tween.from.x, tween.to.x, ratioPassed), easeInCubic(tween.from.y, tween.to.y, ratioPassed), easeInCubic(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutCubic: + newVect = new Vector3(easeOutCubic(tween.from.x, tween.to.x, ratioPassed), easeOutCubic(tween.from.y, tween.to.y, ratioPassed), easeOutCubic(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutCubic: + newVect = new Vector3(easeInOutCubic(tween.from.x, tween.to.x, ratioPassed), easeInOutCubic(tween.from.y, tween.to.y, ratioPassed), easeInOutCubic(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInQuart: + newVect = new Vector3(easeInQuart(tween.from.x, tween.to.x, ratioPassed), easeInQuart(tween.from.y, tween.to.y, ratioPassed), easeInQuart(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutQuart: + newVect = new Vector3(easeOutQuart(tween.from.x, tween.to.x, ratioPassed), easeOutQuart(tween.from.y, tween.to.y, ratioPassed), easeOutQuart(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutQuart: + newVect = new Vector3(easeInOutQuart(tween.from.x, tween.to.x, ratioPassed), easeInOutQuart(tween.from.y, tween.to.y, ratioPassed), easeInOutQuart(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInQuint: + newVect = new Vector3(easeInQuint(tween.from.x, tween.to.x, ratioPassed), easeInQuint(tween.from.y, tween.to.y, ratioPassed), easeInQuint(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutQuint: + newVect = new Vector3(easeOutQuint(tween.from.x, tween.to.x, ratioPassed), easeOutQuint(tween.from.y, tween.to.y, ratioPassed), easeOutQuint(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutQuint: + newVect = new Vector3(easeInOutQuint(tween.from.x, tween.to.x, ratioPassed), easeInOutQuint(tween.from.y, tween.to.y, ratioPassed), easeInOutQuint(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInSine: + newVect = new Vector3(easeInSine(tween.from.x, tween.to.x, ratioPassed), easeInSine(tween.from.y, tween.to.y, ratioPassed), easeInSine(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutSine: + newVect = new Vector3(easeOutSine(tween.from.x, tween.to.x, ratioPassed), easeOutSine(tween.from.y, tween.to.y, ratioPassed), easeOutSine(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutSine: + newVect = new Vector3(easeInOutSine(tween.from.x, tween.to.x, ratioPassed), easeInOutSine(tween.from.y, tween.to.y, ratioPassed), easeInOutSine(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInExpo: + newVect = new Vector3(easeInExpo(tween.from.x, tween.to.x, ratioPassed), easeInExpo(tween.from.y, tween.to.y, ratioPassed), easeInExpo(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutExpo: + newVect = new Vector3(easeOutExpo(tween.from.x, tween.to.x, ratioPassed), easeOutExpo(tween.from.y, tween.to.y, ratioPassed), easeOutExpo(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutExpo: + newVect = new Vector3(easeInOutExpo(tween.from.x, tween.to.x, ratioPassed), easeInOutExpo(tween.from.y, tween.to.y, ratioPassed), easeInOutExpo(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInCirc: + newVect = new Vector3(easeInCirc(tween.from.x, tween.to.x, ratioPassed), easeInCirc(tween.from.y, tween.to.y, ratioPassed), easeInCirc(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutCirc: + newVect = new Vector3(easeOutCirc(tween.from.x, tween.to.x, ratioPassed), easeOutCirc(tween.from.y, tween.to.y, ratioPassed), easeOutCirc(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutCirc: + newVect = new Vector3(easeInOutCirc(tween.from.x, tween.to.x, ratioPassed), easeInOutCirc(tween.from.y, tween.to.y, ratioPassed), easeInOutCirc(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInBounce: + newVect = new Vector3(easeInBounce(tween.from.x, tween.to.x, ratioPassed), easeInBounce(tween.from.y, tween.to.y, ratioPassed), easeInBounce(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutBounce: + newVect = new Vector3(easeOutBounce(tween.from.x, tween.to.x, ratioPassed), easeOutBounce(tween.from.y, tween.to.y, ratioPassed), easeOutBounce(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutBounce: + newVect = new Vector3(easeInOutBounce(tween.from.x, tween.to.x, ratioPassed), easeInOutBounce(tween.from.y, tween.to.y, ratioPassed), easeInOutBounce(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInBack: + newVect = new Vector3(easeInBack(tween.from.x, tween.to.x, ratioPassed), easeInBack(tween.from.y, tween.to.y, ratioPassed), easeInBack(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutBack: + newVect = new Vector3(easeOutBack(tween.from.x, tween.to.x, ratioPassed), easeOutBack(tween.from.y, tween.to.y, ratioPassed), easeOutBack(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutBack: + newVect = new Vector3(easeInOutBack(tween.from.x, tween.to.x, ratioPassed), easeInOutBack(tween.from.y, tween.to.y, ratioPassed), easeInOutBack(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInElastic: + newVect = new Vector3(easeInElastic(tween.from.x, tween.to.x, ratioPassed), easeInElastic(tween.from.y, tween.to.y, ratioPassed), easeInElastic(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeOutElastic: + newVect = new Vector3(easeOutElastic(tween.from.x, tween.to.x, ratioPassed), easeOutElastic(tween.from.y, tween.to.y, ratioPassed), easeOutElastic(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeInOutElastic: + newVect = new Vector3(easeInOutElastic(tween.from.x, tween.to.x, ratioPassed), easeInOutElastic(tween.from.y, tween.to.y, ratioPassed), easeInOutElastic(tween.from.z, tween.to.z, ratioPassed)); + break; + case LeanTweenType.easeShake: + case LeanTweenType.punch: + if (tween.tweenType == LeanTweenType.punch) + { + tween.animationCurve = punch; + } + else if (tween.tweenType == LeanTweenType.easeShake) + { + tween.animationCurve = shake; + } + tween.to = tween.from + tween.to; + tween.diff = tween.to - tween.from; + if (tweenAction == TweenAction.ROTATE || tweenAction == TweenAction.ROTATE_LOCAL) + { + tween.to = new Vector3(closestRot(tween.from.x, tween.to.x), closestRot(tween.from.y, tween.to.y), closestRot(tween.from.z, tween.to.z)); + } + newVect = tweenOnCurveVector(tween, ratioPassed); + break; + case LeanTweenType.easeSpring: + newVect = new Vector3(spring(tween.from.x, tween.to.x, ratioPassed), spring(tween.from.y, tween.to.y, ratioPassed), spring(tween.from.z, tween.to.z, ratioPassed)); + break; + } + } + else + { + newVect = new Vector3(tween.from.x + tween.diff.x * ratioPassed, tween.from.y + tween.diff.y * ratioPassed, tween.from.z + tween.diff.z * ratioPassed); + } + if (tweenAction == TweenAction.MOVE) + { + trans.position = newVect; + } + else if (tweenAction == TweenAction.MOVE_LOCAL) + { + trans.localPosition = newVect; + } + else if (tweenAction == TweenAction.ROTATE) + { + trans.eulerAngles = newVect; + } + else if (tweenAction == TweenAction.ROTATE_LOCAL) + { + trans.localEulerAngles = newVect; + } + else if (tweenAction == TweenAction.SCALE) + { + trans.localScale = newVect; + } + else if (tweenAction == TweenAction.GUI_MOVE) + { + tween.ltRect.rect = new Rect(newVect.x, newVect.y, tween.ltRect.rect.width, tween.ltRect.rect.height); + } + else if (tweenAction == TweenAction.GUI_MOVE_MARGIN) + { + tween.ltRect.margin = new Vector2(newVect.x, newVect.y); + } + else if (tweenAction == TweenAction.GUI_SCALE) + { + tween.ltRect.rect = new Rect(tween.ltRect.rect.x, tween.ltRect.rect.y, newVect.x, newVect.y); + } + else if (tweenAction == TweenAction.GUI_ALPHA) + { + tween.ltRect.alpha = newVect.x; + } + else if (tweenAction == TweenAction.GUI_ROTATE) + { + tween.ltRect.rotation = newVect.x; + } + } + if (tween.onUpdateFloat != null) + { + tween.onUpdateFloat(val); + } + else if (tween.onUpdateFloatObject != null) + { + tween.onUpdateFloatObject(val, tween.onUpdateParam); + } + else if (tween.onUpdateVector3Object != null) + { + tween.onUpdateVector3Object(newVect, tween.onUpdateParam); + } + else if (tween.onUpdateVector3 != null) + { + tween.onUpdateVector3(newVect); + } + else if (tween.optional != null) + { + object obj = tween.optional["onUpdate"]; + if (obj != null) + { + Hashtable arg = (Hashtable)tween.optional["onUpdateParam"]; + if (tweenAction == TweenAction.VALUE3) + { + if (obj.GetType() == typeof(string)) + { + string methodName = obj as string; + customTarget = ((tween.optional["onUpdateTarget"] == null) ? trans.gameObject : (tween.optional["onUpdateTarget"] as GameObject)); + customTarget.BroadcastMessage(methodName, newVect); + } + else if (obj.GetType() == typeof(Action)) + { + Action action = (Action)obj; + action(newVect, arg); + } + else + { + Action action2 = (Action)obj; + action2(newVect); + } + } + else if (obj.GetType() == typeof(string)) + { + string methodName2 = obj as string; + if (tween.optional["onUpdateTarget"] != null) + { + customTarget = (tween.optional["onUpdateTarget"] as GameObject); + customTarget.BroadcastMessage(methodName2, val); + } + else + { + trans.gameObject.BroadcastMessage(methodName2, val); + } + } + else if (obj.GetType() == typeof(Action)) + { + Action action3 = (Action)obj; + action3(val, arg); + } + else if (obj.GetType() == typeof(Action)) + { + Action action4 = (Action)obj; + action4(newVect); + } + else + { + Action action5 = (Action)obj; + action5(val); + } + } + } + } + if (isTweenFinished) + { + if (tweenAction == TweenAction.GUI_ROTATE) + { + tween.ltRect.rotateFinished = true; + } + if (tween.loopType == LeanTweenType.once || tween.loopCount == 1) + { + if (tweenAction == TweenAction.DELAYED_SOUND) + { + AudioSource.PlayClipAtPoint((AudioClip)tween.onCompleteParam, tween.to, tween.from.x); + } + if (tween.onComplete != null) + { + removeTween(i); + tween.onComplete(); + } + else if (tween.onCompleteObject != null) + { + removeTween(i); + tween.onCompleteObject(tween.onCompleteParam); + } + else if (tween.optional != null) + { + Action action6 = null; + Action action7 = null; + string text = string.Empty; + object obj2 = null; + if (tween.optional != null && (bool)tween.trans && tween.optional["onComplete"] != null) + { + obj2 = tween.optional["onCompleteParam"]; + if (tween.optional["onComplete"].GetType() == typeof(string)) + { + text = (tween.optional["onComplete"] as string); + } + else if (obj2 != null) + { + action7 = (Action)tween.optional["onComplete"]; + } + else + { + action6 = (Action)tween.optional["onComplete"]; + if (action6 == null) + { + Debug.LogWarning("callback was not converted"); + } + } + } + removeTween(i); + if (action7 != null) + { + action7(obj2); + } + else if (action6 != null) + { + action6(); + } + else if (text != string.Empty) + { + if (tween.optional["onCompleteTarget"] != null) + { + customTarget = (tween.optional["onCompleteTarget"] as GameObject); + if (obj2 != null) + { + customTarget.BroadcastMessage(text, obj2); + } + else + { + customTarget.BroadcastMessage(text); + } + } + else if (obj2 != null) + { + trans.gameObject.BroadcastMessage(text, obj2); + } + else + { + trans.gameObject.BroadcastMessage(text); + } + } + } + else + { + removeTween(i); + } + } + else + { + if (tween.loopCount < 0 && tween.type == TweenAction.CALLBACK) + { + if (tween.onComplete != null) + { + tween.onComplete(); + } + else if (tween.onCompleteObject != null) + { + tween.onCompleteObject(tween.onCompleteParam); + } + } + if (tween.loopCount >= 1) + { + tween.loopCount--; + } + if (tween.loopType == LeanTweenType.clamp) + { + tween.passed = Mathf.Epsilon; + } + else if (tween.loopType == LeanTweenType.pingPong) + { + tween.direction = 0f - tween.direction; + } + } + } + else if (tween.delay <= 0f) + { + tween.passed += dt * tween.direction; + } + else + { + tween.delay -= dt; + if (tween.delay < 0f) + { + tween.passed = 0f; + tween.delay = 0f; + } + } + } + } + } + frameRendered = Time.frameCount; + } + } + + public static void removeTween(int i) + { + if (tweens[i].toggle) + { + tweens[i].toggle = false; + if (tweens[i].destroyOnComplete && tweens[i].ltRect != null) + { + LTGUI.destroy(tweens[i].ltRect.id); + } + startSearch = i; + if (i + 1 >= tweenMaxSearch) + { + startSearch = 0; + tweenMaxSearch--; + } + } + } + + public static Vector3[] add(Vector3[] a, Vector3 b) + { + Vector3[] array = new Vector3[a.Length]; + for (i = 0; i < a.Length; i++) + { + array[i] = a[i] + b; + } + return array; + } + + public static float closestRot(float from, float to) + { + float num = 0f - (360f - to); + float num2 = 360f + to; + float num3 = Mathf.Abs(to - from); + float num4 = Mathf.Abs(num - from); + float num5 = Mathf.Abs(num2 - from); + if (num3 < num4 && num3 < num5) + { + return to; + } + if (num4 < num5) + { + return num; + } + return num2; + } + + public static void cancel(GameObject gameObject) + { + init(); + Transform transform = gameObject.transform; + for (int i = 0; i < tweenMaxSearch; i++) + { + if (tweens[i].trans == transform) + { + removeTween(i); + } + } + } + + public static void cancel(GameObject gameObject, int uniqueId) + { + if (uniqueId >= 0) + { + init(); + int num = uniqueId & 0xFFFF; + int num2 = uniqueId >> 16; + if (tweens[num].trans == null || (tweens[num].trans.gameObject == gameObject && tweens[num].counter == num2)) + { + removeTween(num); + } + } + } + + public static void cancel(LTRect ltRect, int uniqueId) + { + if (uniqueId >= 0) + { + init(); + int num = uniqueId & 0xFFFF; + int num2 = uniqueId >> 16; + if (tweens[num].ltRect == ltRect && tweens[num].counter == num2) + { + removeTween(num); + } + } + } + + private static void cancel(int uniqueId) + { + if (uniqueId >= 0) + { + init(); + int num = uniqueId & 0xFFFF; + int num2 = uniqueId >> 16; + if (tweens[num].hasInitiliazed && tweens[num].counter == num2) + { + removeTween(num); + } + } + } + + public static LTDescr description(int uniqueId) + { + int num = uniqueId & 0xFFFF; + int num2 = uniqueId >> 16; + if (tweens[num] != null && tweens[num].uniqueId == uniqueId && tweens[num].counter == num2) + { + return tweens[num]; + } + for (int i = 0; i < tweenMaxSearch; i++) + { + if (tweens[i].uniqueId == uniqueId && tweens[i].counter == num2) + { + return tweens[i]; + } + } + return null; + } + + public static void pause(GameObject gameObject, int uniqueId) + { + pause(uniqueId); + } + + public static void pause(int uniqueId) + { + int num = uniqueId & 0xFFFF; + int num2 = uniqueId >> 16; + if (tweens[num].counter == num2) + { + tweens[num].pause(); + } + } + + public static void pause(GameObject gameObject) + { + Transform transform = gameObject.transform; + for (int i = 0; i < tweenMaxSearch; i++) + { + if (tweens[i].trans == transform) + { + tweens[i].pause(); + } + } + } + + public static void resume(GameObject gameObject, int uniqueId) + { + resume(uniqueId); + } + + public static void resume(int uniqueId) + { + int num = uniqueId & 0xFFFF; + int num2 = uniqueId >> 16; + if (tweens[num].counter == num2) + { + tweens[num].resume(); + } + } + + public static void resume(GameObject gameObject) + { + Transform transform = gameObject.transform; + for (int i = 0; i < tweenMaxSearch; i++) + { + if (tweens[i].trans == transform) + { + tweens[i].resume(); + } + } + } + + public static bool isTweening(GameObject gameObject) + { + Transform transform = gameObject.transform; + for (int i = 0; i < tweenMaxSearch; i++) + { + if (tweens[i].toggle && tweens[i].trans == transform) + { + return true; + } + } + return false; + } + + public static bool isTweening(int uniqueId) + { + int num = uniqueId & 0xFFFF; + int num2 = uniqueId >> 16; + if (tweens[num].counter == num2 && tweens[num].toggle) + { + return true; + } + return false; + } + + public static bool isTweening(LTRect ltRect) + { + for (int i = 0; i < tweenMaxSearch; i++) + { + if (tweens[i].toggle && tweens[i].ltRect == ltRect) + { + return true; + } + } + return false; + } + + public static void drawBezierPath(Vector3 a, Vector3 b, Vector3 c, Vector3 d) + { + Vector3 vector = a; + Vector3 a2 = -a + 3f * (b - c) + d; + Vector3 b2 = 3f * (a + c) - 6f * b; + Vector3 b3 = 3f * (b - a); + for (float num = 1f; num <= 30f; num += 1f) + { + float d2 = num / 30f; + Vector3 vector2 = ((a2 * d2 + b2) * d2 + b3) * d2 + a; + Gizmos.DrawLine(vector, vector2); + vector = vector2; + } + } + + public static object logError(string error) + { + if (throwErrors) + { + Debug.LogError(error); + } + else + { + Debug.Log(error); + } + return null; + } + + public static LTDescr options(LTDescr seed) + { + Debug.LogError("error this function is no longer used"); + return null; + } + + public static LTDescr options() + { + init(); + j = 0; + i = startSearch; + while (j < maxTweens) + { + if (i >= maxTweens - 1) + { + i = 0; + } + if (!tweens[i].toggle) + { + if (i + 1 > tweenMaxSearch) + { + tweenMaxSearch = i + 1; + } + startSearch = i + 1; + break; + } + j++; + if (j >= maxTweens) + { + return logError("LeanTween - You have run out of available spaces for tweening. To avoid this error increase the number of spaces to available for tweening when you initialize the LeanTween class ex: LeanTween.init( " + maxTweens * 2 + " );") as LTDescr; + } + i++; + } + tween = tweens[i]; + tween.reset(); + tween.setId((uint)i); + return tween; + } + + private static LTDescr pushNewTween(GameObject gameObject, Vector3 to, float time, TweenAction tweenAction, LTDescr tween) + { + init(maxTweens); + if (gameObject == null) + { + return null; + } + tween.trans = gameObject.transform; + tween.to = to; + tween.time = time; + tween.type = tweenAction; + return tween; + } + + public static LTDescr alpha(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ALPHA, options()); + } + + public static LTDescr alpha(LTRect ltRect, float to, float time) + { + ltRect.alphaEnabled = true; + return pushNewTween(tweenEmpty, new Vector3(to, 0f, 0f), time, TweenAction.GUI_ALPHA, options().setRect(ltRect)); + } + + public static LTDescr alphaVertex(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ALPHA_VERTEX, options()); + } + + public static LTDescr delayedCall(float delayTime, Action callback) + { + return pushNewTween(tweenEmpty, Vector3.zero, delayTime, TweenAction.CALLBACK, options().setOnComplete(callback)); + } + + public static LTDescr delayedCall(float delayTime, Action callback) + { + return pushNewTween(tweenEmpty, Vector3.zero, delayTime, TweenAction.CALLBACK, options().setOnComplete(callback)); + } + + public static LTDescr delayedCall(GameObject gameObject, float delayTime, Action callback) + { + return pushNewTween(gameObject, Vector3.zero, delayTime, TweenAction.CALLBACK, options().setOnComplete(callback)); + } + + public static LTDescr delayedCall(GameObject gameObject, float delayTime, Action callback) + { + return pushNewTween(gameObject, Vector3.zero, delayTime, TweenAction.CALLBACK, options().setOnComplete(callback)); + } + + public static LTDescr destroyAfter(LTRect rect, float delayTime) + { + return pushNewTween(tweenEmpty, Vector3.zero, delayTime, TweenAction.CALLBACK, options().setRect(rect).setDestroyOnComplete(doesDestroy: true)); + } + + public static LTDescr move(GameObject gameObject, Vector3 to, float time) + { + return pushNewTween(gameObject, to, time, TweenAction.MOVE, options()); + } + + public static LTDescr move(GameObject gameObject, Vector2 to, float time) + { + float x = to.x; + float y = to.y; + Vector3 position = gameObject.transform.position; + return pushNewTween(gameObject, new Vector3(x, y, position.z), time, TweenAction.MOVE, options()); + } + + public static LTDescr move(GameObject gameObject, Vector3[] to, float time) + { + descr = options(); + if (descr.path == null) + { + descr.path = new LTBezierPath(to); + } + else + { + descr.path.setPoints(to); + } + return pushNewTween(gameObject, new Vector3(1f, 0f, 0f), time, TweenAction.MOVE_CURVED, descr); + } + + public static LTDescr moveSpline(GameObject gameObject, Vector3[] to, float time) + { + descr = options(); + descr.spline = new LTSpline(to); + return pushNewTween(gameObject, new Vector3(1f, 0f, 0f), time, TweenAction.MOVE_SPLINE, descr); + } + + public static LTDescr moveSplineLocal(GameObject gameObject, Vector3[] to, float time) + { + descr = options(); + descr.spline = new LTSpline(to); + return pushNewTween(gameObject, new Vector3(1f, 0f, 0f), time, TweenAction.MOVE_SPLINE_LOCAL, descr); + } + + public static LTDescr move(LTRect ltRect, Vector2 to, float time) + { + return pushNewTween(tweenEmpty, to, time, TweenAction.GUI_MOVE, options().setRect(ltRect)); + } + + public static LTDescr moveMargin(LTRect ltRect, Vector2 to, float time) + { + return pushNewTween(tweenEmpty, to, time, TweenAction.GUI_MOVE_MARGIN, options().setRect(ltRect)); + } + + public static LTDescr moveX(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_X, options()); + } + + public static LTDescr moveY(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_Y, options()); + } + + public static LTDescr moveZ(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_Z, options()); + } + + public static LTDescr moveLocal(GameObject gameObject, Vector3 to, float time) + { + return pushNewTween(gameObject, to, time, TweenAction.MOVE_LOCAL, options()); + } + + public static LTDescr moveLocal(GameObject gameObject, Vector3[] to, float time) + { + descr = options(); + if (descr.path == null) + { + descr.path = new LTBezierPath(to); + } + else + { + descr.path.setPoints(to); + } + return pushNewTween(gameObject, new Vector3(1f, 0f, 0f), time, TweenAction.MOVE_CURVED_LOCAL, descr); + } + + public static LTDescr moveLocalX(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_LOCAL_X, options()); + } + + public static LTDescr moveLocalY(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_LOCAL_Y, options()); + } + + public static LTDescr moveLocalZ(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_LOCAL_Z, options()); + } + + public static LTDescr rotate(GameObject gameObject, Vector3 to, float time) + { + return pushNewTween(gameObject, to, time, TweenAction.ROTATE, options()); + } + + public static LTDescr rotate(LTRect ltRect, float to, float time) + { + return pushNewTween(tweenEmpty, new Vector3(to, 0f, 0f), time, TweenAction.GUI_ROTATE, options().setRect(ltRect)); + } + + public static LTDescr rotateLocal(GameObject gameObject, Vector3 to, float time) + { + return pushNewTween(gameObject, to, time, TweenAction.ROTATE_LOCAL, options()); + } + + public static LTDescr rotateX(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ROTATE_X, options()); + } + + public static LTDescr rotateY(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ROTATE_Y, options()); + } + + public static LTDescr rotateZ(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ROTATE_Z, options()); + } + + public static LTDescr rotateAround(GameObject gameObject, Vector3 axis, float add, float time) + { + return pushNewTween(gameObject, new Vector3(add, 0f, 0f), time, TweenAction.ROTATE_AROUND, options().setAxis(axis)); + } + + public static LTDescr scale(GameObject gameObject, Vector3 to, float time) + { + return pushNewTween(gameObject, to, time, TweenAction.SCALE, options()); + } + + public static LTDescr scale(LTRect ltRect, Vector2 to, float time) + { + return pushNewTween(tweenEmpty, to, time, TweenAction.GUI_SCALE, options().setRect(ltRect)); + } + + public static LTDescr scaleX(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.SCALE_X, options()); + } + + public static LTDescr scaleY(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.SCALE_Y, options()); + } + + public static LTDescr scaleZ(GameObject gameObject, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.SCALE_Z, options()); + } + + public static LTDescr value(GameObject gameObject, Action callOnUpdate, float from, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.CALLBACK, options().setTo(new Vector3(to, 0f, 0f)).setFrom(new Vector3(from, 0f, 0f)).setOnUpdate(callOnUpdate)); + } + + public static LTDescr value(GameObject gameObject, Action callOnUpdate, Vector3 from, Vector3 to, float time) + { + return pushNewTween(gameObject, to, time, TweenAction.VALUE3, options().setTo(to).setFrom(from).setOnUpdateVector3(callOnUpdate)); + } + + public static LTDescr value(GameObject gameObject, Action callOnUpdate, float from, float to, float time) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.CALLBACK, options().setTo(new Vector3(to, 0f, 0f)).setFrom(new Vector3(from, 0f, 0f)).setOnUpdateObject(callOnUpdate)); + } + + public static LTDescr delayedSound(AudioClip audio, Vector3 pos, float volume) + { + return pushNewTween(tweenEmpty, pos, 0f, TweenAction.DELAYED_SOUND, options().setTo(pos).setFrom(new Vector3(volume, 0f, 0f)).setAudio(audio)); + } + + public static Hashtable h(object[] arr) + { + if (arr.Length % 2 == 1) + { + logError("LeanTween - You have attempted to create a Hashtable with an odd number of values."); + return null; + } + Hashtable hashtable = new Hashtable(); + for (i = 0; i < arr.Length; i += 2) + { + hashtable.Add(arr[i] as string, arr[i + 1]); + } + return hashtable; + } + + private static int idFromUnique(int uniqueId) + { + return uniqueId & 0xFFFF; + } + + private static int pushNewTween(GameObject gameObject, Vector3 to, float time, TweenAction tweenAction, Hashtable optional) + { + init(maxTweens); + if (gameObject == null) + { + return -1; + } + j = 0; + i = startSearch; + while (j < maxTweens) + { + if (i >= maxTweens - 1) + { + i = 0; + } + if (!tweens[i].toggle) + { + if (i + 1 > tweenMaxSearch) + { + tweenMaxSearch = i + 1; + } + startSearch = i + 1; + break; + } + j++; + if (j >= maxTweens) + { + logError("LeanTween - You have run out of available spaces for tweening. To avoid this error increase the number of spaces to available for tweening when you initialize the LeanTween class ex: LeanTween.init( " + maxTweens * 2 + " );"); + return -1; + } + i++; + } + tween = tweens[i]; + tween.toggle = true; + tween.reset(); + tween.trans = gameObject.transform; + tween.to = to; + tween.time = time; + tween.type = tweenAction; + tween.optional = optional; + tween.setId((uint)i); + if (optional != null) + { + object obj = optional["ease"]; + int num = 0; + if (obj != null) + { + tween.tweenType = LeanTweenType.linear; + if (obj.GetType() == typeof(LeanTweenType)) + { + tween.tweenType = (LeanTweenType)(int)obj; + } + else if (obj.GetType() == typeof(AnimationCurve)) + { + tween.animationCurve = (optional["ease"] as AnimationCurve); + } + else + { + string text = optional["ease"].ToString(); + if (text.Equals("easeOutQuad")) + { + tween.tweenType = LeanTweenType.easeOutQuad; + } + else if (text.Equals("easeInQuad")) + { + tween.tweenType = LeanTweenType.easeInQuad; + } + else if (text.Equals("easeInOutQuad")) + { + tween.tweenType = LeanTweenType.easeInOutQuad; + } + } + num++; + } + if (optional["rect"] != null) + { + tween.ltRect = (LTRect)optional["rect"]; + num++; + } + if (optional["path"] != null) + { + tween.path = (LTBezierPath)optional["path"]; + num++; + } + if (optional["delay"] != null) + { + tween.delay = (float)optional["delay"]; + num++; + } + if (optional["useEstimatedTime"] != null) + { + tween.useEstimatedTime = (bool)optional["useEstimatedTime"]; + num++; + } + if (optional["useFrames"] != null) + { + tween.useFrames = (bool)optional["useFrames"]; + num++; + } + if (optional["loopType"] != null) + { + tween.loopType = (LeanTweenType)(int)optional["loopType"]; + num++; + } + if (optional["repeat"] != null) + { + tween.loopCount = (int)optional["repeat"]; + if (tween.loopType == LeanTweenType.once) + { + tween.loopType = LeanTweenType.clamp; + } + num++; + } + if (optional["point"] != null) + { + tween.point = (Vector3)optional["point"]; + num++; + } + if (optional["axis"] != null) + { + tween.axis = (Vector3)optional["axis"]; + num++; + } + if (optional.Count <= num) + { + tween.optional = null; + } + } + else + { + tween.optional = null; + } + return tweens[i].uniqueId; + } + + public static int value(string callOnUpdate, float from, float to, float time, Hashtable optional) + { + return value(tweenEmpty, callOnUpdate, from, to, time, optional); + } + + public static int value(GameObject gameObject, string callOnUpdate, float from, float to, float time) + { + return value(gameObject, callOnUpdate, from, to, time, new Hashtable()); + } + + public static int value(GameObject gameObject, string callOnUpdate, float from, float to, float time, object[] optional) + { + return value(gameObject, callOnUpdate, from, to, time, h(optional)); + } + + public static int value(GameObject gameObject, Action callOnUpdate, float from, float to, float time, object[] optional) + { + return value(gameObject, callOnUpdate, from, to, time, h(optional)); + } + + public static int value(GameObject gameObject, Action callOnUpdate, float from, float to, float time, object[] optional) + { + return value(gameObject, callOnUpdate, from, to, time, h(optional)); + } + + public static int value(GameObject gameObject, string callOnUpdate, float from, float to, float time, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["onUpdate"] = callOnUpdate; + int num = idFromUnique(pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.CALLBACK, optional)); + tweens[num].from = new Vector3(from, 0f, 0f); + return num; + } + + public static int value(GameObject gameObject, Action callOnUpdate, float from, float to, float time, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["onUpdate"] = callOnUpdate; + int num = idFromUnique(pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.CALLBACK, optional)); + tweens[num].from = new Vector3(from, 0f, 0f); + return num; + } + + public static int value(GameObject gameObject, Action callOnUpdate, float from, float to, float time, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["onUpdate"] = callOnUpdate; + int num = idFromUnique(pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.CALLBACK, optional)); + tweens[num].from = new Vector3(from, 0f, 0f); + return num; + } + + public static int value(GameObject gameObject, string callOnUpdate, Vector3 from, Vector3 to, float time, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["onUpdate"] = callOnUpdate; + int num = idFromUnique(pushNewTween(gameObject, to, time, TweenAction.VALUE3, optional)); + tweens[num].from = from; + return num; + } + + public static int value(GameObject gameObject, string callOnUpdate, Vector3 from, Vector3 to, float time, object[] optional) + { + return value(gameObject, callOnUpdate, from, to, time, h(optional)); + } + + public static int value(GameObject gameObject, Action callOnUpdate, Vector3 from, Vector3 to, float time, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["onUpdate"] = callOnUpdate; + int num = idFromUnique(pushNewTween(gameObject, to, time, TweenAction.VALUE3, optional)); + tweens[num].from = from; + return num; + } + + public static int value(GameObject gameObject, Action callOnUpdate, Vector3 from, Vector3 to, float time, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["onUpdate"] = callOnUpdate; + int num = idFromUnique(pushNewTween(gameObject, to, time, TweenAction.VALUE3, optional)); + tweens[num].from = from; + return num; + } + + public static int value(GameObject gameObject, Action callOnUpdate, Vector3 from, Vector3 to, float time, object[] optional) + { + return value(gameObject, callOnUpdate, from, to, time, h(optional)); + } + + public static int value(GameObject gameObject, Action callOnUpdate, Vector3 from, Vector3 to, float time, object[] optional) + { + return value(gameObject, callOnUpdate, from, to, time, h(optional)); + } + + public static int rotate(GameObject gameObject, Vector3 to, float time, Hashtable optional) + { + return pushNewTween(gameObject, to, time, TweenAction.ROTATE, optional); + } + + public static int rotate(GameObject gameObject, Vector3 to, float time, object[] optional) + { + return rotate(gameObject, to, time, h(optional)); + } + + public static int rotate(LTRect ltRect, float to, float time, Hashtable optional) + { + init(); + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["rect"] = ltRect; + return pushNewTween(tweenEmpty, new Vector3(to, 0f, 0f), time, TweenAction.GUI_ROTATE, optional); + } + + public static int rotate(LTRect ltRect, float to, float time, object[] optional) + { + return rotate(ltRect, to, time, h(optional)); + } + + public static int rotateX(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ROTATE_X, optional); + } + + public static int rotateX(GameObject gameObject, float to, float time, object[] optional) + { + return rotateX(gameObject, to, time, h(optional)); + } + + public static int rotateY(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ROTATE_Y, optional); + } + + public static int rotateY(GameObject gameObject, float to, float time, object[] optional) + { + return rotateY(gameObject, to, time, h(optional)); + } + + public static int rotateZ(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ROTATE_Z, optional); + } + + public static int rotateZ(GameObject gameObject, float to, float time, object[] optional) + { + return rotateZ(gameObject, to, time, h(optional)); + } + + public static int rotateLocal(GameObject gameObject, Vector3 to, float time, Hashtable optional) + { + return pushNewTween(gameObject, to, time, TweenAction.ROTATE_LOCAL, optional); + } + + public static int rotateLocal(GameObject gameObject, Vector3 to, float time, object[] optional) + { + return rotateLocal(gameObject, to, time, h(optional)); + } + + public static int rotateAround(GameObject gameObject, Vector3 axis, float add, float time, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["axis"] = axis; + if (optional["point"] == null) + { + optional["point"] = Vector3.zero; + } + return pushNewTween(gameObject, new Vector3(add, 0f, 0f), time, TweenAction.ROTATE_AROUND, optional); + } + + public static int rotateAround(GameObject gameObject, Vector3 axis, float add, float time, object[] optional) + { + return rotateAround(gameObject, axis, add, time, h(optional)); + } + + public static int moveX(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_X, optional); + } + + public static int moveX(GameObject gameObject, float to, float time, object[] optional) + { + return moveX(gameObject, to, time, h(optional)); + } + + public static int moveY(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_Y, optional); + } + + public static int moveY(GameObject gameObject, float to, float time, object[] optional) + { + return moveY(gameObject, to, time, h(optional)); + } + + public static int moveZ(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_Z, optional); + } + + public static int moveZ(GameObject gameObject, float to, float time, object[] optional) + { + return moveZ(gameObject, to, time, h(optional)); + } + + public static int move(GameObject gameObject, Vector3 to, float time, Hashtable optional) + { + return pushNewTween(gameObject, to, time, TweenAction.MOVE, optional); + } + + public static int move(GameObject gameObject, Vector3 to, float time, object[] optional) + { + return move(gameObject, to, time, h(optional)); + } + + public static int move(GameObject gameObject, Vector3[] to, float time, Hashtable optional) + { + if (to.Length < 4) + { + string message = "LeanTween - When passing values for a vector path, you must pass four or more values!"; + if (throwErrors) + { + Debug.LogError(message); + } + else + { + Debug.Log(message); + } + return -1; + } + if (to.Length % 4 != 0) + { + string message2 = "LeanTween - When passing values for a vector path, they must be in sets of four: controlPoint1, controlPoint2, endPoint2, controlPoint2, controlPoint2..."; + if (throwErrors) + { + Debug.LogError(message2); + } + else + { + Debug.Log(message2); + } + return -1; + } + init(); + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + LTBezierPath lTBezierPath = new LTBezierPath(to); + if (optional["orientToPath"] != null) + { + lTBezierPath.orientToPath = true; + } + optional["path"] = lTBezierPath; + return pushNewTween(gameObject, new Vector3(1f, 0f, 0f), time, TweenAction.MOVE_CURVED, optional); + } + + public static int move(GameObject gameObject, Vector3[] to, float time, object[] optional) + { + return move(gameObject, to, time, h(optional)); + } + + public static int move(LTRect ltRect, Vector2 to, float time, Hashtable optional) + { + init(); + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["rect"] = ltRect; + return pushNewTween(tweenEmpty, to, time, TweenAction.GUI_MOVE, optional); + } + + public static int move(LTRect ltRect, Vector3 to, float time, object[] optional) + { + return move(ltRect, to, time, h(optional)); + } + + public static int moveLocal(GameObject gameObject, Vector3 to, float time, Hashtable optional) + { + return pushNewTween(gameObject, to, time, TweenAction.MOVE_LOCAL, optional); + } + + public static int moveLocal(GameObject gameObject, Vector3 to, float time, object[] optional) + { + return moveLocal(gameObject, to, time, h(optional)); + } + + public static int moveLocal(GameObject gameObject, Vector3[] to, float time, Hashtable optional) + { + if (to.Length < 4) + { + string message = "LeanTween - When passing values for a vector path, you must pass four or more values!"; + if (throwErrors) + { + Debug.LogError(message); + } + else + { + Debug.Log(message); + } + return -1; + } + if (to.Length % 4 != 0) + { + string message2 = "LeanTween - When passing values for a vector path, they must be in sets of four: controlPoint1, controlPoint2, endPoint2, controlPoint2, controlPoint2..."; + if (throwErrors) + { + Debug.LogError(message2); + } + else + { + Debug.Log(message2); + } + return -1; + } + init(); + if (optional == null) + { + optional = new Hashtable(); + } + LTBezierPath lTBezierPath = new LTBezierPath(to); + if (optional["orientToPath"] != null) + { + lTBezierPath.orientToPath = true; + } + optional["path"] = lTBezierPath; + return pushNewTween(gameObject, new Vector3(1f, 0f, 0f), time, TweenAction.MOVE_CURVED_LOCAL, optional); + } + + public static int moveLocal(GameObject gameObject, Vector3[] to, float time, object[] optional) + { + return moveLocal(gameObject, to, time, h(optional)); + } + + public static int moveLocalX(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_LOCAL_X, optional); + } + + public static int moveLocalX(GameObject gameObject, float to, float time, object[] optional) + { + return moveLocalX(gameObject, to, time, h(optional)); + } + + public static int moveLocalY(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_LOCAL_Y, optional); + } + + public static int moveLocalY(GameObject gameObject, float to, float time, object[] optional) + { + return moveLocalY(gameObject, to, time, h(optional)); + } + + public static int moveLocalZ(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.MOVE_LOCAL_Z, optional); + } + + public static int moveLocalZ(GameObject gameObject, float to, float time, object[] optional) + { + return moveLocalZ(gameObject, to, time, h(optional)); + } + + public static int scale(GameObject gameObject, Vector3 to, float time, Hashtable optional) + { + return pushNewTween(gameObject, to, time, TweenAction.SCALE, optional); + } + + public static int scale(GameObject gameObject, Vector3 to, float time, object[] optional) + { + return scale(gameObject, to, time, h(optional)); + } + + public static int scale(LTRect ltRect, Vector2 to, float time, Hashtable optional) + { + init(); + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["rect"] = ltRect; + return pushNewTween(tweenEmpty, to, time, TweenAction.GUI_SCALE, optional); + } + + public static int scale(LTRect ltRect, Vector2 to, float time, object[] optional) + { + return scale(ltRect, to, time, h(optional)); + } + + public static int alpha(LTRect ltRect, float to, float time, Hashtable optional) + { + init(); + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + ltRect.alphaEnabled = true; + optional["rect"] = ltRect; + return pushNewTween(tweenEmpty, new Vector3(to, 0f, 0f), time, TweenAction.GUI_ALPHA, optional); + } + + public static int alpha(LTRect ltRect, float to, float time, object[] optional) + { + return alpha(ltRect, to, time, h(optional)); + } + + public static int scaleX(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.SCALE_X, optional); + } + + public static int scaleX(GameObject gameObject, float to, float time, object[] optional) + { + return scaleX(gameObject, to, time, h(optional)); + } + + public static int scaleY(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.SCALE_Y, optional); + } + + public static int scaleY(GameObject gameObject, float to, float time, object[] optional) + { + return scaleY(gameObject, to, time, h(optional)); + } + + public static int scaleZ(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.SCALE_Z, optional); + } + + public static int scaleZ(GameObject gameObject, float to, float time, object[] optional) + { + return scaleZ(gameObject, to, time, h(optional)); + } + + public static int delayedCall(float delayTime, string callback, Hashtable optional) + { + init(); + return delayedCall(tweenEmpty, delayTime, callback, optional); + } + + public static int delayedCall(float delayTime, Action callback, object[] optional) + { + init(); + return delayedCall(tweenEmpty, delayTime, callback, h(optional)); + } + + public static int delayedCall(GameObject gameObject, float delayTime, string callback, object[] optional) + { + return delayedCall(gameObject, delayTime, callback, h(optional)); + } + + public static int delayedCall(GameObject gameObject, float delayTime, Action callback, object[] optional) + { + return delayedCall(gameObject, delayTime, callback, h(optional)); + } + + public static int delayedCall(GameObject gameObject, float delayTime, string callback, Hashtable optional) + { + if (optional == null || optional.Count == 0) + { + optional = new Hashtable(); + } + optional["onComplete"] = callback; + return pushNewTween(gameObject, Vector3.zero, delayTime, TweenAction.CALLBACK, optional); + } + + public static int delayedCall(GameObject gameObject, float delayTime, Action callback, Hashtable optional) + { + if (optional == null) + { + optional = new Hashtable(); + } + optional["onComplete"] = callback; + return pushNewTween(gameObject, Vector3.zero, delayTime, TweenAction.CALLBACK, optional); + } + + public static int delayedCall(GameObject gameObject, float delayTime, Action callback, Hashtable optional) + { + if (optional == null) + { + optional = new Hashtable(); + } + optional["onComplete"] = callback; + return pushNewTween(gameObject, Vector3.zero, delayTime, TweenAction.CALLBACK, optional); + } + + public static int alpha(GameObject gameObject, float to, float time, Hashtable optional) + { + return pushNewTween(gameObject, new Vector3(to, 0f, 0f), time, TweenAction.ALPHA, optional); + } + + public static int alpha(GameObject gameObject, float to, float time, object[] optional) + { + return alpha(gameObject, to, time, h(optional)); + } + + private static float tweenOnCurve(LTDescr tweenDescr, float ratioPassed) + { + return tweenDescr.from.x + tweenDescr.diff.x * tweenDescr.animationCurve.Evaluate(ratioPassed); + } + + private static Vector3 tweenOnCurveVector(LTDescr tweenDescr, float ratioPassed) + { + return new Vector3(tweenDescr.from.x + tweenDescr.diff.x * tweenDescr.animationCurve.Evaluate(ratioPassed), tweenDescr.from.y + tweenDescr.diff.y * tweenDescr.animationCurve.Evaluate(ratioPassed), tweenDescr.from.z + tweenDescr.diff.z * tweenDescr.animationCurve.Evaluate(ratioPassed)); + } + + private static float easeOutQuadOpt(float start, float diff, float ratioPassed) + { + return (0f - diff) * ratioPassed * (ratioPassed - 2f) + start; + } + + private static float easeInQuadOpt(float start, float diff, float ratioPassed) + { + return diff * ratioPassed * ratioPassed + start; + } + + private static float easeInOutQuadOpt(float start, float diff, float ratioPassed) + { + ratioPassed /= 0.5f; + if (ratioPassed < 1f) + { + return diff / 2f * ratioPassed * ratioPassed + start; + } + ratioPassed -= 1f; + return (0f - diff) / 2f * (ratioPassed * (ratioPassed - 2f) - 1f) + start; + } + + private static float linear(float start, float end, float val) + { + return Mathf.Lerp(start, end, val); + } + + private static float clerp(float start, float end, float val) + { + float num = 0f; + float num2 = 360f; + float num3 = Mathf.Abs((num2 - num) / 2f); + float num4 = 0f; + float num5 = 0f; + if (end - start < 0f - num3) + { + num5 = (num2 - start + end) * val; + return start + num5; + } + if (end - start > num3) + { + num5 = (0f - (num2 - end + start)) * val; + return start + num5; + } + return start + (end - start) * val; + } + + private static float spring(float start, float end, float val) + { + val = Mathf.Clamp01(val); + val = (Mathf.Sin(val * 3.14159274f * (0.2f + 2.5f * val * val * val)) * Mathf.Pow(1f - val, 2.2f) + val) * (1f + 1.2f * (1f - val)); + return start + (end - start) * val; + } + + private static float easeInQuad(float start, float end, float val) + { + end -= start; + return end * val * val + start; + } + + private static float easeOutQuad(float start, float end, float val) + { + end -= start; + return (0f - end) * val * (val - 2f) + start; + } + + private static float easeInOutQuad(float start, float end, float val) + { + val /= 0.5f; + end -= start; + if (val < 1f) + { + return end / 2f * val * val + start; + } + val -= 1f; + return (0f - end) / 2f * (val * (val - 2f) - 1f) + start; + } + + private static float easeInCubic(float start, float end, float val) + { + end -= start; + return end * val * val * val + start; + } + + private static float easeOutCubic(float start, float end, float val) + { + val -= 1f; + end -= start; + return end * (val * val * val + 1f) + start; + } + + private static float easeInOutCubic(float start, float end, float val) + { + val /= 0.5f; + end -= start; + if (val < 1f) + { + return end / 2f * val * val * val + start; + } + val -= 2f; + return end / 2f * (val * val * val + 2f) + start; + } + + private static float easeInQuart(float start, float end, float val) + { + end -= start; + return end * val * val * val * val + start; + } + + private static float easeOutQuart(float start, float end, float val) + { + val -= 1f; + end -= start; + return (0f - end) * (val * val * val * val - 1f) + start; + } + + private static float easeInOutQuart(float start, float end, float val) + { + val /= 0.5f; + end -= start; + if (val < 1f) + { + return end / 2f * val * val * val * val + start; + } + val -= 2f; + return (0f - end) / 2f * (val * val * val * val - 2f) + start; + } + + private static float easeInQuint(float start, float end, float val) + { + end -= start; + return end * val * val * val * val * val + start; + } + + private static float easeOutQuint(float start, float end, float val) + { + val -= 1f; + end -= start; + return end * (val * val * val * val * val + 1f) + start; + } + + private static float easeInOutQuint(float start, float end, float val) + { + val /= 0.5f; + end -= start; + if (val < 1f) + { + return end / 2f * val * val * val * val * val + start; + } + val -= 2f; + return end / 2f * (val * val * val * val * val + 2f) + start; + } + + private static float easeInSine(float start, float end, float val) + { + end -= start; + return (0f - end) * Mathf.Cos(val / 1f * 1.57079637f) + end + start; + } + + private static float easeOutSine(float start, float end, float val) + { + end -= start; + return end * Mathf.Sin(val / 1f * 1.57079637f) + start; + } + + private static float easeInOutSine(float start, float end, float val) + { + end -= start; + return (0f - end) / 2f * (Mathf.Cos(3.14159274f * val / 1f) - 1f) + start; + } + + private static float easeInExpo(float start, float end, float val) + { + end -= start; + return end * Mathf.Pow(2f, 10f * (val / 1f - 1f)) + start; + } + + private static float easeOutExpo(float start, float end, float val) + { + end -= start; + return end * (0f - Mathf.Pow(2f, -10f * val / 1f) + 1f) + start; + } + + private static float easeInOutExpo(float start, float end, float val) + { + val /= 0.5f; + end -= start; + if (val < 1f) + { + return end / 2f * Mathf.Pow(2f, 10f * (val - 1f)) + start; + } + val -= 1f; + return end / 2f * (0f - Mathf.Pow(2f, -10f * val) + 2f) + start; + } + + private static float easeInCirc(float start, float end, float val) + { + end -= start; + return (0f - end) * (Mathf.Sqrt(1f - val * val) - 1f) + start; + } + + private static float easeOutCirc(float start, float end, float val) + { + val -= 1f; + end -= start; + return end * Mathf.Sqrt(1f - val * val) + start; + } + + private static float easeInOutCirc(float start, float end, float val) + { + val /= 0.5f; + end -= start; + if (val < 1f) + { + return (0f - end) / 2f * (Mathf.Sqrt(1f - val * val) - 1f) + start; + } + val -= 2f; + return end / 2f * (Mathf.Sqrt(1f - val * val) + 1f) + start; + } + + private static float easeInBounce(float start, float end, float val) + { + end -= start; + float num = 1f; + return end - easeOutBounce(0f, end, num - val) + start; + } + + private static float easeOutBounce(float start, float end, float val) + { + val /= 1f; + end -= start; + if (val < 0.363636374f) + { + return end * (7.5625f * val * val) + start; + } + if (val < 0.727272749f) + { + val -= 0.545454562f; + return end * (7.5625f * val * val + 0.75f) + start; + } + if ((double)val < 0.90909090909090906) + { + val -= 0.8181818f; + return end * (7.5625f * val * val + 0.9375f) + start; + } + val -= 0.954545438f; + return end * (7.5625f * val * val + 0.984375f) + start; + } + + private static float easeInOutBounce(float start, float end, float val) + { + end -= start; + float num = 1f; + if (val < num / 2f) + { + return easeInBounce(0f, end, val * 2f) * 0.5f + start; + } + return easeOutBounce(0f, end, val * 2f - num) * 0.5f + end * 0.5f + start; + } + + private static float easeInBack(float start, float end, float val) + { + end -= start; + val /= 1f; + float num = 1.70158f; + return end * val * val * ((num + 1f) * val - num) + start; + } + + private static float easeOutBack(float start, float end, float val) + { + float num = 1.70158f; + end -= start; + val = val / 1f - 1f; + return end * (val * val * ((num + 1f) * val + num) + 1f) + start; + } + + private static float easeInOutBack(float start, float end, float val) + { + float num = 1.70158f; + end -= start; + val /= 0.5f; + if (val < 1f) + { + num *= 1.525f; + return end / 2f * (val * val * ((num + 1f) * val - num)) + start; + } + val -= 2f; + num *= 1.525f; + return end / 2f * (val * val * ((num + 1f) * val + num) + 2f) + start; + } + + private static float easeInElastic(float start, float end, float val) + { + end -= start; + float num = 1f; + float num2 = num * 0.3f; + float num3 = 0f; + float num4 = 0f; + if (val == 0f) + { + return start; + } + val /= num; + if (val == 1f) + { + return start + end; + } + if (num4 == 0f || num4 < Mathf.Abs(end)) + { + num4 = end; + num3 = num2 / 4f; + } + else + { + num3 = num2 / 6.28318548f * Mathf.Asin(end / num4); + } + val -= 1f; + return 0f - num4 * Mathf.Pow(2f, 10f * val) * Mathf.Sin((val * num - num3) * 6.28318548f / num2) + start; + } + + private static float easeOutElastic(float start, float end, float val) + { + end -= start; + float num = 1f; + float num2 = num * 0.3f; + float num3 = 0f; + float num4 = 0f; + if (val == 0f) + { + return start; + } + val /= num; + if (val == 1f) + { + return start + end; + } + if (num4 == 0f || num4 < Mathf.Abs(end)) + { + num4 = end; + num3 = num2 / 4f; + } + else + { + num3 = num2 / 6.28318548f * Mathf.Asin(end / num4); + } + return num4 * Mathf.Pow(2f, -10f * val) * Mathf.Sin((val * num - num3) * 6.28318548f / num2) + end + start; + } + + private static float easeInOutElastic(float start, float end, float val) + { + end -= start; + float num = 1f; + float num2 = num * 0.3f; + float num3 = 0f; + float num4 = 0f; + if (val == 0f) + { + return start; + } + val /= num / 2f; + if (val == 2f) + { + return start + end; + } + if (num4 == 0f || num4 < Mathf.Abs(end)) + { + num4 = end; + num3 = num2 / 4f; + } + else + { + num3 = num2 / 6.28318548f * Mathf.Asin(end / num4); + } + if (val < 1f) + { + val -= 1f; + return -0.5f * (num4 * Mathf.Pow(2f, 10f * val) * Mathf.Sin((val * num - num3) * 6.28318548f / num2)) + start; + } + val -= 1f; + return num4 * Mathf.Pow(2f, -10f * val) * Mathf.Sin((val * num - num3) * 6.28318548f / num2) * 0.5f + end + start; + } + + public static void addListener(int eventId, Action callback) + { + addListener(tweenEmpty, eventId, callback); + } + + public static void addListener(GameObject caller, int eventId, Action callback) + { + if (eventListeners == null) + { + eventListeners = new Action[EVENTS_MAX * LISTENERS_MAX]; + goListeners = new GameObject[EVENTS_MAX * LISTENERS_MAX]; + } + for (i = 0; i < LISTENERS_MAX; i++) + { + int num = eventId * LISTENERS_MAX + i; + if (goListeners[num] == null || eventListeners[num] == null) + { + eventListeners[num] = callback; + goListeners[num] = caller; + if (i >= eventsMaxSearch) + { + eventsMaxSearch = i + 1; + } + return; + } + if (goListeners[num] == caller && object.ReferenceEquals(eventListeners[num], callback)) + { + return; + } + } + Debug.LogError("You ran out of areas to add listeners, consider increasing LISTENERS_MAX, ex: LeanTween.LISTENERS_MAX = " + LISTENERS_MAX * 2); + } + + public static bool removeListener(int eventId, Action callback) + { + return removeListener(tweenEmpty, eventId, callback); + } + + public static bool removeListener(GameObject caller, int eventId, Action callback) + { + for (i = 0; i < eventsMaxSearch; i++) + { + int num = eventId * LISTENERS_MAX + i; + if (goListeners[num] == caller && object.ReferenceEquals(eventListeners[num], callback)) + { + eventListeners[num] = null; + goListeners[num] = null; + return true; + } + } + return false; + } + + public static void dispatchEvent(int eventId) + { + dispatchEvent(eventId, null); + } + + public static void dispatchEvent(int eventId, object data) + { + for (int i = 0; i < eventsMaxSearch; i++) + { + int num = eventId * LISTENERS_MAX + i; + if (eventListeners[num] != null) + { + if ((bool)goListeners[num]) + { + eventListeners[num](new LTEvent(eventId, data)); + } + else + { + eventListeners[num] = null; + } + } + } + } +} diff --git a/LeanTweenType.cs b/LeanTweenType.cs new file mode 100644 index 00000000..b52b37d5 --- /dev/null +++ b/LeanTweenType.cs @@ -0,0 +1,42 @@ +public enum LeanTweenType +{ + notUsed, + linear, + easeOutQuad, + easeInQuad, + easeInOutQuad, + easeInCubic, + easeOutCubic, + easeInOutCubic, + easeInQuart, + easeOutQuart, + easeInOutQuart, + easeInQuint, + easeOutQuint, + easeInOutQuint, + easeInSine, + easeOutSine, + easeInOutSine, + easeInExpo, + easeOutExpo, + easeInOutExpo, + easeInCirc, + easeOutCirc, + easeInOutCirc, + easeInBounce, + easeOutBounce, + easeInOutBounce, + easeInBack, + easeOutBack, + easeInOutBack, + easeInElastic, + easeOutElastic, + easeInOutElastic, + easeSpring, + easeShake, + punch, + once, + clamp, + pingPong, + animationCurve +} diff --git a/Linear.cs b/Linear.cs new file mode 100644 index 00000000..c92e93e5 --- /dev/null +++ b/Linear.cs @@ -0,0 +1,22 @@ +internal class Linear : Ease +{ + public static double EaseNone(double t, double b, double c, double d) + { + return c * t / d + b; + } + + public static double EaseIn(double t, double b, double c, double d) + { + return c * t / d + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return c * t / d + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + return c * t / d + b; + } +} diff --git a/Localization.cs b/Localization.cs new file mode 100644 index 00000000..6317cbc1 --- /dev/null +++ b/Localization.cs @@ -0,0 +1,309 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public static class Localization +{ + public delegate byte[] LoadFunction(string path); + + public static LoadFunction loadFunction; + + public static bool localizationHasBeenSet = false; + + private static string[] mLanguages = null; + + private static Dictionary mOldDictionary = new Dictionary(); + + private static Dictionary mDictionary = new Dictionary(); + + private static int mLanguageIndex = -1; + + private static string mLanguage; + + public static Dictionary dictionary + { + get + { + if (!localizationHasBeenSet) + { + language = PlayerPrefs.GetString("Language", "English"); + } + return mDictionary; + } + set + { + localizationHasBeenSet = (value != null); + mDictionary = value; + } + } + + public static string[] knownLanguages + { + get + { + if (!localizationHasBeenSet) + { + LoadDictionary(PlayerPrefs.GetString("Language", "English")); + } + return mLanguages; + } + } + + public static string language + { + get + { + if (string.IsNullOrEmpty(mLanguage)) + { + string[] knownLanguages = Localization.knownLanguages; + mLanguage = PlayerPrefs.GetString("Language", (knownLanguages == null) ? "English" : knownLanguages[0]); + LoadAndSelect(mLanguage); + } + return mLanguage; + } + set + { + if (mLanguage != value) + { + mLanguage = value; + LoadAndSelect(value); + } + } + } + + [Obsolete("Localization is now always active. You no longer need to check this property.")] + public static bool isActive + { + get + { + return true; + } + } + + private static bool LoadDictionary(string value) + { + byte[] array = null; + if (!localizationHasBeenSet) + { + if (loadFunction == null) + { + TextAsset textAsset = Resources.Load("Localization"); + if (textAsset != null) + { + array = textAsset.bytes; + } + } + else + { + array = loadFunction("Localization"); + } + localizationHasBeenSet = true; + } + if (LoadCSV(array)) + { + return true; + } + if (string.IsNullOrEmpty(value)) + { + return false; + } + if (loadFunction == null) + { + TextAsset textAsset2 = Resources.Load(value); + if (textAsset2 != null) + { + array = textAsset2.bytes; + } + } + else + { + array = loadFunction(value); + } + if (array != null) + { + Set(value, array); + return true; + } + return false; + } + + private static bool LoadAndSelect(string value) + { + if (!string.IsNullOrEmpty(value)) + { + if (mDictionary.Count == 0 && !LoadDictionary(value)) + { + return false; + } + if (SelectLanguage(value)) + { + return true; + } + } + if (mOldDictionary.Count > 0) + { + return true; + } + mOldDictionary.Clear(); + mDictionary.Clear(); + if (string.IsNullOrEmpty(value)) + { + PlayerPrefs.DeleteKey("Language"); + } + return false; + } + + public static void Load(TextAsset asset) + { + ByteReader byteReader = new ByteReader(asset); + Set(asset.name, byteReader.ReadDictionary()); + } + + public static void Set(string languageName, byte[] bytes) + { + ByteReader byteReader = new ByteReader(bytes); + Set(languageName, byteReader.ReadDictionary()); + } + + public static bool LoadCSV(TextAsset asset) + { + return LoadCSV(asset.bytes, asset); + } + + public static bool LoadCSV(byte[] bytes) + { + return LoadCSV(bytes, null); + } + + private static bool LoadCSV(byte[] bytes, TextAsset asset) + { + if (bytes == null) + { + return false; + } + ByteReader byteReader = new ByteReader(bytes); + BetterList betterList = byteReader.ReadCSV(); + if (betterList.size < 2) + { + return false; + } + betterList[0] = "KEY"; + if (!string.Equals(betterList[0], "KEY")) + { + Debug.LogError("Invalid localization CSV file. The first value is expected to be 'KEY', followed by language columns.\nInstead found '" + betterList[0] + "'", asset); + return false; + } + mLanguages = new string[betterList.size - 1]; + for (int i = 0; i < mLanguages.Length; i++) + { + mLanguages[i] = betterList[i + 1]; + } + mDictionary.Clear(); + while (betterList != null) + { + AddCSV(betterList); + betterList = byteReader.ReadCSV(); + } + return true; + } + + private static bool SelectLanguage(string language) + { + mLanguageIndex = -1; + if (mDictionary.Count == 0) + { + return false; + } + if (mDictionary.TryGetValue("KEY", out string[] value)) + { + for (int i = 0; i < value.Length; i++) + { + if (value[i] == language) + { + mOldDictionary.Clear(); + mLanguageIndex = i; + mLanguage = language; + PlayerPrefs.SetString("Language", mLanguage); + UIRoot.Broadcast("OnLocalize"); + return true; + } + } + } + return false; + } + + private static void AddCSV(BetterList values) + { + if (values.size >= 2) + { + string[] array = new string[values.size - 1]; + for (int i = 1; i < values.size; i++) + { + array[i - 1] = values[i]; + } + try + { + mDictionary.Add(values[0], array); + } + catch (Exception ex) + { + Debug.LogError("Unable to add '" + values[0] + "' to the Localization dictionary.\n" + ex.Message); + } + } + } + + public static void Set(string languageName, Dictionary dictionary) + { + mLanguage = languageName; + PlayerPrefs.SetString("Language", mLanguage); + mOldDictionary = dictionary; + localizationHasBeenSet = false; + mLanguageIndex = -1; + mLanguages = new string[1] + { + languageName + }; + UIRoot.Broadcast("OnLocalize"); + } + + public static string Get(string key) + { + if (!localizationHasBeenSet) + { + language = PlayerPrefs.GetString("Language", "English"); + } + string value2; + if (mLanguageIndex != -1 && mDictionary.TryGetValue(key, out string[] value)) + { + if (mLanguageIndex < value.Length) + { + return value[mLanguageIndex]; + } + } + else if (mOldDictionary.TryGetValue(key, out value2)) + { + return value2; + } + return key; + } + + public static string Format(string key, params object[] parameters) + { + return string.Format(Get(key), parameters); + } + + [Obsolete("Use Localization.Get instead")] + public static string Localize(string key) + { + return Get(key); + } + + public static bool Exists(string key) + { + if (!localizationHasBeenSet) + { + language = PlayerPrefs.GetString("Language", "English"); + } + return mDictionary.ContainsKey(key) || mOldDictionary.ContainsKey(key); + } +} diff --git a/MenuUIController.cs b/MenuUIController.cs new file mode 100644 index 00000000..58211f14 --- /dev/null +++ b/MenuUIController.cs @@ -0,0 +1,64 @@ +using Assets.Scripts.Core; +using Assets.Scripts.Core.Audio; +using System.Collections; +using UnityEngine; + +public class MenuUIController : MonoBehaviour +{ + public delegate void MenuCloseDelegate(); + + public UIPanel Panel; + + private float time = 0.5f; + + private bool isClosing; + + private IEnumerator LeaveMenuAnimation(MenuCloseDelegate onClose, bool showMessage) + { + isClosing = true; + if (time > 0f) + { + yield return (object)new WaitForSeconds(time); + } + AudioController.Instance.PlaySystemSound("sysse05.ogg"); + yield return (object)null; + yield return (object)null; + LeanTween.value(this.Panel.gameObject, delegate(float f) + { + this.Panel.alpha = f; + }, 1f, 0f, 0.3f); + yield return (object)new WaitForSeconds(0.3f); + if (showMessage) + { + GameSystem.Instance.MainUIController.FadeIn(0.3f); + GameSystem.Instance.SceneController.RevealFace(0.3f); + GameSystem.Instance.ExecuteActions(); + yield return (object)new WaitForSeconds(0.3f); + } + onClose?.Invoke(); + Object.Destroy(base.gameObject); + } + + public void LeaveMenu(MenuCloseDelegate onClose, bool showMessage) + { + if (!isClosing && !(time > 0f)) + { + StartCoroutine(LeaveMenuAnimation(onClose, showMessage)); + } + } + + private void Start() + { + Panel.alpha = 0f; + LeanTween.value(Panel.gameObject, delegate(float f) + { + Panel.alpha = f; + }, 0f, 1f, 0.3f).setDelay(0.3f); + AudioController.Instance.PlaySystemSound("sysse05.ogg"); + } + + private void Update() + { + time -= Time.deltaTime; + } +} diff --git a/NGUIDebug.cs b/NGUIDebug.cs new file mode 100644 index 00000000..3524f093 --- /dev/null +++ b/NGUIDebug.cs @@ -0,0 +1,103 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Internal/Debug")] +public class NGUIDebug : MonoBehaviour +{ + private static bool mRayDebug = false; + + private static List mLines = new List(); + + private static NGUIDebug mInstance = null; + + public static bool debugRaycast + { + get + { + return mRayDebug; + } + set + { + if (Application.isPlaying) + { + mRayDebug = value; + if (value) + { + CreateInstance(); + } + } + } + } + + public static void CreateInstance() + { + if (mInstance == null) + { + GameObject gameObject = new GameObject("_NGUI Debug"); + mInstance = gameObject.AddComponent(); + Object.DontDestroyOnLoad(gameObject); + } + } + + private static void LogString(string text) + { + if (Application.isPlaying) + { + if (mLines.Count > 20) + { + mLines.RemoveAt(0); + } + mLines.Add(text); + CreateInstance(); + } + else + { + Debug.Log(text); + } + } + + public static void Log(params object[] objs) + { + string text = string.Empty; + for (int i = 0; i < objs.Length; i++) + { + text = ((i != 0) ? (text + ", " + objs[i].ToString()) : (text + objs[i].ToString())); + } + LogString(text); + } + + public static void Clear() + { + mLines.Clear(); + } + + public static void DrawBounds(Bounds b) + { + Vector3 center = b.center; + Vector3 vector = b.center - b.extents; + Vector3 vector2 = b.center + b.extents; + Debug.DrawLine(new Vector3(vector.x, vector.y, center.z), new Vector3(vector2.x, vector.y, center.z), Color.red); + Debug.DrawLine(new Vector3(vector.x, vector.y, center.z), new Vector3(vector.x, vector2.y, center.z), Color.red); + Debug.DrawLine(new Vector3(vector2.x, vector.y, center.z), new Vector3(vector2.x, vector2.y, center.z), Color.red); + Debug.DrawLine(new Vector3(vector.x, vector2.y, center.z), new Vector3(vector2.x, vector2.y, center.z), Color.red); + } + + private void OnGUI() + { + if (mLines.Count == 0) + { + if (mRayDebug && UICamera.hoveredObject != null && Application.isPlaying) + { + GUILayout.Label("Last Hit: " + NGUITools.GetHierarchy(UICamera.hoveredObject).Replace("\"", string.Empty)); + } + } + else + { + int i = 0; + for (int count = mLines.Count; i < count; i++) + { + GUILayout.Label(mLines[i]); + } + } + } +} diff --git a/NGUIMath.cs b/NGUIMath.cs new file mode 100644 index 00000000..ee21d6e2 --- /dev/null +++ b/NGUIMath.cs @@ -0,0 +1,1030 @@ +using System.Diagnostics; +using UnityEngine; + +public static class NGUIMath +{ + [DebuggerHidden] + [DebuggerStepThrough] + public static float Lerp(float from, float to, float factor) + { + return from * (1f - factor) + to * factor; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static int ClampIndex(int val, int max) + { + return (val >= 0) ? ((val >= max) ? (max - 1) : val) : 0; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static int RepeatIndex(int val, int max) + { + if (max < 1) + { + return 0; + } + while (val < 0) + { + val += max; + } + while (val >= max) + { + val -= max; + } + return val; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static float WrapAngle(float angle) + { + while (angle > 180f) + { + angle -= 360f; + } + while (angle < -180f) + { + angle += 360f; + } + return angle; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static float Wrap01(float val) + { + return val - (float)Mathf.FloorToInt(val); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static int HexToDecimal(char ch) + { + switch (ch) + { + case '0': + return 0; + case '1': + return 1; + case '2': + return 2; + case '3': + return 3; + case '4': + return 4; + case '5': + return 5; + case '6': + return 6; + case '7': + return 7; + case '8': + return 8; + case '9': + return 9; + case 'A': + case 'a': + return 10; + case 'B': + case 'b': + return 11; + case 'C': + case 'c': + return 12; + case 'D': + case 'd': + return 13; + case 'E': + case 'e': + return 14; + case 'F': + case 'f': + return 15; + default: + return 15; + } + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static char DecimalToHexChar(int num) + { + if (num > 15) + { + return 'F'; + } + if (num < 10) + { + return (char)(48 + num); + } + return (char)(65 + num - 10); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string DecimalToHex8(int num) + { + num &= 0xFF; + return num.ToString("X2"); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string DecimalToHex24(int num) + { + num &= 0xFFFFFF; + return num.ToString("X6"); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string DecimalToHex32(int num) + { + return num.ToString("X8"); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static int ColorToInt(Color c) + { + int num = 0; + num |= Mathf.RoundToInt(c.r * 255f) << 24; + num |= Mathf.RoundToInt(c.g * 255f) << 16; + num |= Mathf.RoundToInt(c.b * 255f) << 8; + return num | Mathf.RoundToInt(c.a * 255f); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static Color IntToColor(int val) + { + float num = 0.003921569f; + Color black = Color.black; + black.r = num * (float)((val >> 24) & 0xFF); + black.g = num * (float)((val >> 16) & 0xFF); + black.b = num * (float)((val >> 8) & 0xFF); + black.a = num * (float)(val & 0xFF); + return black; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string IntToBinary(int val, int bits) + { + string text = string.Empty; + int num = bits; + while (num > 0) + { + if (num == 8 || num == 16 || num == 24) + { + text += " "; + } + text += (((val & (1 << --num)) == 0) ? '0' : '1'); + } + return text; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static Color HexToColor(uint val) + { + return IntToColor((int)val); + } + + public static Rect ConvertToTexCoords(Rect rect, int width, int height) + { + Rect result = rect; + if ((float)width != 0f && (float)height != 0f) + { + result.xMin = rect.xMin / (float)width; + result.xMax = rect.xMax / (float)width; + result.yMin = 1f - rect.yMax / (float)height; + result.yMax = 1f - rect.yMin / (float)height; + } + return result; + } + + public static Rect ConvertToPixels(Rect rect, int width, int height, bool round) + { + Rect result = rect; + if (round) + { + result.xMin = (float)Mathf.RoundToInt(rect.xMin * (float)width); + result.xMax = (float)Mathf.RoundToInt(rect.xMax * (float)width); + result.yMin = (float)Mathf.RoundToInt((1f - rect.yMax) * (float)height); + result.yMax = (float)Mathf.RoundToInt((1f - rect.yMin) * (float)height); + } + else + { + result.xMin = rect.xMin * (float)width; + result.xMax = rect.xMax * (float)width; + result.yMin = (1f - rect.yMax) * (float)height; + result.yMax = (1f - rect.yMin) * (float)height; + } + return result; + } + + public static Rect MakePixelPerfect(Rect rect) + { + rect.xMin = (float)Mathf.RoundToInt(rect.xMin); + rect.yMin = (float)Mathf.RoundToInt(rect.yMin); + rect.xMax = (float)Mathf.RoundToInt(rect.xMax); + rect.yMax = (float)Mathf.RoundToInt(rect.yMax); + return rect; + } + + public static Rect MakePixelPerfect(Rect rect, int width, int height) + { + rect = ConvertToPixels(rect, width, height, round: true); + rect.xMin = (float)Mathf.RoundToInt(rect.xMin); + rect.yMin = (float)Mathf.RoundToInt(rect.yMin); + rect.xMax = (float)Mathf.RoundToInt(rect.xMax); + rect.yMax = (float)Mathf.RoundToInt(rect.yMax); + return ConvertToTexCoords(rect, width, height); + } + + public static Vector2 ConstrainRect(Vector2 minRect, Vector2 maxRect, Vector2 minArea, Vector2 maxArea) + { + Vector2 zero = Vector2.zero; + float num = maxRect.x - minRect.x; + float num2 = maxRect.y - minRect.y; + float num3 = maxArea.x - minArea.x; + float num4 = maxArea.y - minArea.y; + if (num > num3) + { + float num5 = num - num3; + minArea.x -= num5; + maxArea.x += num5; + } + if (num2 > num4) + { + float num6 = num2 - num4; + minArea.y -= num6; + maxArea.y += num6; + } + if (minRect.x < minArea.x) + { + zero.x += minArea.x - minRect.x; + } + if (maxRect.x > maxArea.x) + { + zero.x -= maxRect.x - maxArea.x; + } + if (minRect.y < minArea.y) + { + zero.y += minArea.y - minRect.y; + } + if (maxRect.y > maxArea.y) + { + zero.y -= maxRect.y - maxArea.y; + } + return zero; + } + + public static Bounds CalculateAbsoluteWidgetBounds(Transform trans) + { + if (trans != null) + { + UIWidget[] componentsInChildren = trans.GetComponentsInChildren(); + if (componentsInChildren.Length == 0) + { + return new Bounds(trans.position, Vector3.zero); + } + Vector3 center = new Vector3(3.40282347E+38f, 3.40282347E+38f, 3.40282347E+38f); + Vector3 point = new Vector3(-3.40282347E+38f, -3.40282347E+38f, -3.40282347E+38f); + int i = 0; + for (int num = componentsInChildren.Length; i < num; i++) + { + UIWidget uIWidget = componentsInChildren[i]; + if (uIWidget.enabled) + { + Vector3[] worldCorners = uIWidget.worldCorners; + for (int j = 0; j < 4; j++) + { + Vector3 vector = worldCorners[j]; + if (vector.x > point.x) + { + point.x = vector.x; + } + if (vector.y > point.y) + { + point.y = vector.y; + } + if (vector.z > point.z) + { + point.z = vector.z; + } + if (vector.x < center.x) + { + center.x = vector.x; + } + if (vector.y < center.y) + { + center.y = vector.y; + } + if (vector.z < center.z) + { + center.z = vector.z; + } + } + } + } + Bounds result = new Bounds(center, Vector3.zero); + result.Encapsulate(point); + return result; + } + return new Bounds(Vector3.zero, Vector3.zero); + } + + public static Bounds CalculateRelativeWidgetBounds(Transform trans) + { + return CalculateRelativeWidgetBounds(trans, trans, considerInactive: false); + } + + public static Bounds CalculateRelativeWidgetBounds(Transform trans, bool considerInactive) + { + return CalculateRelativeWidgetBounds(trans, trans, considerInactive); + } + + public static Bounds CalculateRelativeWidgetBounds(Transform relativeTo, Transform content) + { + return CalculateRelativeWidgetBounds(relativeTo, content, considerInactive: false); + } + + public static Bounds CalculateRelativeWidgetBounds(Transform relativeTo, Transform content, bool considerInactive) + { + if (content != null && relativeTo != null) + { + bool isSet = false; + Matrix4x4 toLocal = relativeTo.worldToLocalMatrix; + Vector3 vMin = new Vector3(3.40282347E+38f, 3.40282347E+38f, 3.40282347E+38f); + Vector3 vMax = new Vector3(-3.40282347E+38f, -3.40282347E+38f, -3.40282347E+38f); + CalculateRelativeWidgetBounds(content, considerInactive, /*isRoot:*/ true, ref toLocal, ref vMin, ref vMax, ref isSet); + if (isSet) + { + Bounds result = new Bounds(vMin, Vector3.zero); + result.Encapsulate(vMax); + return result; + } + } + return new Bounds(Vector3.zero, Vector3.zero); + } + + [DebuggerHidden] + [DebuggerStepThrough] + private static void CalculateRelativeWidgetBounds(Transform content, bool considerInactive, bool isRoot, ref Matrix4x4 toLocal, ref Vector3 vMin, ref Vector3 vMax, ref bool isSet) + { + if (!(content == null) && (considerInactive || NGUITools.GetActive(content.gameObject))) + { + UIPanel uIPanel = (!isRoot) ? content.GetComponent() : null; + if (!(uIPanel != null) || uIPanel.enabled) + { + if (uIPanel != null && uIPanel.clipping != 0) + { + Vector3[] worldCorners = uIPanel.worldCorners; + for (int i = 0; i < 4; i++) + { + Vector3 vector = toLocal.MultiplyPoint3x4(worldCorners[i]); + if (vector.x > vMax.x) + { + vMax.x = vector.x; + } + if (vector.y > vMax.y) + { + vMax.y = vector.y; + } + if (vector.z > vMax.z) + { + vMax.z = vector.z; + } + if (vector.x < vMin.x) + { + vMin.x = vector.x; + } + if (vector.y < vMin.y) + { + vMin.y = vector.y; + } + if (vector.z < vMin.z) + { + vMin.z = vector.z; + } + isSet = true; + } + } + else + { + UIWidget component = content.GetComponent(); + if (component != null && component.enabled) + { + Vector3[] worldCorners2 = component.worldCorners; + for (int j = 0; j < 4; j++) + { + Vector3 vector2 = toLocal.MultiplyPoint3x4(worldCorners2[j]); + if (vector2.x > vMax.x) + { + vMax.x = vector2.x; + } + if (vector2.y > vMax.y) + { + vMax.y = vector2.y; + } + if (vector2.z > vMax.z) + { + vMax.z = vector2.z; + } + if (vector2.x < vMin.x) + { + vMin.x = vector2.x; + } + if (vector2.y < vMin.y) + { + vMin.y = vector2.y; + } + if (vector2.z < vMin.z) + { + vMin.z = vector2.z; + } + isSet = true; + } + } + int k = 0; + for (int childCount = content.childCount; k < childCount; k++) + { + CalculateRelativeWidgetBounds(content.GetChild(k), considerInactive, /*isRoot:*/ false, ref toLocal, ref vMin, ref vMax, ref isSet); + } + } + } + } + } + + public static Vector3 SpringDampen(ref Vector3 velocity, float strength, float deltaTime) + { + if (deltaTime > 1f) + { + deltaTime = 1f; + } + float f = 1f - strength * 0.001f; + int num = Mathf.RoundToInt(deltaTime * 1000f); + float num2 = Mathf.Pow(f, (float)num); + Vector3 a = velocity * ((num2 - 1f) / Mathf.Log(f)); + velocity *= num2; + return a * 0.06f; + } + + public static Vector2 SpringDampen(ref Vector2 velocity, float strength, float deltaTime) + { + if (deltaTime > 1f) + { + deltaTime = 1f; + } + float f = 1f - strength * 0.001f; + int num = Mathf.RoundToInt(deltaTime * 1000f); + float num2 = Mathf.Pow(f, (float)num); + Vector2 a = velocity * ((num2 - 1f) / Mathf.Log(f)); + velocity *= num2; + return a * 0.06f; + } + + public static float SpringLerp(float strength, float deltaTime) + { + if (deltaTime > 1f) + { + deltaTime = 1f; + } + int num = Mathf.RoundToInt(deltaTime * 1000f); + deltaTime = 0.001f * strength; + float num2 = 0f; + for (int i = 0; i < num; i++) + { + num2 = Mathf.Lerp(num2, 1f, deltaTime); + } + return num2; + } + + public static float SpringLerp(float from, float to, float strength, float deltaTime) + { + if (deltaTime > 1f) + { + deltaTime = 1f; + } + int num = Mathf.RoundToInt(deltaTime * 1000f); + deltaTime = 0.001f * strength; + for (int i = 0; i < num; i++) + { + from = Mathf.Lerp(from, to, deltaTime); + } + return from; + } + + public static Vector2 SpringLerp(Vector2 from, Vector2 to, float strength, float deltaTime) + { + return Vector2.Lerp(from, to, SpringLerp(strength, deltaTime)); + } + + public static Vector3 SpringLerp(Vector3 from, Vector3 to, float strength, float deltaTime) + { + return Vector3.Lerp(from, to, SpringLerp(strength, deltaTime)); + } + + public static Quaternion SpringLerp(Quaternion from, Quaternion to, float strength, float deltaTime) + { + return Quaternion.Slerp(from, to, SpringLerp(strength, deltaTime)); + } + + public static float RotateTowards(float from, float to, float maxAngle) + { + float num = WrapAngle(to - from); + if (Mathf.Abs(num) > maxAngle) + { + num = maxAngle * Mathf.Sign(num); + } + return from + num; + } + + private static float DistancePointToLineSegment(Vector2 point, Vector2 a, Vector2 b) + { + float sqrMagnitude = (b - a).sqrMagnitude; + if (sqrMagnitude == 0f) + { + return (point - a).magnitude; + } + float num = Vector2.Dot(point - a, b - a) / sqrMagnitude; + if (num < 0f) + { + return (point - a).magnitude; + } + if (num > 1f) + { + return (point - b).magnitude; + } + Vector2 b2 = a + num * (b - a); + return (point - b2).magnitude; + } + + public static float DistanceToRectangle(Vector2[] screenPoints, Vector2 mousePos) + { + bool flag = false; + int val = 4; + for (int i = 0; i < 5; i++) + { + Vector3 vector = screenPoints[RepeatIndex(i, 4)]; + Vector3 vector2 = screenPoints[RepeatIndex(val, 4)]; + if (vector.y > mousePos.y != vector2.y > mousePos.y && mousePos.x < (vector2.x - vector.x) * (mousePos.y - vector.y) / (vector2.y - vector.y) + vector.x) + { + flag = !flag; + } + val = i; + } + if (!flag) + { + float num = -1f; + for (int j = 0; j < 4; j++) + { + Vector3 v = screenPoints[j]; + Vector3 v2 = screenPoints[RepeatIndex(j + 1, 4)]; + float num2 = DistancePointToLineSegment(mousePos, v, v2); + if (num2 < num || num < 0f) + { + num = num2; + } + } + return num; + } + return 0f; + } + + public static float DistanceToRectangle(Vector3[] worldPoints, Vector2 mousePos, Camera cam) + { + Vector2[] array = new Vector2[4]; + for (int i = 0; i < 4; i++) + { + array[i] = cam.WorldToScreenPoint(worldPoints[i]); + } + return DistanceToRectangle(array, mousePos); + } + + public static Vector2 GetPivotOffset(UIWidget.Pivot pv) + { + Vector2 zero = Vector2.zero; + switch (pv) + { + case UIWidget.Pivot.Top: + case UIWidget.Pivot.Center: + case UIWidget.Pivot.Bottom: + zero.x = 0.5f; + break; + case UIWidget.Pivot.TopRight: + case UIWidget.Pivot.Right: + case UIWidget.Pivot.BottomRight: + zero.x = 1f; + break; + default: + zero.x = 0f; + break; + } + switch (pv) + { + case UIWidget.Pivot.Left: + case UIWidget.Pivot.Center: + case UIWidget.Pivot.Right: + zero.y = 0.5f; + break; + case UIWidget.Pivot.TopLeft: + case UIWidget.Pivot.Top: + case UIWidget.Pivot.TopRight: + zero.y = 1f; + break; + default: + zero.y = 0f; + break; + } + return zero; + } + + public static UIWidget.Pivot GetPivot(Vector2 offset) + { + if (offset.x == 0f) + { + if (offset.y == 0f) + { + return UIWidget.Pivot.BottomLeft; + } + if (offset.y == 1f) + { + return UIWidget.Pivot.TopLeft; + } + return UIWidget.Pivot.Left; + } + if (offset.x == 1f) + { + if (offset.y == 0f) + { + return UIWidget.Pivot.BottomRight; + } + if (offset.y == 1f) + { + return UIWidget.Pivot.TopRight; + } + return UIWidget.Pivot.Right; + } + if (offset.y == 0f) + { + return UIWidget.Pivot.Bottom; + } + if (offset.y == 1f) + { + return UIWidget.Pivot.Top; + } + return UIWidget.Pivot.Center; + } + + public static void MoveWidget(UIRect w, float x, float y) + { + MoveRect(w, x, y); + } + + public static void MoveRect(UIRect rect, float x, float y) + { + int num = Mathf.FloorToInt(x + 0.5f); + int num2 = Mathf.FloorToInt(y + 0.5f); + Transform cachedTransform = rect.cachedTransform; + cachedTransform.localPosition += new Vector3((float)num, (float)num2); + int num3 = 0; + if ((bool)rect.leftAnchor.target) + { + num3++; + rect.leftAnchor.absolute += num; + } + if ((bool)rect.rightAnchor.target) + { + num3++; + rect.rightAnchor.absolute += num; + } + if ((bool)rect.bottomAnchor.target) + { + num3++; + rect.bottomAnchor.absolute += num2; + } + if ((bool)rect.topAnchor.target) + { + num3++; + rect.topAnchor.absolute += num2; + } + if (num3 != 0) + { + rect.UpdateAnchors(); + } + } + + public static void ResizeWidget(UIWidget w, UIWidget.Pivot pivot, float x, float y, int minWidth, int minHeight) + { + ResizeWidget(w, pivot, x, y, 2, 2, 100000, 100000); + } + + public static void ResizeWidget(UIWidget w, UIWidget.Pivot pivot, float x, float y, int minWidth, int minHeight, int maxWidth, int maxHeight) + { + if (pivot == UIWidget.Pivot.Center) + { + int num = Mathf.RoundToInt(x - (float)w.width); + int num2 = Mathf.RoundToInt(y - (float)w.height); + num -= (num & 1); + num2 -= (num2 & 1); + if ((num | num2) != 0) + { + num >>= 1; + num2 >>= 1; + AdjustWidget(w, (float)(-num), (float)(-num2), (float)num, (float)num2, minWidth, minHeight); + } + } + else + { + Vector3 point = new Vector3(x, y); + point = Quaternion.Inverse(w.cachedTransform.localRotation) * point; + switch (pivot) + { + case UIWidget.Pivot.Center: + break; + case UIWidget.Pivot.BottomLeft: + AdjustWidget(w, point.x, point.y, 0f, 0f, minWidth, minHeight, maxWidth, maxHeight); + break; + case UIWidget.Pivot.Left: + AdjustWidget(w, point.x, 0f, 0f, 0f, minWidth, minHeight, maxWidth, maxHeight); + break; + case UIWidget.Pivot.TopLeft: + AdjustWidget(w, point.x, 0f, 0f, point.y, minWidth, minHeight, maxWidth, maxHeight); + break; + case UIWidget.Pivot.Top: + AdjustWidget(w, 0f, 0f, 0f, point.y, minWidth, minHeight, maxWidth, maxHeight); + break; + case UIWidget.Pivot.TopRight: + AdjustWidget(w, 0f, 0f, point.x, point.y, minWidth, minHeight, maxWidth, maxHeight); + break; + case UIWidget.Pivot.Right: + AdjustWidget(w, 0f, 0f, point.x, 0f, minWidth, minHeight, maxWidth, maxHeight); + break; + case UIWidget.Pivot.BottomRight: + AdjustWidget(w, 0f, point.y, point.x, 0f, minWidth, minHeight, maxWidth, maxHeight); + break; + case UIWidget.Pivot.Bottom: + AdjustWidget(w, 0f, point.y, 0f, 0f, minWidth, minHeight, maxWidth, maxHeight); + break; + } + } + } + + public static void AdjustWidget(UIWidget w, float left, float bottom, float right, float top) + { + AdjustWidget(w, left, bottom, right, top, 2, 2, 100000, 100000); + } + + public static void AdjustWidget(UIWidget w, float left, float bottom, float right, float top, int minWidth, int minHeight) + { + AdjustWidget(w, left, bottom, right, top, minWidth, minHeight, 100000, 100000); + } + + public static void AdjustWidget(UIWidget w, float left, float bottom, float right, float top, int minWidth, int minHeight, int maxWidth, int maxHeight) + { + Vector2 pivotOffset = w.pivotOffset; + Transform cachedTransform = w.cachedTransform; + Quaternion localRotation = cachedTransform.localRotation; + int num = Mathf.FloorToInt(left + 0.5f); + int num2 = Mathf.FloorToInt(bottom + 0.5f); + int num3 = Mathf.FloorToInt(right + 0.5f); + int num4 = Mathf.FloorToInt(top + 0.5f); + if (pivotOffset.x == 0.5f && (num == 0 || num3 == 0)) + { + num = num >> 1 << 1; + num3 = num3 >> 1 << 1; + } + if (pivotOffset.y == 0.5f && (num2 == 0 || num4 == 0)) + { + num2 = num2 >> 1 << 1; + num4 = num4 >> 1 << 1; + } + Vector3 vector = localRotation * new Vector3((float)num, (float)num4); + Vector3 vector2 = localRotation * new Vector3((float)num3, (float)num4); + Vector3 vector3 = localRotation * new Vector3((float)num, (float)num2); + Vector3 vector4 = localRotation * new Vector3((float)num3, (float)num2); + Vector3 vector5 = localRotation * new Vector3((float)num, 0f); + Vector3 vector6 = localRotation * new Vector3((float)num3, 0f); + Vector3 vector7 = localRotation * new Vector3(0f, (float)num4); + Vector3 vector8 = localRotation * new Vector3(0f, (float)num2); + Vector3 zero = Vector3.zero; + if (pivotOffset.x == 0f && pivotOffset.y == 1f) + { + zero.x = vector.x; + zero.y = vector.y; + } + else if (pivotOffset.x == 1f && pivotOffset.y == 0f) + { + zero.x = vector4.x; + zero.y = vector4.y; + } + else if (pivotOffset.x == 0f && pivotOffset.y == 0f) + { + zero.x = vector3.x; + zero.y = vector3.y; + } + else if (pivotOffset.x == 1f && pivotOffset.y == 1f) + { + zero.x = vector2.x; + zero.y = vector2.y; + } + else if (pivotOffset.x == 0f && pivotOffset.y == 0.5f) + { + zero.x = vector5.x + (vector7.x + vector8.x) * 0.5f; + zero.y = vector5.y + (vector7.y + vector8.y) * 0.5f; + } + else if (pivotOffset.x == 1f && pivotOffset.y == 0.5f) + { + zero.x = vector6.x + (vector7.x + vector8.x) * 0.5f; + zero.y = vector6.y + (vector7.y + vector8.y) * 0.5f; + } + else if (pivotOffset.x == 0.5f && pivotOffset.y == 1f) + { + zero.x = vector7.x + (vector5.x + vector6.x) * 0.5f; + zero.y = vector7.y + (vector5.y + vector6.y) * 0.5f; + } + else if (pivotOffset.x == 0.5f && pivotOffset.y == 0f) + { + zero.x = vector8.x + (vector5.x + vector6.x) * 0.5f; + zero.y = vector8.y + (vector5.y + vector6.y) * 0.5f; + } + else if (pivotOffset.x == 0.5f && pivotOffset.y == 0.5f) + { + zero.x = (vector5.x + vector6.x + vector7.x + vector8.x) * 0.5f; + zero.y = (vector7.y + vector8.y + vector5.y + vector6.y) * 0.5f; + } + minWidth = Mathf.Max(minWidth, w.minWidth); + minHeight = Mathf.Max(minHeight, w.minHeight); + int num5 = w.width + num3 - num; + int num6 = w.height + num4 - num2; + Vector3 zero2 = Vector3.zero; + int num7 = num5; + if (num5 < minWidth) + { + num7 = minWidth; + } + else if (num5 > maxWidth) + { + num7 = maxWidth; + } + if (num5 != num7) + { + if (num != 0) + { + zero2.x -= Mathf.Lerp((float)(num7 - num5), 0f, pivotOffset.x); + } + else + { + zero2.x += Mathf.Lerp(0f, (float)(num7 - num5), pivotOffset.x); + } + num5 = num7; + } + int num8 = num6; + if (num6 < minHeight) + { + num8 = minHeight; + } + else if (num6 > maxHeight) + { + num8 = maxHeight; + } + if (num6 != num8) + { + if (num2 != 0) + { + zero2.y -= Mathf.Lerp((float)(num8 - num6), 0f, pivotOffset.y); + } + else + { + zero2.y += Mathf.Lerp(0f, (float)(num8 - num6), pivotOffset.y); + } + num6 = num8; + } + if (pivotOffset.x == 0.5f) + { + num5 = num5 >> 1 << 1; + } + if (pivotOffset.y == 0.5f) + { + num6 = num6 >> 1 << 1; + } + Vector3 vector10 = cachedTransform.localPosition = cachedTransform.localPosition + zero + localRotation * zero2; + w.SetDimensions(num5, num6); + if (w.isAnchored) + { + cachedTransform = cachedTransform.parent; + float num9 = vector10.x - pivotOffset.x * (float)num5; + float num10 = vector10.y - pivotOffset.y * (float)num6; + if ((bool)w.leftAnchor.target) + { + w.leftAnchor.SetHorizontal(cachedTransform, num9); + } + if ((bool)w.rightAnchor.target) + { + w.rightAnchor.SetHorizontal(cachedTransform, num9 + (float)num5); + } + if ((bool)w.bottomAnchor.target) + { + w.bottomAnchor.SetVertical(cachedTransform, num10); + } + if ((bool)w.topAnchor.target) + { + w.topAnchor.SetVertical(cachedTransform, num10 + (float)num6); + } + } + } + + public static int AdjustByDPI(float height) + { + float num = Screen.dpi; + RuntimePlatform platform = Application.platform; + if (num == 0f) + { + num = ((platform != RuntimePlatform.Android && platform != RuntimePlatform.IPhonePlayer) ? 96f : 160f); + } + int num2 = Mathf.RoundToInt(height * (96f / num)); + if ((num2 & 1) == 1) + { + num2++; + } + return num2; + } + + public static Vector2 ScreenToPixels(Vector2 pos, Transform relativeTo) + { + int layer = relativeTo.gameObject.layer; + Camera camera = NGUITools.FindCameraForLayer(layer); + if (camera == null) + { + UnityEngine.Debug.LogWarning("No camera found for layer " + layer); + return pos; + } + Vector3 position = camera.ScreenToWorldPoint(pos); + return relativeTo.InverseTransformPoint(position); + } + + public static Vector2 ScreenToParentPixels(Vector2 pos, Transform relativeTo) + { + int layer = relativeTo.gameObject.layer; + if (relativeTo.parent != null) + { + relativeTo = relativeTo.parent; + } + Camera camera = NGUITools.FindCameraForLayer(layer); + if (camera == null) + { + UnityEngine.Debug.LogWarning("No camera found for layer " + layer); + return pos; + } + Vector3 vector = camera.ScreenToWorldPoint(pos); + return (!(relativeTo != null)) ? vector : relativeTo.InverseTransformPoint(vector); + } + + public static Vector3 WorldToLocalPoint(Vector3 worldPos, Camera worldCam, Camera uiCam, Transform relativeTo) + { + worldPos = worldCam.WorldToViewportPoint(worldPos); + worldPos = uiCam.ViewportToWorldPoint(worldPos); + if (relativeTo == null) + { + return worldPos; + } + relativeTo = relativeTo.parent; + if (relativeTo == null) + { + return worldPos; + } + return relativeTo.InverseTransformPoint(worldPos); + } + + public static void OverlayPosition(this Transform trans, Vector3 worldPos, Camera worldCam, Camera myCam) + { + worldPos = worldCam.WorldToViewportPoint(worldPos); + worldPos = myCam.ViewportToWorldPoint(worldPos); + Transform parent = trans.parent; + trans.localPosition = ((!(parent != null)) ? worldPos : parent.InverseTransformPoint(worldPos)); + } + + public static void OverlayPosition(this Transform trans, Vector3 worldPos, Camera worldCam) + { + Camera camera = NGUITools.FindCameraForLayer(trans.gameObject.layer); + if (camera != null) + { + trans.OverlayPosition(worldPos, worldCam, camera); + } + } + + public static void OverlayPosition(this Transform trans, Transform target) + { + Camera camera = NGUITools.FindCameraForLayer(trans.gameObject.layer); + Camera camera2 = NGUITools.FindCameraForLayer(target.gameObject.layer); + if (camera != null && camera2 != null) + { + trans.OverlayPosition(target.position, camera2, camera); + } + } +} diff --git a/NGUIText.cs b/NGUIText.cs new file mode 100644 index 00000000..651728fe --- /dev/null +++ b/NGUIText.cs @@ -0,0 +1,1892 @@ +using System.Diagnostics; +using System.Text; +using UnityEngine; + +public static class NGUIText +{ + public enum Alignment + { + Automatic, + Left, + Center, + Right, + Justified + } + + public enum SymbolStyle + { + None, + Normal, + Colored + } + + public class GlyphInfo + { + public Vector2 v0; + + public Vector2 v1; + + public Vector2 u0; + + public Vector2 u1; + + public float advance; + + public int channel; + + public bool rotatedUVs; + } + + public static UIFont bitmapFont; + + public static Font dynamicFont; + + public static GlyphInfo glyph = new GlyphInfo(); + + public static int fontSize = 16; + + public static float fontScale = 1f; + + public static float pixelDensity = 1f; + + public static FontStyle fontStyle = FontStyle.Normal; + + public static Alignment alignment = Alignment.Left; + + public static Color tint = Color.white; + + public static int rectWidth = 1000000; + + public static int rectHeight = 1000000; + + public static int regionWidth = 1000000; + + public static int regionHeight = 1000000; + + public static int maxLines = 0; + + public static bool gradient = false; + + public static Color gradientBottom = Color.white; + + public static Color gradientTop = Color.white; + + public static bool encoding = false; + + public static float spacingX = 0f; + + public static float spacingY = 0f; + + public static bool premultiply = false; + + public static SymbolStyle symbolStyle; + + public static int finalSize = 0; + + public static float finalSpacingX = 0f; + + public static float finalLineHeight = 0f; + + public static float baseline = 0f; + + public static bool useSymbols = false; + + private static Color mInvisible = new Color(0f, 0f, 0f, 0f); + + private static BetterList mColors = new BetterList(); + + private static float mAlpha = 1f; + + private static CharacterInfo mTempChar; + + private static BetterList mSizes = new BetterList(); + + private static Color32 s_c0; + + private static Color32 s_c1; + + private static float[] mBoldOffset = new float[8] + { + -0.25f, + 0f, + 0.25f, + 0f, + 0f, + -0.25f, + 0f, + 0.25f + }; + + public static void Update() + { + Update(request: true); + } + + public static void Update(bool request) + { + finalSize = Mathf.RoundToInt((float)fontSize / pixelDensity); + finalSpacingX = spacingX * fontScale; + finalLineHeight = ((float)fontSize + spacingY) * fontScale; + useSymbols = (bitmapFont != null && bitmapFont.hasSymbols && encoding && symbolStyle != SymbolStyle.None); + if (dynamicFont != null && request) + { + dynamicFont.RequestCharactersInTexture(")_-", finalSize, fontStyle); + if (!dynamicFont.GetCharacterInfo(')', out mTempChar, finalSize, fontStyle) || mTempChar.vert.height == 0f) + { + dynamicFont.RequestCharactersInTexture("A", finalSize, fontStyle); + if (!dynamicFont.GetCharacterInfo('A', out mTempChar, finalSize, fontStyle)) + { + baseline = 0f; + return; + } + } + float yMax = mTempChar.vert.yMax; + float yMin = mTempChar.vert.yMin; + baseline = Mathf.Round(yMax + ((float)finalSize - yMax + yMin) * 0.5f); + } + } + + public static void Prepare(string text) + { + if (dynamicFont != null) + { + dynamicFont.RequestCharactersInTexture(text, finalSize, fontStyle); + } + } + + public static BMSymbol GetSymbol(string text, int index, int textLength) + { + return (!(bitmapFont != null)) ? null : bitmapFont.MatchSymbol(text, index, textLength); + } + + public static float GetGlyphWidth(int ch, int prev) + { + if (bitmapFont != null) + { + bool flag = false; + if (ch == 8201) + { + flag = true; + ch = 32; + } + BMGlyph bMGlyph = bitmapFont.bmFont.GetGlyph(ch); + if (bMGlyph != null) + { + int num = bMGlyph.advance; + if (flag) + { + num >>= 1; + } + return fontScale * (float)((prev == 0) ? bMGlyph.advance : (num + bMGlyph.GetKerning(prev))); + } + } + else if (dynamicFont != null && dynamicFont.GetCharacterInfo((char)ch, out mTempChar, finalSize, fontStyle)) + { + return mTempChar.width * fontScale * pixelDensity; + } + return 0f; + } + + public static GlyphInfo GetGlyph(int ch, int prev) + { + if (bitmapFont != null) + { + bool flag = false; + if (ch == 8201) + { + flag = true; + ch = 32; + } + BMGlyph bMGlyph = bitmapFont.bmFont.GetGlyph(ch); + if (bMGlyph != null) + { + int num = (prev != 0) ? bMGlyph.GetKerning(prev) : 0; + glyph.v0.x = (float)((prev == 0) ? bMGlyph.offsetX : (bMGlyph.offsetX + num)); + glyph.v1.y = (float)(-bMGlyph.offsetY); + glyph.v1.x = glyph.v0.x + (float)bMGlyph.width; + glyph.v0.y = glyph.v1.y - (float)bMGlyph.height; + glyph.u0.x = (float)bMGlyph.x; + glyph.u0.y = (float)(bMGlyph.y + bMGlyph.height); + glyph.u1.x = (float)(bMGlyph.x + bMGlyph.width); + glyph.u1.y = (float)bMGlyph.y; + int num2 = bMGlyph.advance; + if (flag) + { + num2 >>= 1; + } + glyph.advance = (float)(num2 + num); + glyph.channel = bMGlyph.channel; + glyph.rotatedUVs = false; + if (fontScale != 1f) + { + glyph.v0 *= fontScale; + glyph.v1 *= fontScale; + glyph.advance *= fontScale; + } + return glyph; + } + } + else if (dynamicFont != null && dynamicFont.GetCharacterInfo((char)ch, out mTempChar, finalSize, fontStyle)) + { + glyph.v0.x = mTempChar.vert.xMin; + glyph.v1.x = glyph.v0.x + mTempChar.vert.width; + glyph.v0.y = mTempChar.vert.yMax - baseline; + glyph.v1.y = glyph.v0.y - mTempChar.vert.height; + glyph.u0.x = mTempChar.uv.xMin; + glyph.u0.y = mTempChar.uv.yMin; + glyph.u1.x = mTempChar.uv.xMax; + glyph.u1.y = mTempChar.uv.yMax; + glyph.advance = mTempChar.width; + glyph.channel = 0; + glyph.rotatedUVs = mTempChar.flipped; + glyph.v0.x = Mathf.Round(glyph.v0.x); + glyph.v0.y = Mathf.Round(glyph.v0.y); + glyph.v1.x = Mathf.Round(glyph.v1.x); + glyph.v1.y = Mathf.Round(glyph.v1.y); + float num3 = fontScale * pixelDensity; + if (num3 != 1f) + { + glyph.v0 *= num3; + glyph.v1 *= num3; + glyph.advance *= num3; + } + return glyph; + } + return null; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static float ParseAlpha(string text, int index) + { + int num = (NGUIMath.HexToDecimal(text[index + 1]) << 4) | NGUIMath.HexToDecimal(text[index + 2]); + return Mathf.Clamp01((float)num / 255f); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static Color ParseColor(string text, int offset) + { + return ParseColor24(text, offset); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static Color ParseColor24(string text, int offset) + { + int num = (NGUIMath.HexToDecimal(text[offset]) << 4) | NGUIMath.HexToDecimal(text[offset + 1]); + int num2 = (NGUIMath.HexToDecimal(text[offset + 2]) << 4) | NGUIMath.HexToDecimal(text[offset + 3]); + int num3 = (NGUIMath.HexToDecimal(text[offset + 4]) << 4) | NGUIMath.HexToDecimal(text[offset + 5]); + float num4 = 0.003921569f; + return new Color(num4 * (float)num, num4 * (float)num2, num4 * (float)num3); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static Color ParseColor32(string text, int offset) + { + int num = (NGUIMath.HexToDecimal(text[offset]) << 4) | NGUIMath.HexToDecimal(text[offset + 1]); + int num2 = (NGUIMath.HexToDecimal(text[offset + 2]) << 4) | NGUIMath.HexToDecimal(text[offset + 3]); + int num3 = (NGUIMath.HexToDecimal(text[offset + 4]) << 4) | NGUIMath.HexToDecimal(text[offset + 5]); + int num4 = (NGUIMath.HexToDecimal(text[offset + 6]) << 4) | NGUIMath.HexToDecimal(text[offset + 7]); + float num5 = 0.003921569f; + return new Color(num5 * (float)num, num5 * (float)num2, num5 * (float)num3, num5 * (float)num4); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string EncodeColor(Color c) + { + return EncodeColor24(c); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string EncodeAlpha(float a) + { + int num = Mathf.Clamp(Mathf.RoundToInt(a * 255f), 0, 255); + return NGUIMath.DecimalToHex8(num); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string EncodeColor24(Color c) + { + int num = 0xFFFFFF & (NGUIMath.ColorToInt(c) >> 8); + return NGUIMath.DecimalToHex24(num); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static string EncodeColor32(Color c) + { + int num = NGUIMath.ColorToInt(c); + return NGUIMath.DecimalToHex32(num); + } + + public static bool ParseSymbol(string text, ref int index) + { + int sub = 1; + bool bold = false; + bool italic = false; + bool underline = false; + bool strike = false; + bool ignoreColor = false; + return ParseSymbol(text, ref index, null, /*premultiply:*/ false, ref sub, ref bold, ref italic, ref underline, ref strike, ref ignoreColor); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static bool IsHex(char ch) + { + return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); + } + + public static bool ParseSymbol(string text, ref int index, BetterList colors, bool premultiply, ref int sub, ref bool bold, ref bool italic, ref bool underline, ref bool strike, ref bool ignoreColor) + { + int length = text.Length; + if (index + 3 > length || text[index] != '[') + { + return false; + } + if (text[index + 2] == ']') + { + if (text[index + 1] == '-') + { + if (colors != null && colors.size > 1) + { + colors.RemoveAt(colors.size - 1); + } + index += 3; + return true; + } + string text2 = text.Substring(index, 3); + switch (text2) + { + case "[b]": + bold = true; + index += 3; + return true; + case "[i]": + italic = true; + index += 3; + return true; + case "[u]": + underline = true; + index += 3; + return true; + case "[s]": + strike = true; + index += 3; + return true; + case "[c]": + ignoreColor = true; + index += 3; + return true; + } + } + if (index + 4 > length) + { + return false; + } + if (text[index + 3] == ']') + { + string text3 = text.Substring(index, 4); + switch (text3) + { + case "[/b]": + bold = false; + index += 4; + return true; + case "[/i]": + italic = false; + index += 4; + return true; + case "[/u]": + underline = false; + index += 4; + return true; + case "[/s]": + strike = false; + index += 4; + return true; + case "[/c]": + ignoreColor = false; + index += 4; + return true; + } + char ch = text[index + 1]; + char ch2 = text[index + 2]; + if (IsHex(ch) && IsHex(ch2)) + { + int num = (NGUIMath.HexToDecimal(ch) << 4) | NGUIMath.HexToDecimal(ch2); + mAlpha = (float)num / 255f; + index += 4; + return true; + } + } + if (index + 5 > length) + { + return false; + } + if (text[index + 4] == ']') + { + string text4 = text.Substring(index, 5); + switch (text4) + { + case "[sub]": + sub = 1; + index += 5; + return true; + case "[sup]": + sub = 2; + index += 5; + return true; + } + } + if (index + 6 > length) + { + return false; + } + if (text[index + 5] == ']') + { + string text5 = text.Substring(index, 6); + switch (text5) + { + case "[/sub]": + sub = 0; + index += 6; + return true; + case "[/sup]": + sub = 0; + index += 6; + return true; + case "[/url]": + index += 6; + return true; + } + } + if (text[index + 1] == 'u' && text[index + 2] == 'r' && text[index + 3] == 'l' && text[index + 4] == '=') + { + int num2 = text.IndexOf(']', index + 4); + if (num2 != -1) + { + index = num2 + 1; + return true; + } + index = text.Length; + return true; + } + if (index + 8 > length) + { + return false; + } + if (text[index + 7] == ']') + { + Color color = ParseColor24(text, index + 1); + if (EncodeColor24(color) != text.Substring(index + 1, 6).ToUpper()) + { + return false; + } + if (colors != null) + { + Color color2 = colors[colors.size - 1]; + color.a = color2.a; + if (premultiply && color.a != 1f) + { + color = Color.Lerp(mInvisible, color, color.a); + } + colors.Add(color); + } + index += 8; + return true; + } + if (index + 10 > length) + { + return false; + } + if (text[index + 9] == ']') + { + Color color3 = ParseColor32(text, index + 1); + if (EncodeColor32(color3) != text.Substring(index + 1, 8).ToUpper()) + { + return false; + } + if (colors != null) + { + if (premultiply && color3.a != 1f) + { + color3 = Color.Lerp(mInvisible, color3, color3.a); + } + colors.Add(color3); + } + index += 10; + return true; + } + return false; + } + + public static string StripSymbols(string text) + { + if (text != null) + { + int num = 0; + int length = text.Length; + while (num < length) + { + char c = text[num]; + if (c == '[') + { + int sub = 0; + bool bold = false; + bool italic = false; + bool underline = false; + bool strike = false; + bool ignoreColor = false; + int index = num; + if (ParseSymbol(text, ref index, null, /*premultiply:*/ false, ref sub, ref bold, ref italic, ref underline, ref strike, ref ignoreColor)) + { + text = text.Remove(num, index - num); + length = text.Length; + continue; + } + } + num++; + } + } + return text; + } + + public static void Align(BetterList verts, int indexOffset, float printedWidth) + { + switch (alignment) + { + case Alignment.Right: + { + float num17 = (float)rectWidth - printedWidth; + if (!(num17 < 0f)) + { + for (int j = indexOffset; j < verts.size; j++) + { + verts.buffer[j].x += num17; + } + } + break; + } + case Alignment.Center: + { + float num14 = ((float)rectWidth - printedWidth) * 0.5f; + if (!(num14 < 0f)) + { + int num15 = Mathf.RoundToInt((float)rectWidth - printedWidth); + int num16 = Mathf.RoundToInt((float)rectWidth); + bool flag = (num15 & 1) == 1; + bool flag2 = (num16 & 1) == 1; + if ((flag && !flag2) || (!flag && flag2)) + { + num14 += 0.5f * fontScale; + } + for (int i = indexOffset; i < verts.size; i++) + { + verts.buffer[i].x += num14; + } + } + break; + } + case Alignment.Justified: + if (!(printedWidth < (float)rectWidth * 0.65f)) + { + float num = ((float)rectWidth - printedWidth) * 0.5f; + if (!(num < 1f)) + { + int num2 = (verts.size - indexOffset) / 4; + if (num2 >= 1) + { + float num3 = 1f / (float)(num2 - 1); + float num4 = (float)rectWidth / printedWidth; + int num5 = indexOffset + 4; + int num6 = 1; + while (num5 < verts.size) + { + float x = verts.buffer[num5].x; + float x2 = verts.buffer[num5 + 2].x; + float num7 = x2 - x; + float num8 = x * num4; + float a = num8 + num7; + float num9 = x2 * num4; + float b = num9 - num7; + float t = (float)num6 * num3; + x = Mathf.Lerp(num8, b, t); + x2 = Mathf.Lerp(a, num9, t); + x = Mathf.Round(x); + x2 = Mathf.Round(x2); + verts.buffer[num5++].x = x; + verts.buffer[num5++].x = x; + verts.buffer[num5++].x = x2; + verts.buffer[num5++].x = x2; + num6++; + } + } + } + } + break; + } + } + + public static int GetExactCharacterIndex(BetterList verts, BetterList indices, Vector2 pos) + { + for (int i = 0; i < indices.size; i++) + { + int num = i << 1; + int i2 = num + 1; + Vector3 vector = verts[num]; + float x = vector.x; + if (!(pos.x < x)) + { + Vector3 vector2 = verts[i2]; + float x2 = vector2.x; + if (!(pos.x > x2)) + { + Vector3 vector3 = verts[num]; + float y = vector3.y; + if (!(pos.y < y)) + { + Vector3 vector4 = verts[i2]; + float y2 = vector4.y; + if (!(pos.y > y2)) + { + return indices[i]; + } + } + } + } + } + return 0; + } + + public static int GetApproximateCharacterIndex(BetterList verts, BetterList indices, Vector2 pos) + { + float num = 3.40282347E+38f; + float num2 = 3.40282347E+38f; + int i = 0; + for (int j = 0; j < verts.size; j++) + { + float y = pos.y; + Vector3 vector = verts[j]; + float num3 = Mathf.Abs(y - vector.y); + if (!(num3 > num2)) + { + float x = pos.x; + Vector3 vector2 = verts[j]; + float num4 = Mathf.Abs(x - vector2.x); + if (num3 < num2) + { + num2 = num3; + num = num4; + i = j; + } + else if (num4 < num) + { + num = num4; + i = j; + } + } + } + return indices[i]; + } + + [DebuggerHidden] + [DebuggerStepThrough] + private static bool IsSpace(int ch) + { + return ch == 32 || ch == 8202 || ch == 8203 || ch == 8201; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static void EndLine(ref StringBuilder s) + { + int num = s.Length - 1; + if (num > 0 && IsSpace(s[num])) + { + s[num] = '\n'; + } + else + { + s.Append('\n'); + } + } + + [DebuggerHidden] + [DebuggerStepThrough] + private static void ReplaceSpaceWithNewline(ref StringBuilder s) + { + int num = s.Length - 1; + if (num > 0 && IsSpace(s[num])) + { + s[num] = '\n'; + } + } + + public static Vector2 CalculatePrintedSize(string text) + { + Vector2 zero = Vector2.zero; + if (!string.IsNullOrEmpty(text)) + { + if (encoding) + { + text = StripSymbols(text); + } + Prepare(text); + float num = 0f; + float num2 = 0f; + float num3 = 0f; + int length = text.Length; + int num4 = 0; + int prev = 0; + for (int i = 0; i < length; i++) + { + num4 = text[i]; + if (num4 == 10) + { + if (num > num3) + { + num3 = num; + } + num = 0f; + num2 += finalLineHeight; + } + else if (num4 >= 32) + { + BMSymbol bMSymbol = (!useSymbols) ? null : GetSymbol(text, i, length); + if (bMSymbol == null) + { + float glyphWidth = GetGlyphWidth(num4, prev); + if (glyphWidth != 0f) + { + glyphWidth += finalSpacingX; + if (Mathf.RoundToInt(num + glyphWidth) > regionWidth) + { + if (num > num3) + { + num3 = num - finalSpacingX; + } + num = glyphWidth; + num2 += finalLineHeight; + } + else + { + num += glyphWidth; + } + prev = num4; + } + } + else + { + float num5 = finalSpacingX + (float)bMSymbol.advance * fontScale; + if (Mathf.RoundToInt(num + num5) > regionWidth) + { + if (num > num3) + { + num3 = num - finalSpacingX; + } + num = num5; + num2 += finalLineHeight; + } + else + { + num += num5; + } + i += bMSymbol.sequence.Length - 1; + prev = 0; + } + } + } + zero.x = ((!(num > num3)) ? num3 : (num - finalSpacingX)); + zero.y = num2 + finalLineHeight; + } + return zero; + } + + public static int CalculateOffsetToFit(string text) + { + if (string.IsNullOrEmpty(text) || regionWidth < 1) + { + return 0; + } + Prepare(text); + int length = text.Length; + int num = 0; + int prev = 0; + int i = 0; + for (int length2 = text.Length; i < length2; i++) + { + BMSymbol bMSymbol = (!useSymbols) ? null : GetSymbol(text, i, length); + if (bMSymbol == null) + { + num = text[i]; + float glyphWidth = GetGlyphWidth(num, prev); + if (glyphWidth != 0f) + { + mSizes.Add(finalSpacingX + glyphWidth); + } + prev = num; + } + else + { + mSizes.Add(finalSpacingX + (float)bMSymbol.advance * fontScale); + int j = 0; + for (int num2 = bMSymbol.sequence.Length - 1; j < num2; j++) + { + mSizes.Add(0f); + } + i += bMSymbol.sequence.Length - 1; + prev = 0; + } + } + float num3 = (float)regionWidth; + int num4 = mSizes.size; + while (num4 > 0 && num3 > 0f) + { + num3 -= mSizes[--num4]; + } + mSizes.Clear(); + if (num3 < 0f) + { + num4++; + } + return num4; + } + + public static string GetEndOfLineThatFits(string text) + { + int length = text.Length; + int num = CalculateOffsetToFit(text); + return text.Substring(num, length - num); + } + + public static bool WrapText(string text, out string finalText) + { + return WrapText(text, out finalText, keepCharCount: false); + } + + public static bool WrapText(string text, out string finalText, bool keepCharCount) + { + if (regionWidth < 1 || regionHeight < 1 || finalLineHeight < 1f) + { + finalText = string.Empty; + return false; + } + float num = (maxLines <= 0) ? ((float)regionHeight) : Mathf.Min((float)regionHeight, finalLineHeight * (float)maxLines); + int num2 = (maxLines <= 0) ? 1000000 : maxLines; + num2 = Mathf.FloorToInt(Mathf.Min((float)num2, num / finalLineHeight) + 0.01f); + if (num2 == 0) + { + finalText = string.Empty; + return false; + } + if (string.IsNullOrEmpty(text)) + { + text = " "; + } + Prepare(text); + StringBuilder s = new StringBuilder(); + int length = text.Length; + float num3 = (float)regionWidth; + int num4 = 0; + int i = 0; + int num5 = 1; + int prev = 0; + bool flag = true; + bool flag2 = true; + bool flag3 = false; + for (; i < length; i++) + { + char c = text[i]; + if (c > '\u2fff') + { + flag3 = true; + } + if (c == '\n') + { + if (num5 == num2) + { + break; + } + num3 = (float)regionWidth; + if (num4 < i) + { + s.Append(text.Substring(num4, i - num4 + 1)); + } + else + { + s.Append(c); + } + flag = true; + num5++; + num4 = i + 1; + prev = 0; + } + else if (encoding && ParseSymbol(text, ref i)) + { + i--; + } + else + { + BMSymbol bMSymbol = (!useSymbols) ? null : GetSymbol(text, i, length); + float num6; + if (bMSymbol == null) + { + float glyphWidth = GetGlyphWidth(c, prev); + if (glyphWidth == 0f) + { + continue; + } + num6 = finalSpacingX + glyphWidth; + } + else + { + num6 = finalSpacingX + (float)bMSymbol.advance * fontScale; + } + num3 -= num6; + if (IsSpace(c) && !flag3 && num4 < i) + { + int num7 = i - num4 + 1; + if (num5 == num2 && num3 <= 0f && i < length) + { + char c2 = text[i]; + if (c2 < ' ' || IsSpace(c2)) + { + num7--; + } + } + s.Append(text.Substring(num4, num7)); + flag = false; + num4 = i + 1; + prev = c; + } + if (Mathf.RoundToInt(num3) < 0) + { + if (!flag && num5 != num2) + { + flag = true; + num3 = (float)regionWidth; + i = num4 - 1; + prev = 0; + if (num5++ == num2) + { + break; + } + if (keepCharCount) + { + ReplaceSpaceWithNewline(ref s); + } + else + { + EndLine(ref s); + } + continue; + } + s.Append(text.Substring(num4, Mathf.Max(0, i - num4))); + bool flag4 = IsSpace(c); + if (!flag4 && !flag3) + { + flag2 = false; + } + if (num5++ == num2) + { + num4 = i; + break; + } + if (keepCharCount) + { + ReplaceSpaceWithNewline(ref s); + } + else + { + EndLine(ref s); + } + flag = true; + if (flag4) + { + num4 = i + 1; + num3 = (float)regionWidth; + } + else + { + num4 = i; + num3 = (float)regionWidth - num6; + } + prev = 0; + } + else + { + prev = c; + } + if (bMSymbol != null) + { + i += bMSymbol.length - 1; + prev = 0; + } + } + } + if (num4 < i) + { + s.Append(text.Substring(num4, i - num4)); + } + finalText = s.ToString(); + return flag2 && (i == length || num5 <= Mathf.Min(maxLines, num2)); + } + + public static void Print(string text, BetterList verts, BetterList uvs, BetterList cols) + { + if (!string.IsNullOrEmpty(text)) + { + int size = verts.size; + Prepare(text); + mColors.Add(Color.white); + mAlpha = 1f; + int num = 0; + int prev = 0; + float num2 = 0f; + float num3 = 0f; + float num4 = 0f; + float num5 = (float)finalSize; + Color a = tint * gradientBottom; + Color b = tint * gradientTop; + Color32 color = tint; + int length = text.Length; + Rect rect = default(Rect); + float num6 = 0f; + float num7 = 0f; + float num8 = num5 * pixelDensity; + bool flag = false; + int sub = 0; + bool bold = false; + bool italic = false; + bool underline = false; + bool strike = false; + bool ignoreColor = false; + float num9 = 0f; + if (bitmapFont != null) + { + rect = bitmapFont.uvRect; + num6 = rect.width / (float)bitmapFont.texWidth; + num7 = rect.height / (float)bitmapFont.texHeight; + } + for (int i = 0; i < length; i++) + { + num = text[i]; + num9 = num2; + if (num == 10) + { + if (num2 > num4) + { + num4 = num2; + } + if (alignment != Alignment.Left) + { + Align(verts, size, num2 - finalSpacingX); + size = verts.size; + } + num2 = 0f; + num3 += finalLineHeight; + prev = 0; + } + else if (num < 32) + { + prev = num; + } + else if (encoding && ParseSymbol(text, ref i, mColors, premultiply, ref sub, ref bold, ref italic, ref underline, ref strike, ref ignoreColor)) + { + Color color2; + if (ignoreColor) + { + color2 = mColors[mColors.size - 1]; + color2.a *= mAlpha * tint.a; + } + else + { + color2 = tint * mColors[mColors.size - 1]; + color2.a *= mAlpha; + } + color = color2; + int j = 0; + for (int num10 = mColors.size - 2; j < num10; j++) + { + float a2 = color2.a; + Color color3 = mColors[j]; + color2.a = a2 * color3.a; + } + if (gradient) + { + a = gradientBottom * color2; + b = gradientTop * color2; + } + i--; + } + else + { + BMSymbol bMSymbol = (!useSymbols) ? null : GetSymbol(text, i, length); + if (bMSymbol != null) + { + float num11 = num2 + (float)bMSymbol.offsetX * fontScale; + float num12 = num11 + (float)bMSymbol.width * fontScale; + float num13 = 0f - (num3 + (float)bMSymbol.offsetY * fontScale); + float num14 = num13 - (float)bMSymbol.height * fontScale; + if (Mathf.RoundToInt(num2 + (float)bMSymbol.advance * fontScale) > regionWidth) + { + if (num2 == 0f) + { + return; + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num2 - finalSpacingX); + size = verts.size; + } + num11 -= num2; + num12 -= num2; + num14 -= finalLineHeight; + num13 -= finalLineHeight; + num2 = 0f; + num3 += finalLineHeight; + num9 = 0f; + } + verts.Add(new Vector3(num11, num14)); + verts.Add(new Vector3(num11, num13)); + verts.Add(new Vector3(num12, num13)); + verts.Add(new Vector3(num12, num14)); + num2 += finalSpacingX + (float)bMSymbol.advance * fontScale; + i += bMSymbol.length - 1; + prev = 0; + if (uvs != null) + { + Rect uvRect = bMSymbol.uvRect; + float xMin = uvRect.xMin; + float yMin = uvRect.yMin; + float xMax = uvRect.xMax; + float yMax = uvRect.yMax; + uvs.Add(new Vector2(xMin, yMin)); + uvs.Add(new Vector2(xMin, yMax)); + uvs.Add(new Vector2(xMax, yMax)); + uvs.Add(new Vector2(xMax, yMin)); + } + if (cols != null) + { + if (symbolStyle == SymbolStyle.Colored) + { + for (int k = 0; k < 4; k++) + { + cols.Add(color); + } + } + else + { + Color32 item = Color.white; + item.a = color.a; + for (int l = 0; l < 4; l++) + { + cols.Add(item); + } + } + } + } + else + { + GlyphInfo glyphInfo = GetGlyph(num, prev); + if (glyphInfo != null) + { + prev = num; + if (sub != 0) + { + glyphInfo.v0.x *= 0.75f; + glyphInfo.v0.y *= 0.75f; + glyphInfo.v1.x *= 0.75f; + glyphInfo.v1.y *= 0.75f; + if (sub == 1) + { + glyphInfo.v0.y -= fontScale * (float)fontSize * 0.4f; + glyphInfo.v1.y -= fontScale * (float)fontSize * 0.4f; + } + else + { + glyphInfo.v0.y += fontScale * (float)fontSize * 0.05f; + glyphInfo.v1.y += fontScale * (float)fontSize * 0.05f; + } + } + float num11 = glyphInfo.v0.x + num2; + float num14 = glyphInfo.v0.y - num3; + float num12 = glyphInfo.v1.x + num2; + float num13 = glyphInfo.v1.y - num3; + float num15 = glyphInfo.advance; + if (finalSpacingX < 0f) + { + num15 += finalSpacingX; + } + if (Mathf.RoundToInt(num2 + num15) > regionWidth) + { + if (num2 == 0f) + { + return; + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num2 - finalSpacingX); + size = verts.size; + } + num11 -= num2; + num12 -= num2; + num14 -= finalLineHeight; + num13 -= finalLineHeight; + num2 = 0f; + num3 += finalLineHeight; + num9 = 0f; + } + if (IsSpace(num)) + { + if (underline) + { + num = 95; + } + else if (strike) + { + num = 45; + } + } + num2 += ((sub != 0) ? ((finalSpacingX + glyphInfo.advance) * 0.75f) : (finalSpacingX + glyphInfo.advance)); + if (!IsSpace(num)) + { + if (uvs != null) + { + if (bitmapFont != null) + { + glyphInfo.u0.x = rect.xMin + num6 * glyphInfo.u0.x; + glyphInfo.u1.x = rect.xMin + num6 * glyphInfo.u1.x; + glyphInfo.u0.y = rect.yMax - num7 * glyphInfo.u0.y; + glyphInfo.u1.y = rect.yMax - num7 * glyphInfo.u1.y; + } + int m = 0; + for (int num16 = (!bold) ? 1 : 4; m < num16; m++) + { + if (glyphInfo.rotatedUVs) + { + uvs.Add(glyphInfo.u0); + uvs.Add(new Vector2(glyphInfo.u1.x, glyphInfo.u0.y)); + uvs.Add(glyphInfo.u1); + uvs.Add(new Vector2(glyphInfo.u0.x, glyphInfo.u1.y)); + } + else + { + uvs.Add(glyphInfo.u0); + uvs.Add(new Vector2(glyphInfo.u0.x, glyphInfo.u1.y)); + uvs.Add(glyphInfo.u1); + uvs.Add(new Vector2(glyphInfo.u1.x, glyphInfo.u0.y)); + } + } + } + if (cols != null) + { + if (glyphInfo.channel == 0 || glyphInfo.channel == 15) + { + if (gradient) + { + float num17 = num8 + glyphInfo.v0.y / fontScale; + float num18 = num8 + glyphInfo.v1.y / fontScale; + num17 /= num8; + num18 /= num8; + s_c0 = Color.Lerp(a, b, num17); + s_c1 = Color.Lerp(a, b, num18); + int n = 0; + for (int num19 = (!bold) ? 1 : 4; n < num19; n++) + { + cols.Add(s_c0); + cols.Add(s_c1); + cols.Add(s_c1); + cols.Add(s_c0); + } + } + else + { + int num20 = 0; + for (int num21 = (!bold) ? 4 : 16; num20 < num21; num20++) + { + cols.Add(color); + } + } + } + else + { + Color color4 = color; + color4 *= 0.49f; + switch (glyphInfo.channel) + { + case 1: + color4.b += 0.51f; + break; + case 2: + color4.g += 0.51f; + break; + case 4: + color4.r += 0.51f; + break; + case 8: + color4.a += 0.51f; + break; + } + Color32 item2 = color4; + int num22 = 0; + for (int num23 = (!bold) ? 4 : 16; num22 < num23; num22++) + { + cols.Add(item2); + } + } + } + if (!bold) + { + if (!italic) + { + verts.Add(new Vector3(num11, num14)); + verts.Add(new Vector3(num11, num13)); + verts.Add(new Vector3(num12, num13)); + verts.Add(new Vector3(num12, num14)); + } + else + { + float num24 = (float)fontSize * 0.1f * ((num13 - num14) / (float)fontSize); + verts.Add(new Vector3(num11 - num24, num14)); + verts.Add(new Vector3(num11 + num24, num13)); + verts.Add(new Vector3(num12 + num24, num13)); + verts.Add(new Vector3(num12 - num24, num14)); + } + } + else + { + for (int num25 = 0; num25 < 4; num25++) + { + float num26 = mBoldOffset[num25 * 2]; + float num27 = mBoldOffset[num25 * 2 + 1]; + float num28 = (!italic) ? 0f : ((float)fontSize * 0.1f * ((num13 - num14) / (float)fontSize)); + verts.Add(new Vector3(num11 + num26 - num28, num14 + num27)); + verts.Add(new Vector3(num11 + num26 + num28, num13 + num27)); + verts.Add(new Vector3(num12 + num26 + num28, num13 + num27)); + verts.Add(new Vector3(num12 + num26 - num28, num14 + num27)); + } + } + if (underline || strike) + { + GlyphInfo glyphInfo2 = GetGlyph((!strike) ? 95 : 45, prev); + if (glyphInfo2 != null) + { + if (uvs != null) + { + if (bitmapFont != null) + { + glyphInfo2.u0.x = rect.xMin + num6 * glyphInfo2.u0.x; + glyphInfo2.u1.x = rect.xMin + num6 * glyphInfo2.u1.x; + glyphInfo2.u0.y = rect.yMax - num7 * glyphInfo2.u0.y; + glyphInfo2.u1.y = rect.yMax - num7 * glyphInfo2.u1.y; + } + float x = (glyphInfo2.u0.x + glyphInfo2.u1.x) * 0.5f; + int num29 = 0; + for (int num30 = (!bold) ? 1 : 4; num29 < num30; num29++) + { + uvs.Add(new Vector2(x, glyphInfo2.u0.y)); + uvs.Add(new Vector2(x, glyphInfo2.u1.y)); + uvs.Add(new Vector2(x, glyphInfo2.u1.y)); + uvs.Add(new Vector2(x, glyphInfo2.u0.y)); + } + } + if (flag && strike) + { + num14 = (0f - num3 + glyphInfo2.v0.y) * 0.75f; + num13 = (0f - num3 + glyphInfo2.v1.y) * 0.75f; + } + else + { + num14 = 0f - num3 + glyphInfo2.v0.y; + num13 = 0f - num3 + glyphInfo2.v1.y; + } + if (bold) + { + for (int num31 = 0; num31 < 4; num31++) + { + float num32 = mBoldOffset[num31 * 2]; + float num33 = mBoldOffset[num31 * 2 + 1]; + verts.Add(new Vector3(num9 + num32, num14 + num33)); + verts.Add(new Vector3(num9 + num32, num13 + num33)); + verts.Add(new Vector3(num2 + num32, num13 + num33)); + verts.Add(new Vector3(num2 + num32, num14 + num33)); + } + } + else + { + verts.Add(new Vector3(num9, num14)); + verts.Add(new Vector3(num9, num13)); + verts.Add(new Vector3(num2, num13)); + verts.Add(new Vector3(num2, num14)); + } + if (gradient) + { + float num34 = num8 + glyphInfo2.v0.y / fontScale; + float num35 = num8 + glyphInfo2.v1.y / fontScale; + num34 /= num8; + num35 /= num8; + s_c0 = Color.Lerp(a, b, num34); + s_c1 = Color.Lerp(a, b, num35); + int num36 = 0; + for (int num37 = (!bold) ? 1 : 4; num36 < num37; num36++) + { + cols.Add(s_c0); + cols.Add(s_c1); + cols.Add(s_c1); + cols.Add(s_c0); + } + } + else + { + int num38 = 0; + for (int num39 = (!bold) ? 4 : 16; num38 < num39; num38++) + { + cols.Add(color); + } + } + } + } + } + } + } + } + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num2 - finalSpacingX); + size = verts.size; + } + mColors.Clear(); + } + } + + public static void PrintApproximateCharacterPositions(string text, BetterList verts, BetterList indices) + { + if (string.IsNullOrEmpty(text)) + { + text = " "; + } + Prepare(text); + float num = 0f; + float num2 = 0f; + float num3 = 0f; + float num4 = (float)fontSize * fontScale * 0.5f; + int length = text.Length; + int size = verts.size; + int num5 = 0; + int prev = 0; + for (int i = 0; i < length; i++) + { + num5 = text[i]; + verts.Add(new Vector3(num, 0f - num2 - num4)); + indices.Add(i); + if (num5 == 10) + { + if (num > num3) + { + num3 = num; + } + if (alignment != Alignment.Left) + { + Align(verts, size, num - finalSpacingX); + size = verts.size; + } + num = 0f; + num2 += finalLineHeight; + prev = 0; + } + else if (num5 < 32) + { + prev = 0; + } + else if (encoding && ParseSymbol(text, ref i)) + { + i--; + } + else + { + BMSymbol bMSymbol = (!useSymbols) ? null : GetSymbol(text, i, length); + if (bMSymbol == null) + { + float glyphWidth = GetGlyphWidth(num5, prev); + if (glyphWidth != 0f) + { + glyphWidth += finalSpacingX; + if (Mathf.RoundToInt(num + glyphWidth) > regionWidth) + { + if (num == 0f) + { + return; + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num - finalSpacingX); + size = verts.size; + } + num = glyphWidth; + num2 += finalLineHeight; + } + else + { + num += glyphWidth; + } + verts.Add(new Vector3(num, 0f - num2 - num4)); + indices.Add(i + 1); + prev = num5; + } + } + else + { + float num6 = (float)bMSymbol.advance * fontScale + finalSpacingX; + if (Mathf.RoundToInt(num + num6) > regionWidth) + { + if (num == 0f) + { + return; + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num - finalSpacingX); + size = verts.size; + } + num = num6; + num2 += finalLineHeight; + } + else + { + num += num6; + } + verts.Add(new Vector3(num, 0f - num2 - num4)); + indices.Add(i + 1); + i += bMSymbol.sequence.Length - 1; + prev = 0; + } + } + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num - finalSpacingX); + } + } + + public static void PrintExactCharacterPositions(string text, BetterList verts, BetterList indices) + { + if (string.IsNullOrEmpty(text)) + { + text = " "; + } + Prepare(text); + float num = (float)fontSize * fontScale; + float num2 = 0f; + float num3 = 0f; + float num4 = 0f; + int length = text.Length; + int size = verts.size; + int num5 = 0; + int prev = 0; + for (int i = 0; i < length; i++) + { + num5 = text[i]; + if (num5 == 10) + { + if (num2 > num4) + { + num4 = num2; + } + if (alignment != Alignment.Left) + { + Align(verts, size, num2 - finalSpacingX); + size = verts.size; + } + num2 = 0f; + num3 += finalLineHeight; + prev = 0; + } + else if (num5 < 32) + { + prev = 0; + } + else if (encoding && ParseSymbol(text, ref i)) + { + i--; + } + else + { + BMSymbol bMSymbol = (!useSymbols) ? null : GetSymbol(text, i, length); + if (bMSymbol == null) + { + float glyphWidth = GetGlyphWidth(num5, prev); + if (glyphWidth != 0f) + { + float num6 = glyphWidth + finalSpacingX; + if (Mathf.RoundToInt(num2 + num6) > regionWidth) + { + if (num2 == 0f) + { + return; + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num2 - finalSpacingX); + size = verts.size; + } + num2 = 0f; + num3 += finalLineHeight; + prev = 0; + i--; + } + else + { + indices.Add(i); + verts.Add(new Vector3(num2, 0f - num3 - num)); + verts.Add(new Vector3(num2 + num6, 0f - num3)); + prev = num5; + num2 += num6; + } + } + } + else + { + float num7 = (float)bMSymbol.advance * fontScale + finalSpacingX; + if (Mathf.RoundToInt(num2 + num7) > regionWidth) + { + if (num2 == 0f) + { + return; + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num2 - finalSpacingX); + size = verts.size; + } + num2 = 0f; + num3 += finalLineHeight; + prev = 0; + i--; + } + else + { + indices.Add(i); + verts.Add(new Vector3(num2, 0f - num3 - num)); + verts.Add(new Vector3(num2 + num7, 0f - num3)); + i += bMSymbol.sequence.Length - 1; + num2 += num7; + prev = 0; + } + } + } + } + if (alignment != Alignment.Left && size < verts.size) + { + Align(verts, size, num2 - finalSpacingX); + } + } + + public static void PrintCaretAndSelection(string text, int start, int end, BetterList caret, BetterList highlight) + { + if (string.IsNullOrEmpty(text)) + { + text = " "; + } + Prepare(text); + int num = end; + if (start > end) + { + end = start; + start = num; + } + float num2 = 0f; + float num3 = 0f; + float num4 = 0f; + float num5 = (float)fontSize * fontScale; + int indexOffset = caret?.size ?? 0; + int num6 = highlight?.size ?? 0; + int length = text.Length; + int i = 0; + int num7 = 0; + int prev = 0; + bool flag = false; + bool flag2 = false; + Vector2 v = Vector2.zero; + Vector2 v2 = Vector2.zero; + for (; i < length; i++) + { + if (caret != null && !flag2 && num <= i) + { + flag2 = true; + caret.Add(new Vector3(num2 - 1f, 0f - num3 - num5)); + caret.Add(new Vector3(num2 - 1f, 0f - num3)); + caret.Add(new Vector3(num2 + 1f, 0f - num3)); + caret.Add(new Vector3(num2 + 1f, 0f - num3 - num5)); + } + num7 = text[i]; + if (num7 == 10) + { + if (num2 > num4) + { + num4 = num2; + } + if (caret != null && flag2) + { + if (alignment != Alignment.Left) + { + Align(caret, indexOffset, num2 - finalSpacingX); + } + caret = null; + } + if (highlight != null) + { + if (flag) + { + flag = false; + highlight.Add(v2); + highlight.Add(v); + } + else if (start <= i && end > i) + { + highlight.Add(new Vector3(num2, 0f - num3 - num5)); + highlight.Add(new Vector3(num2, 0f - num3)); + highlight.Add(new Vector3(num2 + 2f, 0f - num3)); + highlight.Add(new Vector3(num2 + 2f, 0f - num3 - num5)); + } + if (alignment != Alignment.Left && num6 < highlight.size) + { + Align(highlight, num6, num2 - finalSpacingX); + num6 = highlight.size; + } + } + num2 = 0f; + num3 += finalLineHeight; + prev = 0; + } + else if (num7 < 32) + { + prev = 0; + } + else if (encoding && ParseSymbol(text, ref i)) + { + i--; + } + else + { + BMSymbol bMSymbol = (!useSymbols) ? null : GetSymbol(text, i, length); + float num8 = (bMSymbol == null) ? GetGlyphWidth(num7, prev) : ((float)bMSymbol.advance * fontScale); + if (num8 != 0f) + { + float num9 = num2; + float num10 = num2 + num8; + float num11 = 0f - num3 - num5; + float num12 = 0f - num3; + if (Mathf.RoundToInt(num10 + finalSpacingX) > regionWidth) + { + if (num2 == 0f) + { + return; + } + if (num2 > num4) + { + num4 = num2; + } + if (caret != null && flag2) + { + if (alignment != Alignment.Left) + { + Align(caret, indexOffset, num2 - finalSpacingX); + } + caret = null; + } + if (highlight != null) + { + if (flag) + { + flag = false; + highlight.Add(v2); + highlight.Add(v); + } + else if (start <= i && end > i) + { + highlight.Add(new Vector3(num2, 0f - num3 - num5)); + highlight.Add(new Vector3(num2, 0f - num3)); + highlight.Add(new Vector3(num2 + 2f, 0f - num3)); + highlight.Add(new Vector3(num2 + 2f, 0f - num3 - num5)); + } + if (alignment != Alignment.Left && num6 < highlight.size) + { + Align(highlight, num6, num2 - finalSpacingX); + num6 = highlight.size; + } + } + num9 -= num2; + num10 -= num2; + num11 -= finalLineHeight; + num12 -= finalLineHeight; + num2 = 0f; + num3 += finalLineHeight; + } + num2 += num8 + finalSpacingX; + if (highlight != null) + { + if (start > i || end <= i) + { + if (flag) + { + flag = false; + highlight.Add(v2); + highlight.Add(v); + } + } + else if (!flag) + { + flag = true; + highlight.Add(new Vector3(num9, num11)); + highlight.Add(new Vector3(num9, num12)); + } + } + v = new Vector2(num10, num11); + v2 = new Vector2(num10, num12); + prev = num7; + } + } + } + if (caret != null) + { + if (!flag2) + { + caret.Add(new Vector3(num2 - 1f, 0f - num3 - num5)); + caret.Add(new Vector3(num2 - 1f, 0f - num3)); + caret.Add(new Vector3(num2 + 1f, 0f - num3)); + caret.Add(new Vector3(num2 + 1f, 0f - num3 - num5)); + } + if (alignment != Alignment.Left) + { + Align(caret, indexOffset, num2 - finalSpacingX); + } + } + if (highlight != null) + { + if (flag) + { + highlight.Add(v2); + highlight.Add(v); + } + else if (start < i && end == i) + { + highlight.Add(new Vector3(num2, 0f - num3 - num5)); + highlight.Add(new Vector3(num2, 0f - num3)); + highlight.Add(new Vector3(num2 + 2f, 0f - num3)); + highlight.Add(new Vector3(num2 + 2f, 0f - num3 - num5)); + } + if (alignment != Alignment.Left && num6 < highlight.size) + { + Align(highlight, num6, num2 - finalSpacingX); + } + } + } +} diff --git a/NGUITools.cs b/NGUITools.cs new file mode 100644 index 00000000..6ed40f9f --- /dev/null +++ b/NGUITools.cs @@ -0,0 +1,1255 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using UnityEngine; + +public static class NGUITools +{ + private static AudioListener mListener; + + private static bool mLoaded = false; + + private static float mGlobalVolume = 1f; + + private static Vector3[] mSides = new Vector3[4]; + + public static float soundVolume + { + get + { + if (!mLoaded) + { + mLoaded = true; + mGlobalVolume = PlayerPrefs.GetFloat("Sound", 1f); + } + return mGlobalVolume; + } + set + { + if (mGlobalVolume != value) + { + mLoaded = true; + mGlobalVolume = value; + PlayerPrefs.SetFloat("Sound", value); + } + } + } + + public static bool fileAccess => Application.platform != RuntimePlatform.WindowsWebPlayer && Application.platform != RuntimePlatform.OSXWebPlayer; + + public static string clipboard + { + get + { + TextEditor textEditor = new TextEditor(); + textEditor.Paste(); + return textEditor.content.text; + } + set + { + TextEditor textEditor = new TextEditor(); + textEditor.content = new GUIContent(value); + textEditor.OnFocus(); + textEditor.Copy(); + } + } + + public static Vector2 screenSize => new Vector2((float)Screen.width, (float)Screen.height); + + public static AudioSource PlaySound(AudioClip clip) + { + return PlaySound(clip, 1f, 1f); + } + + public static AudioSource PlaySound(AudioClip clip, float volume) + { + return PlaySound(clip, volume, 1f); + } + + public static AudioSource PlaySound(AudioClip clip, float volume, float pitch) + { + volume *= soundVolume; + if (clip != null && volume > 0.01f) + { + if (mListener == null || !GetActive(mListener)) + { + AudioListener[] array = UnityEngine.Object.FindObjectsOfType(typeof(AudioListener)) as AudioListener[]; + if (array != null) + { + for (int i = 0; i < array.Length; i++) + { + if (GetActive(array[i])) + { + mListener = array[i]; + break; + } + } + } + if (mListener == null) + { + Camera camera = Camera.main; + if (camera == null) + { + camera = (UnityEngine.Object.FindObjectOfType(typeof(Camera)) as Camera); + } + if (camera != null) + { + mListener = camera.gameObject.AddComponent(); + } + } + } + if (mListener != null && mListener.enabled && GetActive(mListener.gameObject)) + { + AudioSource audioSource = mListener.GetComponent(); + if (audioSource == null) + { + audioSource = mListener.gameObject.AddComponent(); + } + audioSource.pitch = pitch; + audioSource.PlayOneShot(clip, volume); + return audioSource; + } + } + return null; + } + + public static int RandomRange(int min, int max) + { + if (min == max) + { + return min; + } + return UnityEngine.Random.Range(min, max + 1); + } + + public static string GetHierarchy(GameObject obj) + { + if (obj == null) + { + return string.Empty; + } + string text = obj.name; + while (obj.transform.parent != null) + { + obj = obj.transform.parent.gameObject; + text = obj.name + "\\" + text; + } + return text; + } + + public static T[] FindActive() where T : Component + { + return UnityEngine.Object.FindObjectsOfType(typeof(T)) as T[]; + } + + public static Camera FindCameraForLayer(int layer) + { + int num = 1 << layer; + Camera cachedCamera; + for (int i = 0; i < UICamera.list.size; i++) + { + cachedCamera = UICamera.list.buffer[i].cachedCamera; + if ((bool)cachedCamera && (cachedCamera.cullingMask & num) != 0) + { + return cachedCamera; + } + } + cachedCamera = Camera.main; + if ((bool)cachedCamera && (cachedCamera.cullingMask & num) != 0) + { + return cachedCamera; + } + Camera[] array = new Camera[Camera.allCamerasCount]; + int allCameras = Camera.GetAllCameras(array); + for (int j = 0; j < allCameras; j++) + { + cachedCamera = array[j]; + if ((bool)cachedCamera && cachedCamera.enabled && (cachedCamera.cullingMask & num) != 0) + { + return cachedCamera; + } + } + return null; + } + + public static void AddWidgetCollider(GameObject go) + { + AddWidgetCollider(go, considerInactive: false); + } + + public static void AddWidgetCollider(GameObject go, bool considerInactive) + { + if (go != null) + { + Collider component = go.GetComponent(); + BoxCollider boxCollider = component as BoxCollider; + if (boxCollider != null) + { + UpdateWidgetCollider(boxCollider, considerInactive); + } + else if (!(component != null)) + { + BoxCollider2D component2 = go.GetComponent(); + if (component2 != null) + { + UpdateWidgetCollider(component2, considerInactive); + } + else + { + UICamera uICamera = UICamera.FindCameraForLayer(go.layer); + if (uICamera != null && (uICamera.eventType == UICamera.EventType.World_2D || uICamera.eventType == UICamera.EventType.UI_2D)) + { + component2 = go.AddComponent(); + component2.isTrigger = true; + UIWidget component3 = go.GetComponent(); + if (component3 != null) + { + component3.autoResizeBoxCollider = true; + } + UpdateWidgetCollider(component2, considerInactive); + } + else + { + boxCollider = go.AddComponent(); + boxCollider.isTrigger = true; + UIWidget component4 = go.GetComponent(); + if (component4 != null) + { + component4.autoResizeBoxCollider = true; + } + UpdateWidgetCollider(boxCollider, considerInactive); + } + } + } + } + } + + public static void UpdateWidgetCollider(GameObject go) + { + UpdateWidgetCollider(go, considerInactive: false); + } + + public static void UpdateWidgetCollider(GameObject go, bool considerInactive) + { + if (go != null) + { + BoxCollider component = go.GetComponent(); + if (component != null) + { + UpdateWidgetCollider(component, considerInactive); + } + else + { + BoxCollider2D component2 = go.GetComponent(); + if (component2 != null) + { + UpdateWidgetCollider(component2, considerInactive); + } + } + } + } + + public static void UpdateWidgetCollider(BoxCollider box, bool considerInactive) + { + if (box != null) + { + GameObject gameObject = box.gameObject; + UIWidget component = gameObject.GetComponent(); + if (component != null) + { + Vector4 drawRegion = component.drawRegion; + if (drawRegion.x != 0f || drawRegion.y != 0f || drawRegion.z != 1f || drawRegion.w != 1f) + { + Vector4 drawingDimensions = component.drawingDimensions; + box.center = new Vector3((drawingDimensions.x + drawingDimensions.z) * 0.5f, (drawingDimensions.y + drawingDimensions.w) * 0.5f); + box.size = new Vector3(drawingDimensions.z - drawingDimensions.x, drawingDimensions.w - drawingDimensions.y); + } + else + { + Vector3[] localCorners = component.localCorners; + box.center = Vector3.Lerp(localCorners[0], localCorners[2], 0.5f); + box.size = localCorners[2] - localCorners[0]; + } + } + else + { + Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(gameObject.transform, considerInactive); + box.center = bounds.center; + Vector3 size = bounds.size; + float x = size.x; + Vector3 size2 = bounds.size; + box.size = new Vector3(x, size2.y, 0f); + } + } + } + + public static void UpdateWidgetCollider(BoxCollider2D box, bool considerInactive) + { + if (box != null) + { + GameObject gameObject = box.gameObject; + UIWidget component = gameObject.GetComponent(); + if (component != null) + { + Vector3[] localCorners = component.localCorners; + box.offset = Vector3.Lerp(localCorners[0], localCorners[2], 0.5f); + box.size = localCorners[2] - localCorners[0]; + } + else + { + Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(gameObject.transform, considerInactive); + box.offset = bounds.center; + Vector3 size = bounds.size; + float x = size.x; + Vector3 size2 = bounds.size; + box.size = new Vector2(x, size2.y); + } + } + } + + public static string GetTypeName() + { + string text = typeof(T).ToString(); + if (text.StartsWith("UI")) + { + text = text.Substring(2); + } + else if (text.StartsWith("UnityEngine.")) + { + text = text.Substring(12); + } + return text; + } + + public static string GetTypeName(UnityEngine.Object obj) + { + if (obj == null) + { + return "Null"; + } + string text = obj.GetType().ToString(); + if (text.StartsWith("UI")) + { + text = text.Substring(2); + } + else if (text.StartsWith("UnityEngine.")) + { + text = text.Substring(12); + } + return text; + } + + public static void RegisterUndo(UnityEngine.Object obj, string name) + { + } + + public static void SetDirty(UnityEngine.Object obj) + { + } + + public static GameObject AddChild(GameObject parent) + { + return AddChild(parent, undo: true); + } + + public static GameObject AddChild(GameObject parent, bool undo) + { + GameObject gameObject = new GameObject(); + if (parent != null) + { + Transform transform = gameObject.transform; + transform.parent = parent.transform; + transform.localPosition = Vector3.zero; + transform.localRotation = Quaternion.identity; + transform.localScale = Vector3.one; + gameObject.layer = parent.layer; + } + return gameObject; + } + + public static GameObject AddChild(GameObject parent, GameObject prefab) + { + GameObject gameObject = UnityEngine.Object.Instantiate(prefab); + if (gameObject != null && parent != null) + { + Transform transform = gameObject.transform; + transform.parent = parent.transform; + transform.localPosition = Vector3.zero; + transform.localRotation = Quaternion.identity; + transform.localScale = Vector3.one; + gameObject.layer = parent.layer; + } + return gameObject; + } + + public static int CalculateRaycastDepth(GameObject go) + { + UIWidget component = go.GetComponent(); + if (component != null) + { + return component.raycastDepth; + } + UIWidget[] componentsInChildren = go.GetComponentsInChildren(); + if (componentsInChildren.Length == 0) + { + return 0; + } + int num = 2147483647; + int i = 0; + for (int num2 = componentsInChildren.Length; i < num2; i++) + { + if (componentsInChildren[i].enabled) + { + num = Mathf.Min(num, componentsInChildren[i].raycastDepth); + } + } + return num; + } + + public static int CalculateNextDepth(GameObject go) + { + int num = -1; + UIWidget[] componentsInChildren = go.GetComponentsInChildren(); + int i = 0; + for (int num2 = componentsInChildren.Length; i < num2; i++) + { + num = Mathf.Max(num, componentsInChildren[i].depth); + } + return num + 1; + } + + public static int CalculateNextDepth(GameObject go, bool ignoreChildrenWithColliders) + { + if (ignoreChildrenWithColliders) + { + int num = -1; + UIWidget[] componentsInChildren = go.GetComponentsInChildren(); + int i = 0; + for (int num2 = componentsInChildren.Length; i < num2; i++) + { + UIWidget uIWidget = componentsInChildren[i]; + if (!(uIWidget.cachedGameObject != go) || (!(uIWidget.GetComponent() != null) && !(uIWidget.GetComponent() != null))) + { + num = Mathf.Max(num, uIWidget.depth); + } + } + return num + 1; + } + return CalculateNextDepth(go); + } + + public static int AdjustDepth(GameObject go, int adjustment) + { + if (go != null) + { + UIPanel component = go.GetComponent(); + if (component != null) + { + UIPanel[] componentsInChildren = go.GetComponentsInChildren(includeInactive: true); + foreach (UIPanel uIPanel in componentsInChildren) + { + uIPanel.depth += adjustment; + } + return 1; + } + component = FindInParents(go); + if (component == null) + { + return 0; + } + UIWidget[] componentsInChildren2 = go.GetComponentsInChildren(includeInactive: true); + int j = 0; + for (int num = componentsInChildren2.Length; j < num; j++) + { + UIWidget uIWidget = componentsInChildren2[j]; + if (!(uIWidget.panel != component)) + { + uIWidget.depth += adjustment; + } + } + return 2; + } + return 0; + } + + public static void BringForward(GameObject go) + { + switch (AdjustDepth(go, 1000)) + { + case 1: + NormalizePanelDepths(); + break; + case 2: + NormalizeWidgetDepths(); + break; + } + } + + public static void PushBack(GameObject go) + { + switch (AdjustDepth(go, -1000)) + { + case 1: + NormalizePanelDepths(); + break; + case 2: + NormalizeWidgetDepths(); + break; + } + } + + public static void NormalizeDepths() + { + NormalizeWidgetDepths(); + NormalizePanelDepths(); + } + + public static void NormalizeWidgetDepths() + { + NormalizeWidgetDepths(FindActive()); + } + + public static void NormalizeWidgetDepths(GameObject go) + { + NormalizeWidgetDepths(go.GetComponentsInChildren()); + } + + public static void NormalizeWidgetDepths(UIWidget[] list) + { + int num = list.Length; + if (num > 0) + { + Array.Sort(list, UIWidget.FullCompareFunc); + int num2 = 0; + int depth = list[0].depth; + for (int i = 0; i < num; i++) + { + UIWidget uIWidget = list[i]; + if (uIWidget.depth == depth) + { + uIWidget.depth = num2; + } + else + { + depth = uIWidget.depth; + num2 = (uIWidget.depth = num2 + 1); + } + } + } + } + + public static void NormalizePanelDepths() + { + UIPanel[] array = FindActive(); + int num = array.Length; + if (num > 0) + { + Array.Sort(array, UIPanel.CompareFunc); + int num2 = 0; + int depth = array[0].depth; + for (int i = 0; i < num; i++) + { + UIPanel uIPanel = array[i]; + if (uIPanel.depth == depth) + { + uIPanel.depth = num2; + } + else + { + depth = uIPanel.depth; + num2 = (uIPanel.depth = num2 + 1); + } + } + } + } + + public static UIPanel CreateUI(bool advanced3D) + { + return CreateUI(null, advanced3D, -1); + } + + public static UIPanel CreateUI(bool advanced3D, int layer) + { + return CreateUI(null, advanced3D, layer); + } + + public static UIPanel CreateUI(Transform trans, bool advanced3D, int layer) + { + UIRoot uIRoot = (!(trans != null)) ? null : FindInParents(trans.gameObject); + if (uIRoot == null && UIRoot.list.Count > 0) + { + foreach (UIRoot item in UIRoot.list) + { + if (item.gameObject.layer == layer) + { + uIRoot = item; + break; + } + } + } + if (uIRoot != null) + { + UICamera componentInChildren = uIRoot.GetComponentInChildren(); + if (componentInChildren != null && componentInChildren.GetComponent().orthographic == advanced3D) + { + trans = null; + uIRoot = null; + } + } + if (uIRoot == null) + { + GameObject gameObject = AddChild(null, undo: false); + uIRoot = gameObject.AddComponent(); + if (layer == -1) + { + layer = LayerMask.NameToLayer("UI"); + } + if (layer == -1) + { + layer = LayerMask.NameToLayer("2D UI"); + } + gameObject.layer = layer; + if (advanced3D) + { + gameObject.name = "UI Root (3D)"; + uIRoot.scalingStyle = UIRoot.Scaling.Constrained; + } + else + { + gameObject.name = "UI Root"; + uIRoot.scalingStyle = UIRoot.Scaling.Flexible; + } + } + UIPanel uIPanel = uIRoot.GetComponentInChildren(); + if (uIPanel == null) + { + Camera[] array = FindActive(); + float num = -1f; + bool flag = false; + int num2 = 1 << uIRoot.gameObject.layer; + foreach (Camera camera in array) + { + if (camera.clearFlags == CameraClearFlags.Color || camera.clearFlags == CameraClearFlags.Skybox) + { + flag = true; + } + num = Mathf.Max(num, camera.depth); + camera.cullingMask &= ~num2; + } + Camera camera2 = AddChild(uIRoot.gameObject, undo: false); + camera2.gameObject.AddComponent(); + camera2.clearFlags = ((!flag) ? CameraClearFlags.Color : CameraClearFlags.Depth); + camera2.backgroundColor = Color.grey; + camera2.cullingMask = num2; + camera2.depth = num + 1f; + if (advanced3D) + { + camera2.nearClipPlane = 0.1f; + camera2.farClipPlane = 4f; + camera2.transform.localPosition = new Vector3(0f, 0f, -700f); + } + else + { + camera2.orthographic = true; + camera2.orthographicSize = 1f; + camera2.nearClipPlane = -10f; + camera2.farClipPlane = 10f; + } + AudioListener[] array2 = FindActive(); + if (array2 == null || array2.Length == 0) + { + camera2.gameObject.AddComponent(); + } + uIPanel = uIRoot.gameObject.AddComponent(); + } + if (trans != null) + { + while (trans.parent != null) + { + trans = trans.parent; + } + if (IsChild(trans, uIPanel.transform)) + { + uIPanel = trans.gameObject.AddComponent(); + } + else + { + trans.parent = uIPanel.transform; + trans.localScale = Vector3.one; + trans.localPosition = Vector3.zero; + SetChildLayer(uIPanel.cachedTransform, uIPanel.cachedGameObject.layer); + } + } + return uIPanel; + } + + public static void SetChildLayer(Transform t, int layer) + { + for (int i = 0; i < t.childCount; i++) + { + Transform child = t.GetChild(i); + child.gameObject.layer = layer; + SetChildLayer(child, layer); + } + } + + public static T AddChild(GameObject parent) where T : Component + { + GameObject gameObject = AddChild(parent); + gameObject.name = GetTypeName(); + return gameObject.AddComponent(); + } + + public static T AddChild(GameObject parent, bool undo) where T : Component + { + GameObject gameObject = AddChild(parent, undo); + gameObject.name = GetTypeName(); + return gameObject.AddComponent(); + } + + public static T AddWidget(GameObject go) where T : UIWidget + { + int depth = CalculateNextDepth(go); + T result = AddChild(go); + result.width = 100; + result.height = 100; + result.depth = depth; + return result; + } + + public static UISprite AddSprite(GameObject go, UIAtlas atlas, string spriteName) + { + UISpriteData uISpriteData = (!(atlas != null)) ? null : atlas.GetSprite(spriteName); + UISprite uISprite = AddWidget(go); + uISprite.type = ((uISpriteData != null && uISpriteData.hasBorder) ? UIBasicSprite.Type.Sliced : UIBasicSprite.Type.Simple); + uISprite.atlas = atlas; + uISprite.spriteName = spriteName; + return uISprite; + } + + public static GameObject GetRoot(GameObject go) + { + Transform transform = go.transform; + while (true) + { + Transform parent = transform.parent; + if (parent == null) + { + break; + } + transform = parent; + } + return transform.gameObject; + } + + public static T FindInParents(GameObject go) where T : Component + { + if (go == null) + { + return (T)null; + } + T component = go.GetComponent(); + if ((UnityEngine.Object)component == (UnityEngine.Object)null) + { + Transform parent = go.transform.parent; + while (parent != null && (UnityEngine.Object)component == (UnityEngine.Object)null) + { + component = parent.gameObject.GetComponent(); + parent = parent.parent; + } + } + return component; + } + + public static T FindInParents(Transform trans) where T : Component + { + if (trans == null) + { + return (T)null; + } + return trans.GetComponentInParent(); + } + + public static void Destroy(UnityEngine.Object obj) + { + if (obj != null) + { + if (Application.isPlaying) + { + if (obj is GameObject) + { + GameObject gameObject = obj as GameObject; + gameObject.transform.parent = null; + } + UnityEngine.Object.Destroy(obj); + } + else + { + UnityEngine.Object.DestroyImmediate(obj); + } + } + } + + public static void DestroyImmediate(UnityEngine.Object obj) + { + if (obj != null) + { + if (Application.isEditor) + { + UnityEngine.Object.DestroyImmediate(obj); + } + else + { + UnityEngine.Object.Destroy(obj); + } + } + } + + public static void Broadcast(string funcName) + { + GameObject[] array = UnityEngine.Object.FindObjectsOfType(typeof(GameObject)) as GameObject[]; + int i = 0; + for (int num = array.Length; i < num; i++) + { + array[i].SendMessage(funcName, SendMessageOptions.DontRequireReceiver); + } + } + + public static void Broadcast(string funcName, object param) + { + GameObject[] array = UnityEngine.Object.FindObjectsOfType(typeof(GameObject)) as GameObject[]; + int i = 0; + for (int num = array.Length; i < num; i++) + { + array[i].SendMessage(funcName, param, SendMessageOptions.DontRequireReceiver); + } + } + + public static bool IsChild(Transform parent, Transform child) + { + if (parent == null || child == null) + { + return false; + } + while (child != null) + { + if (child == parent) + { + return true; + } + child = child.parent; + } + return false; + } + + private static void Activate(Transform t) + { + Activate(t, compatibilityMode: false); + } + + private static void Activate(Transform t, bool compatibilityMode) + { + SetActiveSelf(t.gameObject, state: true); + if (compatibilityMode) + { + int i = 0; + for (int childCount = t.childCount; i < childCount; i++) + { + Transform child = t.GetChild(i); + if (child.gameObject.activeSelf) + { + return; + } + } + int j = 0; + for (int childCount2 = t.childCount; j < childCount2; j++) + { + Transform child2 = t.GetChild(j); + Activate(child2, compatibilityMode: true); + } + } + } + + private static void Deactivate(Transform t) + { + SetActiveSelf(t.gameObject, state: false); + } + + public static void SetActive(GameObject go, bool state) + { + SetActive(go, state, compatibilityMode: true); + } + + public static void SetActive(GameObject go, bool state, bool compatibilityMode) + { + if ((bool)go) + { + if (state) + { + Activate(go.transform, compatibilityMode); + CallCreatePanel(go.transform); + } + else + { + Deactivate(go.transform); + } + } + } + + [DebuggerHidden] + [DebuggerStepThrough] + private static void CallCreatePanel(Transform t) + { + UIWidget component = t.GetComponent(); + if (component != null) + { + component.CreatePanel(); + } + int i = 0; + for (int childCount = t.childCount; i < childCount; i++) + { + CallCreatePanel(t.GetChild(i)); + } + } + + public static void SetActiveChildren(GameObject go, bool state) + { + Transform transform = go.transform; + if (state) + { + int i = 0; + for (int childCount = transform.childCount; i < childCount; i++) + { + Transform child = transform.GetChild(i); + Activate(child); + } + } + else + { + int j = 0; + for (int childCount2 = transform.childCount; j < childCount2; j++) + { + Transform child2 = transform.GetChild(j); + Deactivate(child2); + } + } + } + + [Obsolete("Use NGUITools.GetActive instead")] + public static bool IsActive(Behaviour mb) + { + return mb != null && mb.enabled && mb.gameObject.activeInHierarchy; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static bool GetActive(Behaviour mb) + { + return (bool)mb && mb.enabled && mb.gameObject.activeInHierarchy; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static bool GetActive(GameObject go) + { + return (bool)go && go.activeInHierarchy; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static void SetActiveSelf(GameObject go, bool state) + { + go.SetActive(state); + } + + public static void SetLayer(GameObject go, int layer) + { + go.layer = layer; + Transform transform = go.transform; + int i = 0; + for (int childCount = transform.childCount; i < childCount; i++) + { + Transform child = transform.GetChild(i); + SetLayer(child.gameObject, layer); + } + } + + public static Vector3 Round(Vector3 v) + { + v.x = Mathf.Round(v.x); + v.y = Mathf.Round(v.y); + v.z = Mathf.Round(v.z); + return v; + } + + public static void MakePixelPerfect(Transform t) + { + UIWidget component = t.GetComponent(); + if (component != null) + { + component.MakePixelPerfect(); + } + if (t.GetComponent() == null && t.GetComponent() == null) + { + t.localPosition = Round(t.localPosition); + t.localScale = Round(t.localScale); + } + int i = 0; + for (int childCount = t.childCount; i < childCount; i++) + { + MakePixelPerfect(t.GetChild(i)); + } + } + + public static bool Save(string fileName, byte[] bytes) + { + if (!fileAccess) + { + return false; + } + string path = Application.persistentDataPath + "/" + fileName; + if (bytes == null) + { + if (File.Exists(path)) + { + File.Delete(path); + } + return true; + } + FileStream fileStream = null; + try + { + fileStream = File.Create(path); + } + catch (Exception ex) + { + UnityEngine.Debug.LogError(ex.Message); + return false; + IL_0057:; + } + fileStream.Write(bytes, 0, bytes.Length); + fileStream.Close(); + return true; + } + + public static byte[] Load(string fileName) + { + if (!fileAccess) + { + return null; + } + string path = Application.persistentDataPath + "/" + fileName; + if (File.Exists(path)) + { + return File.ReadAllBytes(path); + } + return null; + } + + public static Color ApplyPMA(Color c) + { + if (c.a != 1f) + { + c.r *= c.a; + c.g *= c.a; + c.b *= c.a; + } + return c; + } + + public static void MarkParentAsChanged(GameObject go) + { + UIRect[] componentsInChildren = go.GetComponentsInChildren(); + int i = 0; + for (int num = componentsInChildren.Length; i < num; i++) + { + componentsInChildren[i].ParentHasChanged(); + } + } + + [Obsolete("Use NGUIText.EncodeColor instead")] + public static string EncodeColor(Color c) + { + return NGUIText.EncodeColor24(c); + } + + [Obsolete("Use NGUIText.ParseColor instead")] + public static Color ParseColor(string text, int offset) + { + return NGUIText.ParseColor24(text, offset); + } + + [Obsolete("Use NGUIText.StripSymbols instead")] + public static string StripSymbols(string text) + { + return NGUIText.StripSymbols(text); + } + + public static T AddMissingComponent(this GameObject go) where T : Component + { + T val = go.GetComponent(); + if ((UnityEngine.Object)val == (UnityEngine.Object)null) + { + val = go.AddComponent(); + } + return val; + } + + public static Vector3[] GetSides(this Camera cam) + { + return cam.GetSides(Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f), null); + } + + public static Vector3[] GetSides(this Camera cam, float depth) + { + return cam.GetSides(depth, null); + } + + public static Vector3[] GetSides(this Camera cam, Transform relativeTo) + { + return cam.GetSides(Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f), relativeTo); + } + + public static Vector3[] GetSides(this Camera cam, float depth, Transform relativeTo) + { + if (cam.orthographic) + { + float orthographicSize = cam.orthographicSize; + float num = 0f - orthographicSize; + float num2 = orthographicSize; + float y = 0f - orthographicSize; + float y2 = orthographicSize; + Rect rect = cam.rect; + Vector2 screenSize = NGUITools.screenSize; + float num3 = screenSize.x / screenSize.y; + num3 *= rect.width / rect.height; + num *= num3; + num2 *= num3; + Transform transform = cam.transform; + Quaternion rotation = transform.rotation; + Vector3 position = transform.position; + mSides[0] = rotation * new Vector3(num, 0f, depth) + position; + mSides[1] = rotation * new Vector3(0f, y2, depth) + position; + mSides[2] = rotation * new Vector3(num2, 0f, depth) + position; + mSides[3] = rotation * new Vector3(0f, y, depth) + position; + } + else + { + mSides[0] = cam.ViewportToWorldPoint(new Vector3(0f, 0.5f, depth)); + mSides[1] = cam.ViewportToWorldPoint(new Vector3(0.5f, 1f, depth)); + mSides[2] = cam.ViewportToWorldPoint(new Vector3(1f, 0.5f, depth)); + mSides[3] = cam.ViewportToWorldPoint(new Vector3(0.5f, 0f, depth)); + } + if (relativeTo != null) + { + for (int i = 0; i < 4; i++) + { + mSides[i] = relativeTo.InverseTransformPoint(mSides[i]); + } + } + return mSides; + } + + public static Vector3[] GetWorldCorners(this Camera cam) + { + float depth = Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f); + return cam.GetWorldCorners(depth, null); + } + + public static Vector3[] GetWorldCorners(this Camera cam, float depth) + { + return cam.GetWorldCorners(depth, null); + } + + public static Vector3[] GetWorldCorners(this Camera cam, Transform relativeTo) + { + return cam.GetWorldCorners(Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f), relativeTo); + } + + public static Vector3[] GetWorldCorners(this Camera cam, float depth, Transform relativeTo) + { + if (cam.orthographic) + { + float orthographicSize = cam.orthographicSize; + float num = 0f - orthographicSize; + float num2 = orthographicSize; + float y = 0f - orthographicSize; + float y2 = orthographicSize; + Rect rect = cam.rect; + Vector2 screenSize = NGUITools.screenSize; + float num3 = screenSize.x / screenSize.y; + num3 *= rect.width / rect.height; + num *= num3; + num2 *= num3; + Transform transform = cam.transform; + Quaternion rotation = transform.rotation; + Vector3 position = transform.position; + mSides[0] = rotation * new Vector3(num, y, depth) + position; + mSides[1] = rotation * new Vector3(num, y2, depth) + position; + mSides[2] = rotation * new Vector3(num2, y2, depth) + position; + mSides[3] = rotation * new Vector3(num2, y, depth) + position; + } + else + { + mSides[0] = cam.ViewportToWorldPoint(new Vector3(0f, 0f, depth)); + mSides[1] = cam.ViewportToWorldPoint(new Vector3(0f, 1f, depth)); + mSides[2] = cam.ViewportToWorldPoint(new Vector3(1f, 1f, depth)); + mSides[3] = cam.ViewportToWorldPoint(new Vector3(1f, 0f, depth)); + } + if (relativeTo != null) + { + for (int i = 0; i < 4; i++) + { + mSides[i] = relativeTo.InverseTransformPoint(mSides[i]); + } + } + return mSides; + } + + public static string GetFuncName(object obj, string method) + { + if (obj == null) + { + return ""; + } + string text = obj.GetType().ToString(); + int num = text.LastIndexOf('/'); + if (num > 0) + { + text = text.Substring(num + 1); + } + return (!string.IsNullOrEmpty(method)) ? (text + "/" + method) : text; + } + + public static void Execute(GameObject go, string funcName) where T : Component + { + T[] components = go.GetComponents(); + T[] array = components; + for (int i = 0; i < array.Length; i++) + { + T obj = array[i]; + obj.GetType().GetMethod(funcName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(obj, null); + } + } + + public static void ExecuteAll(GameObject root, string funcName) where T : Component + { + Execute(root, funcName); + Transform transform = root.transform; + int i = 0; + for (int childCount = transform.childCount; i < childCount; i++) + { + ExecuteAll(transform.GetChild(i).gameObject, funcName); + } + } + + public static void ImmediatelyCreateDrawCalls(GameObject root) + { + ExecuteAll(root, "Start"); + ExecuteAll(root, "Start"); + ExecuteAll(root, "Update"); + ExecuteAll(root, "Update"); + ExecuteAll(root, "LateUpdate"); + } +} diff --git a/Newtonsoft.Json.Bson/BsonArray.cs b/Newtonsoft.Json.Bson/BsonArray.cs new file mode 100644 index 00000000..57d65245 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonArray.cs @@ -0,0 +1,28 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Bson +{ + internal class BsonArray : BsonToken, IEnumerable, IEnumerable + { + private readonly List _children = new List(); + + public override BsonType Type => BsonType.Array; + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(BsonToken token) + { + _children.Add(token); + token.Parent = this; + } + + public IEnumerator GetEnumerator() + { + return _children.GetEnumerator(); + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonBinaryType.cs b/Newtonsoft.Json.Bson/BsonBinaryType.cs new file mode 100644 index 00000000..f4004334 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonBinaryType.cs @@ -0,0 +1,15 @@ +using System; + +namespace Newtonsoft.Json.Bson +{ + internal enum BsonBinaryType : byte + { + Binary = 0, + Function = 1, + [Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")] + Data = 2, + Uuid = 3, + Md5 = 5, + UserDefined = 0x80 + } +} diff --git a/Newtonsoft.Json.Bson/BsonBinaryWriter.cs b/Newtonsoft.Json.Bson/BsonBinaryWriter.cs new file mode 100644 index 00000000..051cebce --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonBinaryWriter.cs @@ -0,0 +1,285 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; +using System.IO; +using System.Text; + +namespace Newtonsoft.Json.Bson +{ + internal class BsonBinaryWriter + { + private static readonly Encoding Encoding = Encoding.UTF8; + + private readonly BinaryWriter _writer; + + private byte[] _largeByteBuffer; + + private int _maxChars; + + public DateTimeKind DateTimeKindHandling + { + get; + set; + } + + public BsonBinaryWriter(Stream stream) + { + DateTimeKindHandling = DateTimeKind.Utc; + _writer = new BinaryWriter(stream); + } + + public void Flush() + { + _writer.Flush(); + } + + public void Close() + { + _writer.Close(); + } + + public void WriteToken(BsonToken t) + { + CalculateSize(t); + WriteTokenInternal(t); + } + + private void WriteTokenInternal(BsonToken t) + { + switch (t.Type) + { + case BsonType.Undefined: + case BsonType.Null: + break; + case BsonType.Object: + { + BsonObject bsonObject = (BsonObject)t; + _writer.Write(bsonObject.CalculatedSize); + foreach (BsonProperty item in bsonObject) + { + _writer.Write((sbyte)item.Value.Type); + WriteString((string)item.Name.Value, item.Name.ByteCount, null); + WriteTokenInternal(item.Value); + } + _writer.Write((byte)0); + break; + } + case BsonType.Array: + { + BsonArray bsonArray = (BsonArray)t; + _writer.Write(bsonArray.CalculatedSize); + int num2 = 0; + foreach (BsonToken item2 in bsonArray) + { + _writer.Write((sbyte)item2.Type); + WriteString(num2.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(num2), null); + WriteTokenInternal(item2); + num2++; + } + _writer.Write((byte)0); + break; + } + case BsonType.Integer: + { + BsonValue bsonValue4 = (BsonValue)t; + _writer.Write(Convert.ToInt32(bsonValue4.Value, CultureInfo.InvariantCulture)); + break; + } + case BsonType.Long: + { + BsonValue bsonValue5 = (BsonValue)t; + _writer.Write(Convert.ToInt64(bsonValue5.Value, CultureInfo.InvariantCulture)); + break; + } + case BsonType.Number: + { + BsonValue bsonValue6 = (BsonValue)t; + _writer.Write(Convert.ToDouble(bsonValue6.Value, CultureInfo.InvariantCulture)); + break; + } + case BsonType.String: + { + BsonString bsonString = (BsonString)t; + WriteString((string)bsonString.Value, bsonString.ByteCount, bsonString.CalculatedSize - 4); + break; + } + case BsonType.Boolean: + { + BsonValue bsonValue7 = (BsonValue)t; + _writer.Write((bool)bsonValue7.Value); + break; + } + case BsonType.Date: + { + BsonValue bsonValue3 = (BsonValue)t; + long num = 0L; + if (bsonValue3.Value is DateTime) + { + DateTime dateTime = (DateTime)bsonValue3.Value; + if (DateTimeKindHandling == DateTimeKind.Utc) + { + dateTime = dateTime.ToUniversalTime(); + } + else if (DateTimeKindHandling == DateTimeKind.Local) + { + dateTime = dateTime.ToLocalTime(); + } + num = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime, convertToUtc: false); + } + else + { + DateTimeOffset dateTimeOffset = (DateTimeOffset)bsonValue3.Value; + num = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset); + } + _writer.Write(num); + break; + } + case BsonType.Binary: + { + BsonValue bsonValue2 = (BsonValue)t; + byte[] array = (byte[])bsonValue2.Value; + _writer.Write(array.Length); + _writer.Write((byte)0); + _writer.Write(array); + break; + } + case BsonType.Oid: + { + BsonValue bsonValue = (BsonValue)t; + byte[] buffer = (byte[])bsonValue.Value; + _writer.Write(buffer); + break; + } + case BsonType.Regex: + { + BsonRegex bsonRegex = (BsonRegex)t; + WriteString((string)bsonRegex.Pattern.Value, bsonRegex.Pattern.ByteCount, null); + WriteString((string)bsonRegex.Options.Value, bsonRegex.Options.ByteCount, null); + break; + } + default: + throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); + } + } + + private void WriteString(string s, int byteCount, int? calculatedlengthPrefix) + { + if (calculatedlengthPrefix.HasValue) + { + _writer.Write(calculatedlengthPrefix.Value); + } + if (s != null) + { + if (_largeByteBuffer == null) + { + _largeByteBuffer = new byte[256]; + _maxChars = 256 / Encoding.GetMaxByteCount(1); + } + if (byteCount <= 256) + { + Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0); + _writer.Write(_largeByteBuffer, 0, byteCount); + } + else + { + int num = 0; + int num3; + for (int num2 = s.Length; num2 > 0; num2 -= num3) + { + num3 = ((num2 <= _maxChars) ? num2 : _maxChars); + int bytes = Encoding.GetBytes(s, num, num3, _largeByteBuffer, 0); + _writer.Write(_largeByteBuffer, 0, bytes); + num += num3; + } + } + } + _writer.Write((byte)0); + } + + private int CalculateSize(int stringByteCount) + { + return stringByteCount + 1; + } + + private int CalculateSizeWithLength(int stringByteCount, bool includeSize) + { + int num = (!includeSize) ? 1 : 5; + return num + stringByteCount; + } + + private int CalculateSize(BsonToken t) + { + switch (t.Type) + { + case BsonType.Object: + { + BsonObject bsonObject = (BsonObject)t; + int num6 = 4; + foreach (BsonProperty item in bsonObject) + { + int num7 = 1; + num7 += CalculateSize(item.Name); + num7 += CalculateSize(item.Value); + num6 += num7; + } + return bsonObject.CalculatedSize = num6 + 1; + } + case BsonType.Array: + { + BsonArray bsonArray = (BsonArray)t; + int num3 = 4; + int num4 = 0; + foreach (BsonToken item2 in bsonArray) + { + num3++; + num3 += CalculateSize(MathUtils.IntLength(num4)); + num3 += CalculateSize(item2); + num4++; + } + num3 = (bsonArray.CalculatedSize = num3 + 1); + return bsonArray.CalculatedSize; + } + case BsonType.Integer: + return 4; + case BsonType.Long: + return 8; + case BsonType.Number: + return 8; + case BsonType.String: + { + BsonString bsonString = (BsonString)t; + string text = (string)bsonString.Value; + bsonString.ByteCount = ((text != null) ? Encoding.GetByteCount(text) : 0); + bsonString.CalculatedSize = CalculateSizeWithLength(bsonString.ByteCount, bsonString.IncludeLength); + return bsonString.CalculatedSize; + } + case BsonType.Boolean: + return 1; + case BsonType.Undefined: + case BsonType.Null: + return 0; + case BsonType.Date: + return 8; + case BsonType.Binary: + { + BsonValue bsonValue = (BsonValue)t; + byte[] array = (byte[])bsonValue.Value; + bsonValue.CalculatedSize = 5 + array.Length; + return bsonValue.CalculatedSize; + } + case BsonType.Oid: + return 12; + case BsonType.Regex: + { + BsonRegex bsonRegex = (BsonRegex)t; + int num = 0; + num += CalculateSize(bsonRegex.Pattern); + num = (bsonRegex.CalculatedSize = num + CalculateSize(bsonRegex.Options)); + return bsonRegex.CalculatedSize; + } + default: + throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); + } + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonObject.cs b/Newtonsoft.Json.Bson/BsonObject.cs new file mode 100644 index 00000000..636930d0 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonObject.cs @@ -0,0 +1,32 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Bson +{ + internal class BsonObject : BsonToken, IEnumerable, IEnumerable + { + private readonly List _children = new List(); + + public override BsonType Type => BsonType.Object; + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(string name, BsonToken token) + { + _children.Add(new BsonProperty + { + Name = new BsonString(name, includeLength: false), + Value = token + }); + token.Parent = this; + } + + public IEnumerator GetEnumerator() + { + return _children.GetEnumerator(); + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonObjectId.cs b/Newtonsoft.Json.Bson/BsonObjectId.cs new file mode 100644 index 00000000..f96e9fa6 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonObjectId.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json.Utilities; +using System; + +namespace Newtonsoft.Json.Bson +{ + public class BsonObjectId + { + public byte[] Value + { + get; + private set; + } + + public BsonObjectId(byte[] value) + { + ValidationUtils.ArgumentNotNull(value, "value"); + if (value.Length != 12) + { + throw new Exception("An ObjectId must be 12 bytes"); + } + Value = value; + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonProperty.cs b/Newtonsoft.Json.Bson/BsonProperty.cs new file mode 100644 index 00000000..d49f22d4 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonProperty.cs @@ -0,0 +1,17 @@ +namespace Newtonsoft.Json.Bson +{ + internal class BsonProperty + { + public BsonString Name + { + get; + set; + } + + public BsonToken Value + { + get; + set; + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonReader.cs b/Newtonsoft.Json.Bson/BsonReader.cs new file mode 100644 index 00000000..260b34c1 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonReader.cs @@ -0,0 +1,716 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; + +namespace Newtonsoft.Json.Bson +{ + public class BsonReader : JsonReader + { + private enum BsonReaderState + { + Normal, + ReferenceStart, + ReferenceRef, + ReferenceId, + CodeWScopeStart, + CodeWScopeCode, + CodeWScopeScope, + CodeWScopeScopeObject, + CodeWScopeScopeEnd + } + + private class ContainerContext + { + public readonly BsonType Type; + + public int Length; + + public int Position; + + public ContainerContext(BsonType type) + { + Type = type; + } + } + + private const int MaxCharBytesSize = 128; + + private static readonly byte[] _seqRange1 = new byte[2] + { + 0, + 127 + }; + + private static readonly byte[] _seqRange2 = new byte[2] + { + 194, + 223 + }; + + private static readonly byte[] _seqRange3 = new byte[2] + { + 224, + 239 + }; + + private static readonly byte[] _seqRange4 = new byte[2] + { + 240, + 244 + }; + + private readonly BinaryReader _reader; + + private readonly List _stack; + + private byte[] _byteBuffer; + + private char[] _charBuffer; + + private BsonType _currentElementType; + + private BsonReaderState _bsonReaderState; + + private ContainerContext _currentContext; + + private bool _readRootValueAsArray; + + private bool _jsonNet35BinaryCompatibility; + + private DateTimeKind _dateTimeKindHandling; + + public bool JsonNet35BinaryCompatibility + { + get + { + return _jsonNet35BinaryCompatibility; + } + set + { + _jsonNet35BinaryCompatibility = value; + } + } + + public bool ReadRootValueAsArray + { + get + { + return _readRootValueAsArray; + } + set + { + _readRootValueAsArray = value; + } + } + + public DateTimeKind DateTimeKindHandling + { + get + { + return _dateTimeKindHandling; + } + set + { + _dateTimeKindHandling = value; + } + } + + public BsonReader(Stream stream) + : this(stream, /*readRootValueAsArray:*/ false, DateTimeKind.Local) + { + } + + public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling) + { + ValidationUtils.ArgumentNotNull(stream, "stream"); + _reader = new BinaryReader(stream); + _stack = new List(); + _readRootValueAsArray = readRootValueAsArray; + _dateTimeKindHandling = dateTimeKindHandling; + } + + private string ReadElement() + { + _currentElementType = ReadType(); + return ReadString(); + } + + public override byte[] ReadAsBytes() + { + Read(); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Bytes) + { + return (byte[])Value; + } + throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + public override decimal? ReadAsDecimal() + { + Read(); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float) + { + SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture)); + return (decimal)Value; + } + throw new JsonReaderException("Error reading decimal. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + public override DateTimeOffset? ReadAsDateTimeOffset() + { + Read(); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Date) + { + SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value)); + return (DateTimeOffset)Value; + } + throw new JsonReaderException("Error reading date. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + public override bool Read() + { + try + { + switch (_bsonReaderState) + { + case BsonReaderState.Normal: + return ReadNormal(); + case BsonReaderState.ReferenceStart: + case BsonReaderState.ReferenceRef: + case BsonReaderState.ReferenceId: + return ReadReference(); + case BsonReaderState.CodeWScopeStart: + case BsonReaderState.CodeWScopeCode: + case BsonReaderState.CodeWScopeScope: + case BsonReaderState.CodeWScopeScopeObject: + case BsonReaderState.CodeWScopeScopeEnd: + return ReadCodeWScope(); + default: + throw new JsonReaderException("Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState)); + } + IL_0083: + bool result; + return result; + } + catch (EndOfStreamException) + { + return false; + IL_0090: + bool result; + return result; + } + } + + public override void Close() + { + base.Close(); + if (base.CloseInput && _reader != null) + { + _reader.Close(); + } + } + + private bool ReadCodeWScope() + { + switch (_bsonReaderState) + { + case BsonReaderState.CodeWScopeStart: + SetToken(JsonToken.PropertyName, "$code"); + _bsonReaderState = BsonReaderState.CodeWScopeCode; + return true; + case BsonReaderState.CodeWScopeCode: + ReadInt32(); + SetToken(JsonToken.String, ReadLengthString()); + _bsonReaderState = BsonReaderState.CodeWScopeScope; + return true; + case BsonReaderState.CodeWScopeScope: + { + if (base.CurrentState == State.PostValue) + { + SetToken(JsonToken.PropertyName, "$scope"); + return true; + } + SetToken(JsonToken.StartObject); + _bsonReaderState = BsonReaderState.CodeWScopeScopeObject; + ContainerContext containerContext = new ContainerContext(BsonType.Object); + PushContext(containerContext); + containerContext.Length = ReadInt32(); + return true; + } + case BsonReaderState.CodeWScopeScopeObject: + { + bool flag = ReadNormal(); + if (flag && TokenType == JsonToken.EndObject) + { + _bsonReaderState = BsonReaderState.CodeWScopeScopeEnd; + } + return flag; + } + case BsonReaderState.CodeWScopeScopeEnd: + SetToken(JsonToken.EndObject); + _bsonReaderState = BsonReaderState.Normal; + return true; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private bool ReadReference() + { + switch (base.CurrentState) + { + case State.ObjectStart: + SetToken(JsonToken.PropertyName, "$ref"); + _bsonReaderState = BsonReaderState.ReferenceRef; + return true; + case State.Property: + if (_bsonReaderState == BsonReaderState.ReferenceRef) + { + SetToken(JsonToken.String, ReadLengthString()); + return true; + } + if (_bsonReaderState == BsonReaderState.ReferenceId) + { + SetToken(JsonToken.Bytes, ReadBytes(12)); + return true; + } + throw new JsonReaderException("Unexpected state when reading BSON reference: " + _bsonReaderState); + case State.PostValue: + if (_bsonReaderState == BsonReaderState.ReferenceRef) + { + SetToken(JsonToken.PropertyName, "$id"); + _bsonReaderState = BsonReaderState.ReferenceId; + return true; + } + if (_bsonReaderState == BsonReaderState.ReferenceId) + { + SetToken(JsonToken.EndObject); + _bsonReaderState = BsonReaderState.Normal; + return true; + } + throw new JsonReaderException("Unexpected state when reading BSON reference: " + _bsonReaderState); + default: + throw new JsonReaderException("Unexpected state when reading BSON reference: " + base.CurrentState); + } + } + + private bool ReadNormal() + { + switch (base.CurrentState) + { + case State.Start: + { + JsonToken token2 = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray; + BsonType type = _readRootValueAsArray ? BsonType.Array : BsonType.Object; + SetToken(token2); + ContainerContext containerContext = new ContainerContext(type); + PushContext(containerContext); + containerContext.Length = ReadInt32(); + return true; + } + case State.Complete: + case State.Closed: + return false; + case State.Property: + ReadType(_currentElementType); + return true; + case State.ObjectStart: + case State.ArrayStart: + case State.PostValue: + { + ContainerContext currentContext = _currentContext; + if (currentContext == null) + { + return false; + } + int num = currentContext.Length - 1; + if (currentContext.Position < num) + { + if (currentContext.Type == BsonType.Array) + { + ReadElement(); + ReadType(_currentElementType); + return true; + } + SetToken(JsonToken.PropertyName, ReadElement()); + return true; + } + if (currentContext.Position == num) + { + if (ReadByte() != 0) + { + throw new JsonReaderException("Unexpected end of object byte value."); + } + PopContext(); + if (_currentContext != null) + { + MovePosition(currentContext.Length); + } + JsonToken token = (currentContext.Type != BsonType.Object) ? JsonToken.EndArray : JsonToken.EndObject; + SetToken(token); + return true; + } + throw new JsonReaderException("Read past end of current container context."); + } + default: + throw new ArgumentOutOfRangeException(); + case State.ConstructorStart: + case State.Constructor: + case State.Error: + case State.Finished: + return false; + } + } + + private void PopContext() + { + _stack.RemoveAt(_stack.Count - 1); + if (_stack.Count == 0) + { + _currentContext = null; + } + else + { + _currentContext = _stack[_stack.Count - 1]; + } + } + + private void PushContext(ContainerContext newContext) + { + _stack.Add(newContext); + _currentContext = newContext; + } + + private byte ReadByte() + { + MovePosition(1); + return _reader.ReadByte(); + } + + private void ReadType(BsonType type) + { + switch (type) + { + case BsonType.Number: + SetToken(JsonToken.Float, ReadDouble()); + break; + case BsonType.String: + case BsonType.Symbol: + SetToken(JsonToken.String, ReadLengthString()); + break; + case BsonType.Object: + { + SetToken(JsonToken.StartObject); + ContainerContext containerContext2 = new ContainerContext(BsonType.Object); + PushContext(containerContext2); + containerContext2.Length = ReadInt32(); + break; + } + case BsonType.Array: + { + SetToken(JsonToken.StartArray); + ContainerContext containerContext = new ContainerContext(BsonType.Array); + PushContext(containerContext); + containerContext.Length = ReadInt32(); + break; + } + case BsonType.Binary: + SetToken(JsonToken.Bytes, ReadBinary()); + break; + case BsonType.Undefined: + SetToken(JsonToken.Undefined); + break; + case BsonType.Oid: + { + byte[] value2 = ReadBytes(12); + SetToken(JsonToken.Bytes, value2); + break; + } + case BsonType.Boolean: + { + bool flag = Convert.ToBoolean(ReadByte()); + SetToken(JsonToken.Boolean, flag); + break; + } + case BsonType.Date: + { + long javaScriptTicks = ReadInt64(); + DateTime dateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks); + DateTime dateTime2; + switch (DateTimeKindHandling) + { + case DateTimeKind.Unspecified: + dateTime2 = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified); + break; + case DateTimeKind.Local: + dateTime2 = dateTime.ToLocalTime(); + break; + default: + dateTime2 = dateTime; + break; + } + SetToken(JsonToken.Date, dateTime2); + break; + } + case BsonType.Null: + SetToken(JsonToken.Null); + break; + case BsonType.Regex: + { + string str = ReadString(); + string str2 = ReadString(); + string value = "/" + str + "/" + str2; + SetToken(JsonToken.String, value); + break; + } + case BsonType.Reference: + SetToken(JsonToken.StartObject); + _bsonReaderState = BsonReaderState.ReferenceStart; + break; + case BsonType.Code: + SetToken(JsonToken.String, ReadLengthString()); + break; + case BsonType.CodeWScope: + SetToken(JsonToken.StartObject); + _bsonReaderState = BsonReaderState.CodeWScopeStart; + break; + case BsonType.Integer: + SetToken(JsonToken.Integer, (long)ReadInt32()); + break; + case BsonType.TimeStamp: + case BsonType.Long: + SetToken(JsonToken.Integer, ReadInt64()); + break; + default: + throw new ArgumentOutOfRangeException("type", "Unexpected BsonType value: " + type); + } + } + + private byte[] ReadBinary() + { + int count = ReadInt32(); + BsonBinaryType bsonBinaryType = (BsonBinaryType)ReadByte(); + if (bsonBinaryType == BsonBinaryType.Data && !_jsonNet35BinaryCompatibility) + { + count = ReadInt32(); + } + return ReadBytes(count); + } + + private string ReadString() + { + EnsureBuffers(); + StringBuilder stringBuilder = null; + int num = 0; + int num2 = 0; + while (true) + { + int num3 = num2; + byte b; + while (num3 < 128 && (b = _reader.ReadByte()) > 0) + { + _byteBuffer[num3++] = b; + } + int num5 = num3 - num2; + num += num5; + if (num3 < 128 && stringBuilder == null) + { + int chars = Encoding.UTF8.GetChars(_byteBuffer, 0, num5, _charBuffer, 0); + MovePosition(num + 1); + return new string(_charBuffer, 0, chars); + } + int lastFullCharStop = GetLastFullCharStop(num3 - 1); + int chars2 = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0); + if (stringBuilder == null) + { + stringBuilder = new StringBuilder(256); + } + stringBuilder.Append(_charBuffer, 0, chars2); + if (lastFullCharStop < num5 - 1) + { + num2 = num5 - lastFullCharStop - 1; + Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, num2); + } + else + { + if (num3 < 128) + { + break; + } + num2 = 0; + } + } + MovePosition(num + 1); + return stringBuilder.ToString(); + } + + private string ReadLengthString() + { + int num = ReadInt32(); + MovePosition(num); + string @string = GetString(num - 1); + _reader.ReadByte(); + return @string; + } + + private string GetString(int length) + { + if (length == 0) + { + return string.Empty; + } + EnsureBuffers(); + StringBuilder stringBuilder = null; + int num = 0; + int num2 = 0; + do + { + int count = (length - num <= 128 - num2) ? (length - num) : (128 - num2); + int num3 = _reader.BaseStream.Read(_byteBuffer, num2, count); + if (num3 == 0) + { + throw new EndOfStreamException("Unable to read beyond the end of the stream."); + } + num += num3; + num3 += num2; + if (num3 == length) + { + int chars = Encoding.UTF8.GetChars(_byteBuffer, 0, num3, _charBuffer, 0); + return new string(_charBuffer, 0, chars); + } + int lastFullCharStop = GetLastFullCharStop(num3 - 1); + if (stringBuilder == null) + { + stringBuilder = new StringBuilder(length); + } + int chars2 = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0); + stringBuilder.Append(_charBuffer, 0, chars2); + if (lastFullCharStop < num3 - 1) + { + num2 = num3 - lastFullCharStop - 1; + Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, num2); + } + else + { + num2 = 0; + } + } + while (num < length); + return stringBuilder.ToString(); + } + + private int GetLastFullCharStop(int start) + { + int num = start; + int num2 = 0; + while (num >= 0) + { + num2 = BytesInSequence(_byteBuffer[num]); + switch (num2) + { + case 0: + break; + default: + num--; + goto end_IL_003c; + case 1: + goto end_IL_003c; + } + num--; + continue; + continue; + end_IL_003c: + break; + } + if (num2 == start - num) + { + return start; + } + return num; + } + + private int BytesInSequence(byte b) + { + if (b <= _seqRange1[1]) + { + return 1; + } + if (b >= _seqRange2[0] && b <= _seqRange2[1]) + { + return 2; + } + if (b >= _seqRange3[0] && b <= _seqRange3[1]) + { + return 3; + } + if (b >= _seqRange4[0] && b <= _seqRange4[1]) + { + return 4; + } + return 0; + } + + private void EnsureBuffers() + { + if (_byteBuffer == null) + { + _byteBuffer = new byte[128]; + } + if (_charBuffer == null) + { + int maxCharCount = Encoding.UTF8.GetMaxCharCount(128); + _charBuffer = new char[maxCharCount]; + } + } + + private double ReadDouble() + { + MovePosition(8); + return _reader.ReadDouble(); + } + + private int ReadInt32() + { + MovePosition(4); + return _reader.ReadInt32(); + } + + private long ReadInt64() + { + MovePosition(8); + return _reader.ReadInt64(); + } + + private BsonType ReadType() + { + MovePosition(1); + return (BsonType)_reader.ReadSByte(); + } + + private void MovePosition(int count) + { + _currentContext.Position += count; + } + + private byte[] ReadBytes(int count) + { + MovePosition(count); + return _reader.ReadBytes(count); + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonRegex.cs b/Newtonsoft.Json.Bson/BsonRegex.cs new file mode 100644 index 00000000..95fdc634 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonRegex.cs @@ -0,0 +1,25 @@ +namespace Newtonsoft.Json.Bson +{ + internal class BsonRegex : BsonToken + { + public BsonString Pattern + { + get; + set; + } + + public BsonString Options + { + get; + set; + } + + public override BsonType Type => BsonType.Regex; + + public BsonRegex(string pattern, string options) + { + Pattern = new BsonString(pattern, includeLength: false); + Options = new BsonString(options, includeLength: false); + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonString.cs b/Newtonsoft.Json.Bson/BsonString.cs new file mode 100644 index 00000000..2721a993 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonString.cs @@ -0,0 +1,23 @@ +namespace Newtonsoft.Json.Bson +{ + internal class BsonString : BsonValue + { + public int ByteCount + { + get; + set; + } + + public bool IncludeLength + { + get; + set; + } + + public BsonString(object value, bool includeLength) + : base(value, BsonType.String) + { + IncludeLength = includeLength; + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonToken.cs b/Newtonsoft.Json.Bson/BsonToken.cs new file mode 100644 index 00000000..1ef41a56 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonToken.cs @@ -0,0 +1,22 @@ +namespace Newtonsoft.Json.Bson +{ + internal abstract class BsonToken + { + public abstract BsonType Type + { + get; + } + + public BsonToken Parent + { + get; + set; + } + + public int CalculatedSize + { + get; + set; + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonType.cs b/Newtonsoft.Json.Bson/BsonType.cs new file mode 100644 index 00000000..97725506 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonType.cs @@ -0,0 +1,26 @@ +namespace Newtonsoft.Json.Bson +{ + internal enum BsonType : sbyte + { + Number = 1, + String = 2, + Object = 3, + Array = 4, + Binary = 5, + Undefined = 6, + Oid = 7, + Boolean = 8, + Date = 9, + Null = 10, + Regex = 11, + Reference = 12, + Code = 13, + Symbol = 14, + CodeWScope = 0xF, + Integer = 0x10, + TimeStamp = 17, + Long = 18, + MinKey = -1, + MaxKey = sbyte.MaxValue + } +} diff --git a/Newtonsoft.Json.Bson/BsonValue.cs b/Newtonsoft.Json.Bson/BsonValue.cs new file mode 100644 index 00000000..e825e411 --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonValue.cs @@ -0,0 +1,19 @@ +namespace Newtonsoft.Json.Bson +{ + internal class BsonValue : BsonToken + { + private object _value; + + private BsonType _type; + + public object Value => _value; + + public override BsonType Type => _type; + + public BsonValue(object value, BsonType type) + { + _value = value; + _type = type; + } + } +} diff --git a/Newtonsoft.Json.Bson/BsonWriter.cs b/Newtonsoft.Json.Bson/BsonWriter.cs new file mode 100644 index 00000000..585bc06c --- /dev/null +++ b/Newtonsoft.Json.Bson/BsonWriter.cs @@ -0,0 +1,304 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; +using System.IO; + +namespace Newtonsoft.Json.Bson +{ + public class BsonWriter : JsonWriter + { + private readonly BsonBinaryWriter _writer; + + private BsonToken _root; + + private BsonToken _parent; + + private string _propertyName; + + public DateTimeKind DateTimeKindHandling + { + get + { + return _writer.DateTimeKindHandling; + } + set + { + _writer.DateTimeKindHandling = value; + } + } + + public BsonWriter(Stream stream) + { + ValidationUtils.ArgumentNotNull(stream, "stream"); + _writer = new BsonBinaryWriter(stream); + } + + public override void Flush() + { + _writer.Flush(); + } + + protected override void WriteEnd(JsonToken token) + { + base.WriteEnd(token); + RemoveParent(); + if (base.Top == 0) + { + _writer.WriteToken(_root); + } + } + + public override void WriteComment(string text) + { + throw new JsonWriterException("Cannot write JSON comment as BSON."); + } + + public override void WriteStartConstructor(string name) + { + throw new JsonWriterException("Cannot write JSON constructor as BSON."); + } + + public override void WriteRaw(string json) + { + throw new JsonWriterException("Cannot write raw JSON as BSON."); + } + + public override void WriteRawValue(string json) + { + throw new JsonWriterException("Cannot write raw JSON as BSON."); + } + + public override void WriteStartArray() + { + base.WriteStartArray(); + AddParent(new BsonArray()); + } + + public override void WriteStartObject() + { + base.WriteStartObject(); + AddParent(new BsonObject()); + } + + public override void WritePropertyName(string name) + { + base.WritePropertyName(name); + _propertyName = name; + } + + public override void Close() + { + base.Close(); + if (base.CloseOutput && _writer != null) + { + _writer.Close(); + } + } + + private void AddParent(BsonToken container) + { + AddToken(container); + _parent = container; + } + + private void RemoveParent() + { + _parent = _parent.Parent; + } + + private void AddValue(object value, BsonType type) + { + AddToken(new BsonValue(value, type)); + } + + internal void AddToken(BsonToken token) + { + if (_parent != null) + { + if (_parent is BsonObject) + { + ((BsonObject)_parent).Add(_propertyName, token); + _propertyName = null; + } + else + { + ((BsonArray)_parent).Add(token); + } + } + else + { + if (token.Type != BsonType.Object && token.Type != BsonType.Array) + { + throw new JsonWriterException("Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + } + _parent = token; + _root = token; + } + } + + public override void WriteNull() + { + base.WriteNull(); + AddValue(null, BsonType.Null); + } + + public override void WriteUndefined() + { + base.WriteUndefined(); + AddValue(null, BsonType.Undefined); + } + + public override void WriteValue(string value) + { + base.WriteValue(value); + if (value == null) + { + AddValue(null, BsonType.Null); + } + else + { + AddToken(new BsonString(value, includeLength: true)); + } + } + + public override void WriteValue(int value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } + + public override void WriteValue(uint value) + { + if (value > 2147483647) + { + throw new JsonWriterException("Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values."); + } + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } + + public override void WriteValue(long value) + { + base.WriteValue(value); + AddValue(value, BsonType.Long); + } + + public override void WriteValue(ulong value) + { + if (value > 9223372036854775807L) + { + throw new JsonWriterException("Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values."); + } + base.WriteValue(value); + AddValue(value, BsonType.Long); + } + + public override void WriteValue(float value) + { + base.WriteValue(value); + AddValue(value, BsonType.Number); + } + + public override void WriteValue(double value) + { + base.WriteValue(value); + AddValue(value, BsonType.Number); + } + + public override void WriteValue(bool value) + { + base.WriteValue(value); + AddValue(value, BsonType.Boolean); + } + + public override void WriteValue(short value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } + + public override void WriteValue(ushort value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } + + public override void WriteValue(char value) + { + base.WriteValue(value); + AddToken(new BsonString(value.ToString(), includeLength: true)); + } + + public override void WriteValue(byte value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } + + public override void WriteValue(sbyte value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } + + public override void WriteValue(decimal value) + { + base.WriteValue(value); + AddValue(value, BsonType.Number); + } + + public override void WriteValue(DateTime value) + { + base.WriteValue(value); + AddValue(value, BsonType.Date); + } + + public override void WriteValue(DateTimeOffset value) + { + base.WriteValue(value); + AddValue(value, BsonType.Date); + } + + public override void WriteValue(byte[] value) + { + base.WriteValue(value); + AddValue(value, BsonType.Binary); + } + + public override void WriteValue(Guid value) + { + base.WriteValue(value); + AddToken(new BsonString(value.ToString(), includeLength: true)); + } + + public override void WriteValue(TimeSpan value) + { + base.WriteValue(value); + AddToken(new BsonString(value.ToString(), includeLength: true)); + } + + public override void WriteValue(Uri value) + { + base.WriteValue(value); + AddToken(new BsonString(value.ToString(), includeLength: true)); + } + + public void WriteObjectId(byte[] value) + { + ValidationUtils.ArgumentNotNull(value, "value"); + if (value.Length != 12) + { + throw new Exception("An object id must be 12 bytes"); + } + AutoComplete(JsonToken.Undefined); + AddValue(value, BsonType.Oid); + } + + public void WriteRegex(string pattern, string options) + { + ValidationUtils.ArgumentNotNull(pattern, "pattern"); + AutoComplete(JsonToken.Undefined); + AddToken(new BsonRegex(pattern, options)); + } + } +} diff --git a/Newtonsoft.Json.Converters/BsonObjectIdConverter.cs b/Newtonsoft.Json.Converters/BsonObjectIdConverter.cs new file mode 100644 index 00000000..71682b3e --- /dev/null +++ b/Newtonsoft.Json.Converters/BsonObjectIdConverter.cs @@ -0,0 +1,39 @@ +using Newtonsoft.Json.Bson; +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; + +namespace Newtonsoft.Json.Converters +{ + public class BsonObjectIdConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + BsonObjectId bsonObjectId = (BsonObjectId)value; + BsonWriter bsonWriter = writer as BsonWriter; + if (bsonWriter != null) + { + bsonWriter.WriteObjectId(bsonObjectId.Value); + } + else + { + writer.WriteValue(bsonObjectId.Value); + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType != JsonToken.Bytes) + { + throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + byte[] value = (byte[])reader.Value; + return new BsonObjectId(value); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(BsonObjectId); + } + } +} diff --git a/Newtonsoft.Json.Converters/CustomCreationConverter.cs b/Newtonsoft.Json.Converters/CustomCreationConverter.cs new file mode 100644 index 00000000..b1a0d572 --- /dev/null +++ b/Newtonsoft.Json.Converters/CustomCreationConverter.cs @@ -0,0 +1,36 @@ +using System; + +namespace Newtonsoft.Json.Converters +{ + public abstract class CustomCreationConverter : JsonConverter + { + public override bool CanWrite => false; + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new NotSupportedException("CustomCreationConverter should only be used while deserializing."); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + { + return null; + } + T val = Create(objectType); + if (val == null) + { + throw new JsonSerializationException("No object created."); + } + serializer.Populate(reader, val); + return val; + } + + public abstract T Create(Type objectType); + + public override bool CanConvert(Type objectType) + { + return typeof(T).IsAssignableFrom(objectType); + } + } +} diff --git a/Newtonsoft.Json.Converters/DateTimeConverterBase.cs b/Newtonsoft.Json.Converters/DateTimeConverterBase.cs new file mode 100644 index 00000000..c68ab8da --- /dev/null +++ b/Newtonsoft.Json.Converters/DateTimeConverterBase.cs @@ -0,0 +1,20 @@ +using System; + +namespace Newtonsoft.Json.Converters +{ + public abstract class DateTimeConverterBase : JsonConverter + { + public override bool CanConvert(Type objectType) + { + if (objectType == typeof(DateTime) || objectType == typeof(DateTime?)) + { + return true; + } + if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?)) + { + return true; + } + return false; + } + } +} diff --git a/Newtonsoft.Json.Converters/IXmlDeclaration.cs b/Newtonsoft.Json.Converters/IXmlDeclaration.cs new file mode 100644 index 00000000..f532d27d --- /dev/null +++ b/Newtonsoft.Json.Converters/IXmlDeclaration.cs @@ -0,0 +1,22 @@ +namespace Newtonsoft.Json.Converters +{ + internal interface IXmlDeclaration : IXmlNode + { + string Version + { + get; + } + + string Encoding + { + get; + set; + } + + string Standalone + { + get; + set; + } + } +} diff --git a/Newtonsoft.Json.Converters/IXmlDocument.cs b/Newtonsoft.Json.Converters/IXmlDocument.cs new file mode 100644 index 00000000..177884e8 --- /dev/null +++ b/Newtonsoft.Json.Converters/IXmlDocument.cs @@ -0,0 +1,32 @@ +namespace Newtonsoft.Json.Converters +{ + internal interface IXmlDocument : IXmlNode + { + IXmlElement DocumentElement + { + get; + } + + IXmlNode CreateComment(string text); + + IXmlNode CreateTextNode(string text); + + IXmlNode CreateCDataSection(string data); + + IXmlNode CreateWhitespace(string text); + + IXmlNode CreateSignificantWhitespace(string text); + + IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone); + + IXmlNode CreateProcessingInstruction(string target, string data); + + IXmlElement CreateElement(string elementName); + + IXmlElement CreateElement(string qualifiedName, string namespaceURI); + + IXmlNode CreateAttribute(string name, string value); + + IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value); + } +} diff --git a/Newtonsoft.Json.Converters/IXmlElement.cs b/Newtonsoft.Json.Converters/IXmlElement.cs new file mode 100644 index 00000000..0d56f0b4 --- /dev/null +++ b/Newtonsoft.Json.Converters/IXmlElement.cs @@ -0,0 +1,9 @@ +namespace Newtonsoft.Json.Converters +{ + internal interface IXmlElement : IXmlNode + { + void SetAttributeNode(IXmlNode attribute); + + string GetPrefixOfNamespace(string namespaceURI); + } +} diff --git a/Newtonsoft.Json.Converters/IXmlNode.cs b/Newtonsoft.Json.Converters/IXmlNode.cs new file mode 100644 index 00000000..2f44d778 --- /dev/null +++ b/Newtonsoft.Json.Converters/IXmlNode.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Xml; + +namespace Newtonsoft.Json.Converters +{ + internal interface IXmlNode + { + XmlNodeType NodeType + { + get; + } + + string LocalName + { + get; + } + + IList ChildNodes + { + get; + } + + IList Attributes + { + get; + } + + IXmlNode ParentNode + { + get; + } + + string Value + { + get; + set; + } + + string NamespaceURI + { + get; + } + + object WrappedNode + { + get; + } + + IXmlNode AppendChild(IXmlNode newChild); + } +} diff --git a/Newtonsoft.Json.Converters/IsoDateTimeConverter.cs b/Newtonsoft.Json.Converters/IsoDateTimeConverter.cs new file mode 100644 index 00000000..542d7eb6 --- /dev/null +++ b/Newtonsoft.Json.Converters/IsoDateTimeConverter.cs @@ -0,0 +1,117 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; + +namespace Newtonsoft.Json.Converters +{ + public class IsoDateTimeConverter : DateTimeConverterBase + { + private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; + + private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; + + private string _dateTimeFormat; + + private CultureInfo _culture; + + public DateTimeStyles DateTimeStyles + { + get + { + return _dateTimeStyles; + } + set + { + _dateTimeStyles = value; + } + } + + public string DateTimeFormat + { + get + { + return _dateTimeFormat ?? string.Empty; + } + set + { + _dateTimeFormat = StringUtils.NullEmptyString(value); + } + } + + public CultureInfo Culture + { + get + { + return _culture ?? CultureInfo.CurrentCulture; + } + set + { + _culture = value; + } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + string value2; + if (value is DateTime) + { + DateTime dateTime = (DateTime)value; + if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) + { + dateTime = dateTime.ToUniversalTime(); + } + value2 = dateTime.ToString(_dateTimeFormat ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK", Culture); + } + else + { + if (!(value is DateTimeOffset)) + { + throw new Exception("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value))); + } + DateTimeOffset dateTimeOffset = (DateTimeOffset)value; + if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) + { + dateTimeOffset = dateTimeOffset.ToUniversalTime(); + } + value2 = dateTimeOffset.ToString(_dateTimeFormat ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK", Culture); + } + writer.WriteValue(value2); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + bool flag = ReflectionUtils.IsNullableType(objectType); + Type type = (!flag) ? objectType : Nullable.GetUnderlyingType(objectType); + if (reader.TokenType == JsonToken.Null) + { + if (!ReflectionUtils.IsNullableType(objectType)) + { + throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + return null; + } + if (reader.TokenType != JsonToken.String) + { + throw new Exception("Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + string text = reader.Value.ToString(); + if (string.IsNullOrEmpty(text) && flag) + { + return null; + } + if (type == typeof(DateTimeOffset)) + { + if (!string.IsNullOrEmpty(_dateTimeFormat)) + { + return DateTimeOffset.ParseExact(text, _dateTimeFormat, Culture, _dateTimeStyles); + } + return DateTimeOffset.Parse(text, Culture, _dateTimeStyles); + } + if (!string.IsNullOrEmpty(_dateTimeFormat)) + { + return DateTime.ParseExact(text, _dateTimeFormat, Culture, _dateTimeStyles); + } + return DateTime.Parse(text, Culture, _dateTimeStyles); + } + } +} diff --git a/Newtonsoft.Json.Converters/JavaScriptDateTimeConverter.cs b/Newtonsoft.Json.Converters/JavaScriptDateTimeConverter.cs new file mode 100644 index 00000000..3e4b2a52 --- /dev/null +++ b/Newtonsoft.Json.Converters/JavaScriptDateTimeConverter.cs @@ -0,0 +1,64 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; + +namespace Newtonsoft.Json.Converters +{ + public class JavaScriptDateTimeConverter : DateTimeConverterBase + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + long value2; + if (value is DateTime) + { + DateTime dateTime = ((DateTime)value).ToUniversalTime(); + value2 = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime); + } + else + { + if (!(value is DateTimeOffset)) + { + throw new Exception("Expected date object value."); + } + value2 = JsonConvert.ConvertDateTimeToJavaScriptTicks(((DateTimeOffset)value).ToUniversalTime().UtcDateTime); + } + writer.WriteStartConstructor("Date"); + writer.WriteValue(value2); + writer.WriteEndConstructor(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + Type type = (!ReflectionUtils.IsNullableType(objectType)) ? objectType : Nullable.GetUnderlyingType(objectType); + if (reader.TokenType == JsonToken.Null) + { + if (!ReflectionUtils.IsNullableType(objectType)) + { + throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + return null; + } + if (reader.TokenType != JsonToken.StartConstructor || string.Compare(reader.Value.ToString(), "Date", StringComparison.Ordinal) != 0) + { + throw new Exception("Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value)); + } + reader.Read(); + if (reader.TokenType != JsonToken.Integer) + { + throw new Exception("Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + long javaScriptTicks = (long)reader.Value; + DateTime dateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks); + reader.Read(); + if (reader.TokenType != JsonToken.EndConstructor) + { + throw new Exception("Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + if (type == typeof(DateTimeOffset)) + { + return new DateTimeOffset(dateTime); + } + return dateTime; + } + } +} diff --git a/Newtonsoft.Json.Converters/JsonDateTimeSerializationMode.cs b/Newtonsoft.Json.Converters/JsonDateTimeSerializationMode.cs new file mode 100644 index 00000000..b120c62a --- /dev/null +++ b/Newtonsoft.Json.Converters/JsonDateTimeSerializationMode.cs @@ -0,0 +1,10 @@ +namespace Newtonsoft.Json.Converters +{ + public enum JsonDateTimeSerializationMode + { + Local, + Utc, + Unspecified, + RoundtripKind + } +} diff --git a/Newtonsoft.Json.Converters/KeyValuePairConverter.cs b/Newtonsoft.Json.Converters/KeyValuePairConverter.cs new file mode 100644 index 00000000..3510c75b --- /dev/null +++ b/Newtonsoft.Json.Converters/KeyValuePairConverter.cs @@ -0,0 +1,47 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Newtonsoft.Json.Converters +{ + public class KeyValuePairConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + Type type = value.GetType(); + PropertyInfo property = type.GetProperty("Key"); + PropertyInfo property2 = type.GetProperty("Value"); + writer.WriteStartObject(); + writer.WritePropertyName("Key"); + serializer.Serialize(writer, ReflectionUtils.GetMemberValue(property, value)); + writer.WritePropertyName("Value"); + serializer.Serialize(writer, ReflectionUtils.GetMemberValue(property2, value)); + writer.WriteEndObject(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + IList genericArguments = objectType.GetGenericArguments(); + Type objectType2 = genericArguments[0]; + Type objectType3 = genericArguments[1]; + reader.Read(); + reader.Read(); + object obj = serializer.Deserialize(reader, objectType2); + reader.Read(); + reader.Read(); + object obj2 = serializer.Deserialize(reader, objectType3); + reader.Read(); + return ReflectionUtils.CreateInstance(objectType, obj, obj2); + } + + public override bool CanConvert(Type objectType) + { + if (objectType.IsValueType && objectType.IsGenericType) + { + return objectType.GetGenericTypeDefinition() == typeof(KeyValuePair<, >); + } + return false; + } + } +} diff --git a/Newtonsoft.Json.Converters/RegexConverter.cs b/Newtonsoft.Json.Converters/RegexConverter.cs new file mode 100644 index 00000000..da7159d9 --- /dev/null +++ b/Newtonsoft.Json.Converters/RegexConverter.cs @@ -0,0 +1,118 @@ +using Newtonsoft.Json.Bson; +using System; +using System.Globalization; +using System.Text.RegularExpressions; + +namespace Newtonsoft.Json.Converters +{ + public class RegexConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + Regex regex = (Regex)value; + BsonWriter bsonWriter = writer as BsonWriter; + if (bsonWriter != null) + { + WriteBson(bsonWriter, regex); + } + else + { + WriteJson(writer, regex); + } + } + + private bool HasFlag(RegexOptions options, RegexOptions flag) + { + return (options & flag) == flag; + } + + private void WriteBson(BsonWriter writer, Regex regex) + { + string str = null; + if (HasFlag(regex.Options, RegexOptions.IgnoreCase)) + { + str += "i"; + } + if (HasFlag(regex.Options, RegexOptions.Multiline)) + { + str += "m"; + } + if (HasFlag(regex.Options, RegexOptions.Singleline)) + { + str += "s"; + } + str += "u"; + if (HasFlag(regex.Options, RegexOptions.ExplicitCapture)) + { + str += "x"; + } + writer.WriteRegex(regex.ToString(), str); + } + + private void WriteJson(JsonWriter writer, Regex regex) + { + writer.WriteStartObject(); + writer.WritePropertyName("Pattern"); + writer.WriteValue(regex.ToString()); + writer.WritePropertyName("Options"); + writer.WriteValue(regex.Options); + writer.WriteEndObject(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + BsonReader bsonReader = reader as BsonReader; + if (bsonReader != null) + { + return ReadBson(bsonReader); + } + return ReadJson(reader); + } + + private object ReadBson(BsonReader reader) + { + string text = (string)reader.Value; + int num = text.LastIndexOf("/"); + string pattern = text.Substring(1, num - 1); + string text2 = text.Substring(num + 1); + RegexOptions regexOptions = RegexOptions.None; + string text3 = text2; + for (int i = 0; i < text3.Length; i++) + { + switch (text3[i]) + { + case 'i': + regexOptions |= RegexOptions.IgnoreCase; + break; + case 'm': + regexOptions |= RegexOptions.Multiline; + break; + case 's': + regexOptions |= RegexOptions.Singleline; + break; + case 'x': + regexOptions |= RegexOptions.ExplicitCapture; + break; + } + } + return new Regex(pattern, regexOptions); + } + + private Regex ReadJson(JsonReader reader) + { + reader.Read(); + reader.Read(); + string pattern = (string)reader.Value; + reader.Read(); + reader.Read(); + int options = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture); + reader.Read(); + return new Regex(pattern, (RegexOptions)options); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(Regex); + } + } +} diff --git a/Newtonsoft.Json.Converters/StringEnumConverter.cs b/Newtonsoft.Json.Converters/StringEnumConverter.cs new file mode 100644 index 00000000..e66997fe --- /dev/null +++ b/Newtonsoft.Json.Converters/StringEnumConverter.cs @@ -0,0 +1,110 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Converters +{ + public class StringEnumConverter : JsonConverter + { + private readonly Dictionary> _enumMemberNamesPerType = new Dictionary>(); + + public bool CamelCaseText + { + get; + set; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + } + else + { + Enum @enum = (Enum)value; + string text = @enum.ToString("G"); + if (char.IsNumber(text[0]) || text[0] == '-') + { + writer.WriteValue(value); + } + else + { + BidirectionalDictionary enumNameMap = GetEnumNameMap(@enum.GetType()); + enumNameMap.TryGetByFirst(text, out string second); + second = (second ?? text); + if (CamelCaseText) + { + second = StringUtils.ToCamelCase(second); + } + writer.WriteValue(second); + } + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + Type type = (!ReflectionUtils.IsNullableType(objectType)) ? objectType : Nullable.GetUnderlyingType(objectType); + if (reader.TokenType == JsonToken.Null) + { + if (!ReflectionUtils.IsNullableType(objectType)) + { + throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + return null; + } + if (reader.TokenType == JsonToken.String) + { + BidirectionalDictionary enumNameMap = GetEnumNameMap(type); + enumNameMap.TryGetBySecond(reader.Value.ToString(), out string first); + first = (first ?? reader.Value.ToString()); + return Enum.Parse(type, first, ignoreCase: true); + } + if (reader.TokenType == JsonToken.Integer) + { + return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, type); + } + throw new Exception("Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + + private BidirectionalDictionary GetEnumNameMap(Type t) + { + if (!_enumMemberNamesPerType.TryGetValue(t, out BidirectionalDictionary value)) + { + lock (_enumMemberNamesPerType) + { + if (_enumMemberNamesPerType.TryGetValue(t, out value)) + { + return value; + } + value = new BidirectionalDictionary(StringComparer.OrdinalIgnoreCase, StringComparer.OrdinalIgnoreCase); + FieldInfo[] fields = t.GetFields(); + foreach (FieldInfo fieldInfo in fields) + { + string name = fieldInfo.Name; + string text = (from EnumMemberAttribute a in fieldInfo.GetCustomAttributes(typeof(EnumMemberAttribute), inherit: true) + select a.Value).SingleOrDefault() ?? fieldInfo.Name; + if (value.TryGetBySecond(text, out string _)) + { + throw new Exception("Enum name '{0}' already exists on enum '{1}'.".FormatWith(CultureInfo.InvariantCulture, text, t.Name)); + } + value.Add(name, text); + } + _enumMemberNamesPerType[t] = value; + return value; + } + } + return value; + } + + public override bool CanConvert(Type objectType) + { + Type type = (!ReflectionUtils.IsNullableType(objectType)) ? objectType : Nullable.GetUnderlyingType(objectType); + return type.IsEnum; + } + } +} diff --git a/Newtonsoft.Json.Converters/XmlDeclarationWrapper.cs b/Newtonsoft.Json.Converters/XmlDeclarationWrapper.cs new file mode 100644 index 00000000..29446a23 --- /dev/null +++ b/Newtonsoft.Json.Converters/XmlDeclarationWrapper.cs @@ -0,0 +1,41 @@ +using System.Xml; + +namespace Newtonsoft.Json.Converters +{ + internal class XmlDeclarationWrapper : XmlNodeWrapper, IXmlDeclaration, IXmlNode + { + private XmlDeclaration _declaration; + + public string Version => _declaration.Version; + + public string Encoding + { + get + { + return _declaration.Encoding; + } + set + { + _declaration.Encoding = value; + } + } + + public string Standalone + { + get + { + return _declaration.Standalone; + } + set + { + _declaration.Standalone = value; + } + } + + public XmlDeclarationWrapper(XmlDeclaration declaration) + : base(declaration) + { + _declaration = declaration; + } + } +} diff --git a/Newtonsoft.Json.Converters/XmlDocumentWrapper.cs b/Newtonsoft.Json.Converters/XmlDocumentWrapper.cs new file mode 100644 index 00000000..e0deb151 --- /dev/null +++ b/Newtonsoft.Json.Converters/XmlDocumentWrapper.cs @@ -0,0 +1,86 @@ +using System.Xml; + +namespace Newtonsoft.Json.Converters +{ + internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument, IXmlNode + { + private XmlDocument _document; + + public IXmlElement DocumentElement + { + get + { + if (_document.DocumentElement == null) + { + return null; + } + return new XmlElementWrapper(_document.DocumentElement); + } + } + + public XmlDocumentWrapper(XmlDocument document) + : base(document) + { + _document = document; + } + + public IXmlNode CreateComment(string data) + { + return new XmlNodeWrapper(_document.CreateComment(data)); + } + + public IXmlNode CreateTextNode(string text) + { + return new XmlNodeWrapper(_document.CreateTextNode(text)); + } + + public IXmlNode CreateCDataSection(string data) + { + return new XmlNodeWrapper(_document.CreateCDataSection(data)); + } + + public IXmlNode CreateWhitespace(string text) + { + return new XmlNodeWrapper(_document.CreateWhitespace(text)); + } + + public IXmlNode CreateSignificantWhitespace(string text) + { + return new XmlNodeWrapper(_document.CreateSignificantWhitespace(text)); + } + + public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone) + { + return new XmlNodeWrapper(_document.CreateXmlDeclaration(version, encoding, standalone)); + } + + public IXmlNode CreateProcessingInstruction(string target, string data) + { + return new XmlNodeWrapper(_document.CreateProcessingInstruction(target, data)); + } + + public IXmlElement CreateElement(string elementName) + { + return new XmlElementWrapper(_document.CreateElement(elementName)); + } + + public IXmlElement CreateElement(string qualifiedName, string namespaceURI) + { + return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceURI)); + } + + public IXmlNode CreateAttribute(string name, string value) + { + XmlNodeWrapper xmlNodeWrapper = new XmlNodeWrapper(_document.CreateAttribute(name)); + xmlNodeWrapper.Value = value; + return xmlNodeWrapper; + } + + public IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value) + { + XmlNodeWrapper xmlNodeWrapper = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceURI)); + xmlNodeWrapper.Value = value; + return xmlNodeWrapper; + } + } +} diff --git a/Newtonsoft.Json.Converters/XmlElementWrapper.cs b/Newtonsoft.Json.Converters/XmlElementWrapper.cs new file mode 100644 index 00000000..07e36861 --- /dev/null +++ b/Newtonsoft.Json.Converters/XmlElementWrapper.cs @@ -0,0 +1,26 @@ +using System.Xml; + +namespace Newtonsoft.Json.Converters +{ + internal class XmlElementWrapper : XmlNodeWrapper, IXmlElement, IXmlNode + { + private XmlElement _element; + + public XmlElementWrapper(XmlElement element) + : base(element) + { + _element = element; + } + + public void SetAttributeNode(IXmlNode attribute) + { + XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper)attribute; + _element.SetAttributeNode((XmlAttribute)xmlNodeWrapper.WrappedNode); + } + + public string GetPrefixOfNamespace(string namespaceURI) + { + return _element.GetPrefixOfNamespace(namespaceURI); + } + } +} diff --git a/Newtonsoft.Json.Converters/XmlNodeConverter.cs b/Newtonsoft.Json.Converters/XmlNodeConverter.cs new file mode 100644 index 00000000..5baeb22b --- /dev/null +++ b/Newtonsoft.Json.Converters/XmlNodeConverter.cs @@ -0,0 +1,655 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; + +namespace Newtonsoft.Json.Converters +{ + public class XmlNodeConverter : JsonConverter + { + private const string TextName = "#text"; + + private const string CommentName = "#comment"; + + private const string CDataName = "#cdata-section"; + + private const string WhitespaceName = "#whitespace"; + + private const string SignificantWhitespaceName = "#significant-whitespace"; + + private const string DeclarationName = "?xml"; + + private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json"; + + public string DeserializeRootElementName + { + get; + set; + } + + public bool WriteArrayAttribute + { + get; + set; + } + + public bool OmitRootObject + { + get; + set; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + IXmlNode node = WrapXml(value); + XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); + PushParentNamespaces(node, manager); + if (!OmitRootObject) + { + writer.WriteStartObject(); + } + SerializeNode(writer, node, manager, !OmitRootObject); + if (!OmitRootObject) + { + writer.WriteEndObject(); + } + } + + private IXmlNode WrapXml(object value) + { + if (value is XmlNode) + { + return new XmlNodeWrapper((XmlNode)value); + } + throw new ArgumentException("Value must be an XML object.", "value"); + } + + private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager) + { + List list = null; + IXmlNode xmlNode = node; + while ((xmlNode = xmlNode.ParentNode) != null) + { + if (xmlNode.NodeType == XmlNodeType.Element) + { + if (list == null) + { + list = new List(); + } + list.Add(xmlNode); + } + } + if (list != null) + { + list.Reverse(); + foreach (IXmlNode item in list) + { + manager.PushScope(); + foreach (IXmlNode attribute in item.Attributes) + { + if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns") + { + manager.AddNamespace(attribute.LocalName, attribute.Value); + } + } + } + } + } + + private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager) + { + string text = (node.NamespaceURI != null && (!(node.LocalName == "xmlns") || !(node.NamespaceURI == "http://www.w3.org/2000/xmlns/"))) ? manager.LookupPrefix(node.NamespaceURI) : null; + if (!string.IsNullOrEmpty(text)) + { + return text + ":" + node.LocalName; + } + return node.LocalName; + } + + private string GetPropertyName(IXmlNode node, XmlNamespaceManager manager) + { + switch (node.NodeType) + { + case XmlNodeType.Attribute: + if (node.NamespaceURI == "http://james.newtonking.com/projects/json") + { + return "$" + node.LocalName; + } + return "@" + ResolveFullName(node, manager); + case XmlNodeType.CDATA: + return "#cdata-section"; + case XmlNodeType.Comment: + return "#comment"; + case XmlNodeType.Element: + return ResolveFullName(node, manager); + case XmlNodeType.ProcessingInstruction: + return "?" + ResolveFullName(node, manager); + case XmlNodeType.XmlDeclaration: + return "?xml"; + case XmlNodeType.SignificantWhitespace: + return "#significant-whitespace"; + case XmlNodeType.Text: + return "#text"; + case XmlNodeType.Whitespace: + return "#whitespace"; + default: + throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType); + } + } + + private bool IsArray(IXmlNode node) + { + object obj; + if (node.Attributes != null) + { + IXmlNode xmlNode = node.Attributes.SingleOrDefault((IXmlNode a) => a.LocalName == "Array" && a.NamespaceURI == "http://james.newtonking.com/projects/json"); + obj = xmlNode; + } + else + { + obj = null; + } + IXmlNode xmlNode2 = (IXmlNode)obj; + return xmlNode2 != null && XmlConvert.ToBoolean(xmlNode2.Value); + } + + private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName) + { + Dictionary> dictionary = new Dictionary>(); + for (int i = 0; i < node.ChildNodes.Count; i++) + { + IXmlNode xmlNode = node.ChildNodes[i]; + string propertyName = GetPropertyName(xmlNode, manager); + if (!dictionary.TryGetValue(propertyName, out List value)) + { + value = new List(); + dictionary.Add(propertyName, value); + } + value.Add(xmlNode); + } + foreach (KeyValuePair> item in dictionary) + { + List value2 = item.Value; + if (value2.Count == 1 && !IsArray(value2[0])) + { + SerializeNode(writer, value2[0], manager, writePropertyName); + } + else + { + string key = item.Key; + if (writePropertyName) + { + writer.WritePropertyName(key); + } + writer.WriteStartArray(); + for (int j = 0; j < value2.Count; j++) + { + SerializeNode(writer, value2[j], manager, writePropertyName: false); + } + writer.WriteEndArray(); + } + } + } + + private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName) + { + switch (node.NodeType) + { + case XmlNodeType.Document: + case XmlNodeType.DocumentFragment: + SerializeGroupedNodes(writer, node, manager, writePropertyName); + break; + case XmlNodeType.Element: + if (IsArray(node) && node.ChildNodes.All((IXmlNode n) => n.LocalName == node.LocalName) && node.ChildNodes.Count > 0) + { + SerializeGroupedNodes(writer, node, manager, writePropertyName: false); + } + else + { + foreach (IXmlNode attribute in node.Attributes) + { + if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/") + { + string prefix = (!(attribute.LocalName != "xmlns")) ? string.Empty : attribute.LocalName; + manager.AddNamespace(prefix, attribute.Value); + } + } + if (writePropertyName) + { + writer.WritePropertyName(GetPropertyName(node, manager)); + } + if (ValueAttributes(node.Attributes).Count() == 0 && node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == XmlNodeType.Text) + { + writer.WriteValue(node.ChildNodes[0].Value); + } + else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes)) + { + writer.WriteNull(); + } + else + { + writer.WriteStartObject(); + for (int i = 0; i < node.Attributes.Count; i++) + { + SerializeNode(writer, node.Attributes[i], manager, writePropertyName: true); + } + SerializeGroupedNodes(writer, node, manager, writePropertyName: true); + writer.WriteEndObject(); + } + } + break; + case XmlNodeType.Comment: + if (writePropertyName) + { + writer.WriteComment(node.Value); + } + break; + case XmlNodeType.Attribute: + case XmlNodeType.Text: + case XmlNodeType.CDATA: + case XmlNodeType.ProcessingInstruction: + case XmlNodeType.Whitespace: + case XmlNodeType.SignificantWhitespace: + if ((!(node.NamespaceURI == "http://www.w3.org/2000/xmlns/") || !(node.Value == "http://james.newtonking.com/projects/json")) && (!(node.NamespaceURI == "http://james.newtonking.com/projects/json") || !(node.LocalName == "Array"))) + { + if (writePropertyName) + { + writer.WritePropertyName(GetPropertyName(node, manager)); + } + writer.WriteValue(node.Value); + } + break; + case XmlNodeType.XmlDeclaration: + { + IXmlDeclaration xmlDeclaration = (IXmlDeclaration)node; + writer.WritePropertyName(GetPropertyName(node, manager)); + writer.WriteStartObject(); + if (!string.IsNullOrEmpty(xmlDeclaration.Version)) + { + writer.WritePropertyName("@version"); + writer.WriteValue(xmlDeclaration.Version); + } + if (!string.IsNullOrEmpty(xmlDeclaration.Encoding)) + { + writer.WritePropertyName("@encoding"); + writer.WriteValue(xmlDeclaration.Encoding); + } + if (!string.IsNullOrEmpty(xmlDeclaration.Standalone)) + { + writer.WritePropertyName("@standalone"); + writer.WriteValue(xmlDeclaration.Standalone); + } + writer.WriteEndObject(); + break; + } + default: + throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType); + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); + IXmlDocument xmlDocument = null; + IXmlNode xmlNode = null; + if (typeof(XmlNode).IsAssignableFrom(objectType)) + { + if (objectType != typeof(XmlDocument)) + { + throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments"); + } + XmlDocument document = new XmlDocument(); + xmlDocument = new XmlDocumentWrapper(document); + xmlNode = xmlDocument; + } + if (xmlDocument == null || xmlNode == null) + { + throw new JsonSerializationException("Unexpected type when converting XML: " + objectType); + } + if (reader.TokenType != JsonToken.StartObject) + { + throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object."); + } + if (!string.IsNullOrEmpty(DeserializeRootElementName)) + { + ReadElement(reader, xmlDocument, xmlNode, DeserializeRootElementName, manager); + } + else + { + reader.Read(); + DeserializeNode(reader, xmlDocument, manager, xmlNode); + } + return xmlDocument.WrappedNode; + } + + private void DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, string propertyName, IXmlNode currentNode) + { + switch (propertyName) + { + case "#text": + currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString())); + break; + case "#cdata-section": + currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString())); + break; + case "#whitespace": + currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString())); + break; + case "#significant-whitespace": + currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString())); + break; + default: + if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?') + { + CreateInstruction(reader, document, currentNode, propertyName); + } + else if (reader.TokenType == JsonToken.StartArray) + { + ReadArrayElements(reader, document, propertyName, currentNode, manager); + } + else + { + ReadElement(reader, document, currentNode, propertyName, manager); + } + break; + } + } + + private void ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName, XmlNamespaceManager manager) + { + if (string.IsNullOrEmpty(propertyName)) + { + throw new JsonSerializationException("XmlNodeConverter cannot convert JSON with an empty property name to XML."); + } + Dictionary dictionary = ReadAttributeElements(reader, manager); + string prefix = MiscellaneousUtils.GetPrefix(propertyName); + IXmlElement xmlElement = CreateElement(propertyName, document, prefix, manager); + currentNode.AppendChild(xmlElement); + foreach (KeyValuePair item in dictionary) + { + string prefix2 = MiscellaneousUtils.GetPrefix(item.Key); + object xmlNode2; + if (!string.IsNullOrEmpty(prefix2)) + { + IXmlNode xmlNode = document.CreateAttribute(item.Key, manager.LookupNamespace(prefix2), item.Value); + xmlNode2 = xmlNode; + } + else + { + xmlNode2 = document.CreateAttribute(item.Key, item.Value); + } + IXmlNode attributeNode = (IXmlNode)xmlNode2; + xmlElement.SetAttributeNode(attributeNode); + } + if (reader.TokenType == JsonToken.String) + { + xmlElement.AppendChild(document.CreateTextNode(reader.Value.ToString())); + } + else if (reader.TokenType == JsonToken.Integer) + { + xmlElement.AppendChild(document.CreateTextNode(XmlConvert.ToString((long)reader.Value))); + } + else if (reader.TokenType == JsonToken.Float) + { + xmlElement.AppendChild(document.CreateTextNode(XmlConvert.ToString((double)reader.Value))); + } + else if (reader.TokenType == JsonToken.Boolean) + { + xmlElement.AppendChild(document.CreateTextNode(XmlConvert.ToString((bool)reader.Value))); + } + else if (reader.TokenType == JsonToken.Date) + { + DateTime value = (DateTime)reader.Value; + xmlElement.AppendChild(document.CreateTextNode(XmlConvert.ToString(value, DateTimeUtils.ToSerializationMode(value.Kind)))); + } + else if (reader.TokenType != JsonToken.Null && reader.TokenType != JsonToken.EndObject) + { + manager.PushScope(); + DeserializeNode(reader, document, manager, xmlElement); + manager.PopScope(); + } + } + + private void ReadArrayElements(JsonReader reader, IXmlDocument document, string propertyName, IXmlNode currentNode, XmlNamespaceManager manager) + { + string prefix = MiscellaneousUtils.GetPrefix(propertyName); + IXmlElement xmlElement = CreateElement(propertyName, document, prefix, manager); + currentNode.AppendChild(xmlElement); + int num = 0; + while (reader.Read() && reader.TokenType != JsonToken.EndArray) + { + DeserializeValue(reader, document, manager, propertyName, xmlElement); + num++; + } + if (WriteArrayAttribute) + { + AddJsonArrayAttribute(xmlElement, document); + } + if (num == 1 && WriteArrayAttribute) + { + IXmlElement element = xmlElement.ChildNodes.CastValid().Single((IXmlElement n) => n.LocalName == propertyName); + AddJsonArrayAttribute(element, document); + } + } + + private void AddJsonArrayAttribute(IXmlElement element, IXmlDocument document) + { + element.SetAttributeNode(document.CreateAttribute("json:Array", "http://james.newtonking.com/projects/json", "true")); + } + + private Dictionary ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager) + { + Dictionary dictionary = new Dictionary(); + bool flag = false; + bool flag2 = false; + if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null && reader.TokenType != JsonToken.Boolean && reader.TokenType != JsonToken.Integer && reader.TokenType != JsonToken.Float && reader.TokenType != JsonToken.Date && reader.TokenType != JsonToken.StartConstructor) + { + while (!flag && !flag2 && reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + { + string text = reader.Value.ToString(); + if (!string.IsNullOrEmpty(text)) + { + switch (text[0]) + { + case '@': + { + text = text.Substring(1); + reader.Read(); + string value = reader.Value.ToString(); + dictionary.Add(text, value); + if (IsNamespaceAttribute(text, out string prefix)) + { + manager.AddNamespace(prefix, value); + } + break; + } + case '$': + { + text = text.Substring(1); + reader.Read(); + string value = reader.Value.ToString(); + string text2 = manager.LookupPrefix("http://james.newtonking.com/projects/json"); + if (text2 == null) + { + int? num = null; + while (manager.LookupNamespace("json" + num) != null) + { + num = num.GetValueOrDefault() + 1; + } + text2 = "json" + num; + dictionary.Add("xmlns:" + text2, "http://james.newtonking.com/projects/json"); + manager.AddNamespace(text2, "http://james.newtonking.com/projects/json"); + } + dictionary.Add(text2 + ":" + text, value); + break; + } + default: + flag = true; + break; + } + } + else + { + flag = true; + } + break; + } + case JsonToken.EndObject: + flag2 = true; + break; + default: + throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType); + } + } + } + return dictionary; + } + + private void CreateInstruction(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName) + { + if (propertyName == "?xml") + { + string version = null; + string encoding = null; + string standalone = null; + while (reader.Read() && reader.TokenType != JsonToken.EndObject) + { + switch (reader.Value.ToString()) + { + case "@version": + reader.Read(); + version = reader.Value.ToString(); + break; + case "@encoding": + reader.Read(); + encoding = reader.Value.ToString(); + break; + case "@standalone": + reader.Read(); + standalone = reader.Value.ToString(); + break; + default: + throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value); + } + } + IXmlNode newChild = document.CreateXmlDeclaration(version, encoding, standalone); + currentNode.AppendChild(newChild); + } + else + { + IXmlNode newChild2 = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString()); + currentNode.AppendChild(newChild2); + } + } + + private IXmlElement CreateElement(string elementName, IXmlDocument document, string elementPrefix, XmlNamespaceManager manager) + { + object result; + if (!string.IsNullOrEmpty(elementPrefix)) + { + IXmlElement xmlElement = document.CreateElement(elementName, manager.LookupNamespace(elementPrefix)); + result = xmlElement; + } + else + { + result = document.CreateElement(elementName); + } + return (IXmlElement)result; + } + + private void DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode) + { + string propertyName; + do + { + switch (reader.TokenType) + { + case JsonToken.EndObject: + case JsonToken.EndArray: + return; + case JsonToken.PropertyName: + if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null) + { + throw new JsonSerializationException("JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName."); + } + propertyName = reader.Value.ToString(); + reader.Read(); + if (reader.TokenType == JsonToken.StartArray) + { + int num = 0; + while (reader.Read() && reader.TokenType != JsonToken.EndArray) + { + DeserializeValue(reader, document, manager, propertyName, currentNode); + num++; + } + if (num == 1 && WriteArrayAttribute) + { + IXmlElement element = currentNode.ChildNodes.CastValid().Single((IXmlElement n) => n.LocalName == propertyName); + AddJsonArrayAttribute(element, document); + } + } + else + { + DeserializeValue(reader, document, manager, propertyName, currentNode); + } + break; + case JsonToken.StartConstructor: + { + string propertyName2 = reader.Value.ToString(); + while (reader.Read() && reader.TokenType != JsonToken.EndConstructor) + { + DeserializeValue(reader, document, manager, propertyName2, currentNode); + } + break; + } + case JsonToken.Comment: + currentNode.AppendChild(document.CreateComment((string)reader.Value)); + break; + default: + throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType); + } + } + while (reader.TokenType == JsonToken.PropertyName || reader.Read()); + } + + private bool IsNamespaceAttribute(string attributeName, out string prefix) + { + if (attributeName.StartsWith("xmlns", StringComparison.Ordinal)) + { + if (attributeName.Length == 5) + { + prefix = string.Empty; + return true; + } + if (attributeName[5] == ':') + { + prefix = attributeName.Substring(6, attributeName.Length - 6); + return true; + } + } + prefix = null; + return false; + } + + private IEnumerable ValueAttributes(IEnumerable c) + { + return from a in c + where a.NamespaceURI != "http://james.newtonking.com/projects/json" + select a; + } + + public override bool CanConvert(Type valueType) + { + if (typeof(XmlNode).IsAssignableFrom(valueType)) + { + return true; + } + return false; + } + } +} diff --git a/Newtonsoft.Json.Converters/XmlNodeWrapper.cs b/Newtonsoft.Json.Converters/XmlNodeWrapper.cs new file mode 100644 index 00000000..6631862b --- /dev/null +++ b/Newtonsoft.Json.Converters/XmlNodeWrapper.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml; + +namespace Newtonsoft.Json.Converters +{ + internal class XmlNodeWrapper : IXmlNode + { + private readonly XmlNode _node; + + public object WrappedNode => _node; + + public XmlNodeType NodeType => _node.NodeType; + + public string Name => _node.Name; + + public string LocalName => _node.LocalName; + + public IList ChildNodes => (from XmlNode n in _node.ChildNodes + select WrapNode(n)).ToList(); + + public IList Attributes + { + get + { + if (_node.Attributes == null) + { + return null; + } + return (from XmlAttribute a in _node.Attributes + select WrapNode(a)).ToList(); + } + } + + public IXmlNode ParentNode + { + get + { + XmlNode xmlNode = (!(_node is XmlAttribute)) ? _node.ParentNode : ((XmlAttribute)_node).OwnerElement; + if (xmlNode == null) + { + return null; + } + return WrapNode(xmlNode); + } + } + + public string Value + { + get + { + return _node.Value; + } + set + { + _node.Value = value; + } + } + + public string Prefix => _node.Prefix; + + public string NamespaceURI => _node.NamespaceURI; + + public XmlNodeWrapper(XmlNode node) + { + _node = node; + } + + private IXmlNode WrapNode(XmlNode node) + { + switch (node.NodeType) + { + case XmlNodeType.Element: + return new XmlElementWrapper((XmlElement)node); + case XmlNodeType.XmlDeclaration: + return new XmlDeclarationWrapper((XmlDeclaration)node); + default: + return new XmlNodeWrapper(node); + } + } + + public IXmlNode AppendChild(IXmlNode newChild) + { + XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper)newChild; + _node.AppendChild(xmlNodeWrapper._node); + return newChild; + } + } +} diff --git a/Newtonsoft.Json.Linq/IJEnumerable.cs b/Newtonsoft.Json.Linq/IJEnumerable.cs new file mode 100644 index 00000000..d115d11a --- /dev/null +++ b/Newtonsoft.Json.Linq/IJEnumerable.cs @@ -0,0 +1,13 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Linq +{ + public interface IJEnumerable : IEnumerable, IEnumerable where T : JToken + { + IJEnumerable this[object key] + { + get; + } + } +} diff --git a/Newtonsoft.Json.Linq/JArray.cs b/Newtonsoft.Json.Linq/JArray.cs new file mode 100644 index 00000000..67b32114 --- /dev/null +++ b/Newtonsoft.Json.Linq/JArray.cs @@ -0,0 +1,182 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.IO; + +namespace Newtonsoft.Json.Linq +{ + public class JArray : JContainer, IEnumerable, IEnumerable, ICollection, IList + { + private IList _values = new List(); + + bool ICollection.IsReadOnly + { + get + { + return false; + } + } + + protected override IList ChildrenTokens => _values; + + public override JTokenType Type => JTokenType.Array; + + public override JToken this[object key] + { + get + { + ValidationUtils.ArgumentNotNull(key, "o"); + if (!(key is int)) + { + throw new ArgumentException("Accessed JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + } + return GetItem((int)key); + } + set + { + ValidationUtils.ArgumentNotNull(key, "o"); + if (!(key is int)) + { + throw new ArgumentException("Set JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + } + SetItem((int)key, value); + } + } + + public JToken this[int index] + { + get + { + return GetItem(index); + } + set + { + SetItem(index, value); + } + } + + public JArray() + { + } + + public JArray(JArray other) + : base(other) + { + } + + public JArray(params object[] content) + : this((object)content) + { + } + + public JArray(object content) + { + Add(content); + } + + void ICollection.CopyTo(JToken[] array, int arrayIndex) + { + CopyItemsTo(array, arrayIndex); + } + + internal override bool DeepEquals(JToken node) + { + JArray jArray = node as JArray; + return jArray != null && ContentsEqual(jArray); + } + + internal override JToken CloneToken() + { + return new JArray(this); + } + + public new static JArray Load(JsonReader reader) + { + if (reader.TokenType == JsonToken.None && !reader.Read()) + { + throw new Exception("Error reading JArray from JsonReader."); + } + if (reader.TokenType != JsonToken.StartArray) + { + throw new Exception("Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + JArray jArray = new JArray(); + jArray.SetLineInfo(reader as IJsonLineInfo); + jArray.ReadTokenFrom(reader); + return jArray; + } + + public new static JArray Parse(string json) + { + JsonReader reader = new JsonTextReader(new StringReader(json)); + return Load(reader); + } + + public new static JArray FromObject(object o) + { + return FromObject(o, new JsonSerializer()); + } + + public new static JArray FromObject(object o, JsonSerializer jsonSerializer) + { + JToken jToken = JToken.FromObjectInternal(o, jsonSerializer); + if (jToken.Type != JTokenType.Array) + { + throw new ArgumentException("Object serialized to {0}. JArray instance expected.".FormatWith(CultureInfo.InvariantCulture, jToken.Type)); + } + return (JArray)jToken; + } + + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WriteStartArray(); + foreach (JToken childrenToken in ChildrenTokens) + { + childrenToken.WriteTo(writer, converters); + } + writer.WriteEndArray(); + } + + public int IndexOf(JToken item) + { + return IndexOfItem(item); + } + + public void Insert(int index, JToken item) + { + InsertItem(index, item); + } + + public void RemoveAt(int index) + { + RemoveItemAt(index); + } + + public void Add(JToken item) + { + Add((object)item); + } + + public void Clear() + { + ClearItems(); + } + + public bool Contains(JToken item) + { + return ContainsItem(item); + } + + public bool Remove(JToken item) + { + return RemoveItem(item); + } + + internal override int GetDeepHashCode() + { + return ContentsHashCode(); + } + } +} diff --git a/Newtonsoft.Json.Linq/JConstructor.cs b/Newtonsoft.Json.Linq/JConstructor.cs new file mode 100644 index 00000000..effde5e4 --- /dev/null +++ b/Newtonsoft.Json.Linq/JConstructor.cs @@ -0,0 +1,121 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Newtonsoft.Json.Linq +{ + public class JConstructor : JContainer + { + private string _name; + + private IList _values = new List(); + + protected override IList ChildrenTokens => _values; + + public string Name + { + get + { + return _name; + } + set + { + _name = value; + } + } + + public override JTokenType Type => JTokenType.Constructor; + + public override JToken this[object key] + { + get + { + ValidationUtils.ArgumentNotNull(key, "o"); + if (!(key is int)) + { + throw new ArgumentException("Accessed JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + } + return GetItem((int)key); + } + set + { + ValidationUtils.ArgumentNotNull(key, "o"); + if (!(key is int)) + { + throw new ArgumentException("Set JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + } + SetItem((int)key, value); + } + } + + public JConstructor() + { + } + + public JConstructor(JConstructor other) + : base(other) + { + _name = other.Name; + } + + public JConstructor(string name, params object[] content) + : this(name, (object)content) + { + } + + public JConstructor(string name, object content) + : this(name) + { + Add(content); + } + + public JConstructor(string name) + { + ValidationUtils.ArgumentNotNullOrEmpty(name, "name"); + _name = name; + } + + internal override bool DeepEquals(JToken node) + { + JConstructor jConstructor = node as JConstructor; + return jConstructor != null && _name == jConstructor.Name && ContentsEqual(jConstructor); + } + + internal override JToken CloneToken() + { + return new JConstructor(this); + } + + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WriteStartConstructor(_name); + foreach (JToken item in Children()) + { + item.WriteTo(writer, converters); + } + writer.WriteEndConstructor(); + } + + internal override int GetDeepHashCode() + { + return _name.GetHashCode() ^ ContentsHashCode(); + } + + public new static JConstructor Load(JsonReader reader) + { + if (reader.TokenType == JsonToken.None && !reader.Read()) + { + throw new Exception("Error reading JConstructor from JsonReader."); + } + if (reader.TokenType != JsonToken.StartConstructor) + { + throw new Exception("Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + JConstructor jConstructor = new JConstructor((string)reader.Value); + jConstructor.SetLineInfo(reader as IJsonLineInfo); + jConstructor.ReadTokenFrom(reader); + return jConstructor; + } + } +} diff --git a/Newtonsoft.Json.Linq/JContainer.cs b/Newtonsoft.Json.Linq/JContainer.cs new file mode 100644 index 00000000..16e95fff --- /dev/null +++ b/Newtonsoft.Json.Linq/JContainer.cs @@ -0,0 +1,851 @@ +using Newtonsoft.Json.ObservableSupport; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Threading; + +namespace Newtonsoft.Json.Linq +{ + public abstract class JContainer : JToken, IEnumerable, IEnumerable, ICollection, IList, IList, ICollection, ITypedList, IBindingList + { + private class JTokenReferenceEqualityComparer : IEqualityComparer + { + public static readonly JTokenReferenceEqualityComparer Instance = new JTokenReferenceEqualityComparer(); + + public bool Equals(JToken x, JToken y) + { + return object.ReferenceEquals(x, y); + } + + public int GetHashCode(JToken obj) + { + return obj?.GetHashCode() ?? 0; + } + } + + private object _syncRoot; + + private bool _busy; + + JToken IList.this[int index] + { + get + { + return GetItem(index); + } + set + { + SetItem(index, value); + } + } + + bool ICollection.IsReadOnly + { + get + { + return false; + } + } + + bool IList.IsFixedSize + { + get + { + return false; + } + } + + bool IList.IsReadOnly + { + get + { + return false; + } + } + + object IList.this[int index] + { + get + { + return GetItem(index); + } + set + { + SetItem(index, EnsureValue(value)); + } + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + { + Interlocked.CompareExchange(ref _syncRoot, new object(), null); + } + return _syncRoot; + } + } + + bool IBindingList.AllowEdit + { + get + { + return true; + } + } + + bool IBindingList.AllowNew + { + get + { + return true; + } + } + + bool IBindingList.AllowRemove + { + get + { + return true; + } + } + + bool IBindingList.IsSorted + { + get + { + return false; + } + } + + ListSortDirection IBindingList.SortDirection + { + get + { + return ListSortDirection.Ascending; + } + } + + PropertyDescriptor IBindingList.SortProperty + { + get + { + return null; + } + } + + bool IBindingList.SupportsChangeNotification + { + get + { + return true; + } + } + + bool IBindingList.SupportsSearching + { + get + { + return false; + } + } + + bool IBindingList.SupportsSorting + { + get + { + return false; + } + } + + protected abstract IList ChildrenTokens + { + get; + } + + public override bool HasValues => ChildrenTokens.Count > 0; + + public override JToken First => ChildrenTokens.FirstOrDefault(); + + public override JToken Last => ChildrenTokens.LastOrDefault(); + + public int Count => ChildrenTokens.Count; + + public event ListChangedEventHandler ListChanged; + + public event Newtonsoft.Json.ObservableSupport.AddingNewEventHandler AddingNew; + + internal JContainer() + { + } + + internal JContainer(JContainer other) + { + ValidationUtils.ArgumentNotNull(other, "c"); + foreach (JToken item in (IEnumerable)other) + { + Add(item); + } + } + + string ITypedList.GetListName(PropertyDescriptor[] listAccessors) + { + return string.Empty; + } + + PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) + { + return (First as ICustomTypeDescriptor)?.GetProperties(); + } + + int IList.IndexOf(JToken item) + { + return IndexOfItem(item); + } + + void IList.Insert(int index, JToken item) + { + InsertItem(index, item); + } + + void IList.RemoveAt(int index) + { + RemoveItemAt(index); + } + + void ICollection.Add(JToken item) + { + Add(item); + } + + void ICollection.Clear() + { + ClearItems(); + } + + bool ICollection.Contains(JToken item) + { + return ContainsItem(item); + } + + void ICollection.CopyTo(JToken[] array, int arrayIndex) + { + CopyItemsTo(array, arrayIndex); + } + + bool ICollection.Remove(JToken item) + { + return RemoveItem(item); + } + + int IList.Add(object value) + { + Add(EnsureValue(value)); + return Count - 1; + } + + void IList.Clear() + { + ClearItems(); + } + + bool IList.Contains(object value) + { + return ContainsItem(EnsureValue(value)); + } + + int IList.IndexOf(object value) + { + return IndexOfItem(EnsureValue(value)); + } + + void IList.Insert(int index, object value) + { + InsertItem(index, EnsureValue(value)); + } + + void IList.Remove(object value) + { + RemoveItem(EnsureValue(value)); + } + + void IList.RemoveAt(int index) + { + RemoveItemAt(index); + } + + void ICollection.CopyTo(Array array, int index) + { + CopyItemsTo(array, index); + } + + void IBindingList.AddIndex(PropertyDescriptor property) + { + } + + object IBindingList.AddNew() + { + Newtonsoft.Json.ObservableSupport.AddingNewEventArgs addingNewEventArgs = new Newtonsoft.Json.ObservableSupport.AddingNewEventArgs(); + OnAddingNew(addingNewEventArgs); + if (addingNewEventArgs.NewObject == null) + { + throw new Exception("Could not determine new value to add to '{0}'.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + if (!(addingNewEventArgs.NewObject is JToken)) + { + throw new Exception("New item to be added to collection must be compatible with {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JToken))); + } + JToken jToken = (JToken)addingNewEventArgs.NewObject; + Add(jToken); + return jToken; + } + + void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction) + { + throw new NotSupportedException(); + } + + int IBindingList.Find(PropertyDescriptor property, object key) + { + throw new NotSupportedException(); + } + + void IBindingList.RemoveIndex(PropertyDescriptor property) + { + } + + void IBindingList.RemoveSort() + { + throw new NotSupportedException(); + } + + internal void CheckReentrancy() + { + if (_busy) + { + throw new InvalidOperationException("Cannot change {0} during a collection change event.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + } + + protected virtual void OnAddingNew(Newtonsoft.Json.ObservableSupport.AddingNewEventArgs e) + { + this.AddingNew?.Invoke(this, e); + } + + protected virtual void OnListChanged(ListChangedEventArgs e) + { + ListChangedEventHandler listChanged = this.ListChanged; + if (listChanged != null) + { + _busy = true; + try + { + listChanged(this, e); + } + finally + { + _busy = false; + } + } + } + + internal bool ContentsEqual(JContainer container) + { + JToken jToken = First; + JToken jToken2 = container.First; + if (jToken == jToken2) + { + return true; + } + while (true) + { + if (jToken == null && jToken2 == null) + { + return true; + } + if (jToken == null || jToken2 == null || !jToken.DeepEquals(jToken2)) + { + break; + } + jToken = ((jToken == Last) ? null : jToken.Next); + jToken2 = ((jToken2 == container.Last) ? null : jToken2.Next); + } + return false; + } + + public override JEnumerable Children() + { + return new JEnumerable(ChildrenTokens); + } + + public override IEnumerable Values() + { + return ChildrenTokens.Convert(); + } + + public IEnumerable Descendants() + { + foreach (JToken childrenToken in ChildrenTokens) + { + yield return childrenToken; + JContainer c = childrenToken as JContainer; + if (c != null) + { + foreach (JToken item in c.Descendants()) + { + yield return item; + } + } + } + } + + internal bool IsMultiContent(object content) + { + return content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[]); + } + + internal JToken EnsureParentToken(JToken item) + { + if (item == null) + { + return new JValue((object)null); + } + if (item.Parent != null) + { + item = item.CloneToken(); + } + else + { + JContainer jContainer = this; + while (jContainer.Parent != null) + { + jContainer = jContainer.Parent; + } + if (item == jContainer) + { + item = item.CloneToken(); + } + } + return item; + } + + internal int IndexOfItem(JToken item) + { + return ChildrenTokens.IndexOf(item, JTokenReferenceEqualityComparer.Instance); + } + + internal virtual void InsertItem(int index, JToken item) + { + if (index > ChildrenTokens.Count) + { + throw new ArgumentOutOfRangeException("index", "Index must be within the bounds of the List."); + } + CheckReentrancy(); + item = EnsureParentToken(item); + JToken jToken = (index != 0) ? ChildrenTokens[index - 1] : null; + JToken jToken2 = (index != ChildrenTokens.Count) ? ChildrenTokens[index] : null; + ValidateToken(item, null); + item.Parent = this; + item.Previous = jToken; + if (jToken != null) + { + jToken.Next = item; + } + item.Next = jToken2; + if (jToken2 != null) + { + jToken2.Previous = item; + } + ChildrenTokens.Insert(index, item); + if (this.ListChanged != null) + { + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index)); + } + } + + internal virtual void RemoveItemAt(int index) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException("index", "Index is less than 0."); + } + if (index >= ChildrenTokens.Count) + { + throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count."); + } + CheckReentrancy(); + JToken jToken = ChildrenTokens[index]; + JToken jToken2 = (index != 0) ? ChildrenTokens[index - 1] : null; + JToken jToken3 = (index != ChildrenTokens.Count - 1) ? ChildrenTokens[index + 1] : null; + if (jToken2 != null) + { + jToken2.Next = jToken3; + } + if (jToken3 != null) + { + jToken3.Previous = jToken2; + } + jToken.Parent = null; + jToken.Previous = null; + jToken.Next = null; + ChildrenTokens.RemoveAt(index); + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index)); + } + + internal virtual bool RemoveItem(JToken item) + { + int num = IndexOfItem(item); + if (num >= 0) + { + RemoveItemAt(num); + return true; + } + return false; + } + + internal virtual JToken GetItem(int index) + { + return ChildrenTokens[index]; + } + + internal virtual void SetItem(int index, JToken item) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException("index", "Index is less than 0."); + } + if (index >= ChildrenTokens.Count) + { + throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count."); + } + JToken jToken = ChildrenTokens[index]; + if (!IsTokenUnchanged(jToken, item)) + { + CheckReentrancy(); + item = EnsureParentToken(item); + ValidateToken(item, jToken); + JToken jToken2 = (index != 0) ? ChildrenTokens[index - 1] : null; + JToken jToken3 = (index != ChildrenTokens.Count - 1) ? ChildrenTokens[index + 1] : null; + item.Parent = this; + item.Previous = jToken2; + if (jToken2 != null) + { + jToken2.Next = item; + } + item.Next = jToken3; + if (jToken3 != null) + { + jToken3.Previous = item; + } + ChildrenTokens[index] = item; + jToken.Parent = null; + jToken.Previous = null; + jToken.Next = null; + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index)); + } + } + + internal virtual void ClearItems() + { + CheckReentrancy(); + foreach (JToken childrenToken in ChildrenTokens) + { + childrenToken.Parent = null; + childrenToken.Previous = null; + childrenToken.Next = null; + } + ChildrenTokens.Clear(); + OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); + } + + internal virtual void ReplaceItem(JToken existing, JToken replacement) + { + if (existing != null && existing.Parent == this) + { + int index = IndexOfItem(existing); + SetItem(index, replacement); + } + } + + internal virtual bool ContainsItem(JToken item) + { + return IndexOfItem(item) != -1; + } + + internal virtual void CopyItemsTo(Array array, int arrayIndex) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + if (arrayIndex < 0) + { + throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0."); + } + if (arrayIndex >= array.Length) + { + throw new ArgumentException("arrayIndex is equal to or greater than the length of array."); + } + if (Count > array.Length - arrayIndex) + { + throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); + } + int num = 0; + foreach (JToken childrenToken in ChildrenTokens) + { + array.SetValue(childrenToken, arrayIndex + num); + num++; + } + } + + internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue) + { + JValue jValue = currentValue as JValue; + if (jValue != null) + { + if (jValue.Type == JTokenType.Null && newValue == null) + { + return true; + } + return jValue.Equals(newValue); + } + return false; + } + + internal virtual void ValidateToken(JToken o, JToken existing) + { + ValidationUtils.ArgumentNotNull(o, "o"); + if (o.Type == JTokenType.Property) + { + throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType())); + } + } + + public virtual void Add(object content) + { + AddInternal(ChildrenTokens.Count, content); + } + + public void AddFirst(object content) + { + AddInternal(0, content); + } + + internal void AddInternal(int index, object content) + { + if (IsMultiContent(content)) + { + IEnumerable enumerable = (IEnumerable)content; + int num = index; + foreach (object item2 in enumerable) + { + AddInternal(num, item2); + num++; + } + } + else + { + JToken item = CreateFromContent(content); + InsertItem(index, item); + } + } + + internal JToken CreateFromContent(object content) + { + if (content is JToken) + { + return (JToken)content; + } + return new JValue(content); + } + + public JsonWriter CreateWriter() + { + return new JTokenWriter(this); + } + + public void ReplaceAll(object content) + { + ClearItems(); + Add(content); + } + + public void RemoveAll() + { + ClearItems(); + } + + internal void ReadTokenFrom(JsonReader r) + { + int depth = r.Depth; + if (!r.Read()) + { + throw new Exception("Error reading {0} from JsonReader.".FormatWith(CultureInfo.InvariantCulture, GetType().Name)); + } + ReadContentFrom(r); + int depth2 = r.Depth; + if (depth2 > depth) + { + throw new Exception("Unexpected end of content while loading {0}.".FormatWith(CultureInfo.InvariantCulture, GetType().Name)); + } + } + + internal void ReadContentFrom(JsonReader r) + { + ValidationUtils.ArgumentNotNull(r, "r"); + IJsonLineInfo lineInfo = r as IJsonLineInfo; + JContainer jContainer = this; + do + { + if (jContainer is JProperty && ((JProperty)jContainer).Value != null) + { + if (jContainer == this) + { + break; + } + jContainer = jContainer.Parent; + } + switch (r.TokenType) + { + case JsonToken.StartArray: + { + JArray jArray = new JArray(); + jArray.SetLineInfo(lineInfo); + jContainer.Add(jArray); + jContainer = jArray; + break; + } + case JsonToken.EndArray: + if (jContainer == this) + { + return; + } + jContainer = jContainer.Parent; + break; + case JsonToken.StartObject: + { + JObject jObject2 = new JObject(); + jObject2.SetLineInfo(lineInfo); + jContainer.Add(jObject2); + jContainer = jObject2; + break; + } + case JsonToken.EndObject: + if (jContainer == this) + { + return; + } + jContainer = jContainer.Parent; + break; + case JsonToken.StartConstructor: + { + JConstructor jConstructor = new JConstructor(r.Value.ToString()); + jConstructor.SetLineInfo(jConstructor); + jContainer.Add(jConstructor); + jContainer = jConstructor; + break; + } + case JsonToken.EndConstructor: + if (jContainer == this) + { + return; + } + jContainer = jContainer.Parent; + break; + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Date: + case JsonToken.Bytes: + { + JValue jValue = new JValue(r.Value); + jValue.SetLineInfo(lineInfo); + jContainer.Add(jValue); + break; + } + case JsonToken.Comment: + { + JValue jValue = JValue.CreateComment(r.Value.ToString()); + jValue.SetLineInfo(lineInfo); + jContainer.Add(jValue); + break; + } + case JsonToken.Null: + { + JValue jValue = new JValue(null, JTokenType.Null); + jValue.SetLineInfo(lineInfo); + jContainer.Add(jValue); + break; + } + case JsonToken.Undefined: + { + JValue jValue = new JValue(null, JTokenType.Undefined); + jValue.SetLineInfo(lineInfo); + jContainer.Add(jValue); + break; + } + case JsonToken.PropertyName: + { + string name = r.Value.ToString(); + JProperty jProperty = new JProperty(name); + jProperty.SetLineInfo(lineInfo); + JObject jObject = (JObject)jContainer; + JProperty jProperty2 = jObject.Property(name); + if (jProperty2 == null) + { + jContainer.Add(jProperty); + } + else + { + jProperty2.Replace(jProperty); + } + jContainer = jProperty; + break; + } + default: + throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, r.TokenType)); + case JsonToken.None: + break; + } + } + while (r.Read()); + } + + internal int ContentsHashCode() + { + int num = 0; + foreach (JToken childrenToken in ChildrenTokens) + { + num ^= childrenToken.GetDeepHashCode(); + } + return num; + } + + private JToken EnsureValue(object value) + { + if (value == null) + { + return null; + } + if (value is JToken) + { + return (JToken)value; + } + throw new ArgumentException("Argument is not a JToken."); + } + } +} diff --git a/Newtonsoft.Json.Linq/JEnumerable.cs b/Newtonsoft.Json.Linq/JEnumerable.cs new file mode 100644 index 00000000..da8ed35d --- /dev/null +++ b/Newtonsoft.Json.Linq/JEnumerable.cs @@ -0,0 +1,54 @@ +using Newtonsoft.Json.Utilities; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Newtonsoft.Json.Linq +{ + public struct JEnumerable : IEnumerable, IEnumerable, IJEnumerable where T : JToken + { + public static readonly JEnumerable Empty = new JEnumerable(Enumerable.Empty()); + + private IEnumerable _enumerable; + + public IJEnumerable this[object key] + { + get + { + return new JEnumerable(_enumerable.Values(key)); + } + } + + public JEnumerable(IEnumerable enumerable) + { + ValidationUtils.ArgumentNotNull(enumerable, "enumerable"); + _enumerable = enumerable; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public IEnumerator GetEnumerator() + { + return _enumerable.GetEnumerator(); + } + + public override bool Equals(object obj) + { + if (obj is JEnumerable) + { + IEnumerable enumerable = _enumerable; + JEnumerable jEnumerable = (JEnumerable)obj; + return enumerable.Equals(jEnumerable._enumerable); + } + return false; + } + + public override int GetHashCode() + { + return _enumerable.GetHashCode(); + } + } +} diff --git a/Newtonsoft.Json.Linq/JObject.cs b/Newtonsoft.Json.Linq/JObject.cs new file mode 100644 index 00000000..0c27c7c4 --- /dev/null +++ b/Newtonsoft.Json.Linq/JObject.cs @@ -0,0 +1,471 @@ +using Newtonsoft.Json.ObservableSupport; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Globalization; +using System.IO; +using System.Linq; + +namespace Newtonsoft.Json.Linq +{ + public class JObject : JContainer, IEnumerable, Newtonsoft.Json.ObservableSupport.INotifyPropertyChanging, IDictionary, ICollection>, ICustomTypeDescriptor, INotifyPropertyChanged, IEnumerable> + { + private class JPropertKeyedCollection : KeyedCollection + { + public new IDictionary Dictionary => base.Dictionary; + + public JPropertKeyedCollection(IEqualityComparer comparer) + : base(comparer) + { + } + + protected override string GetKeyForItem(JToken item) + { + return ((JProperty)item).Name; + } + + protected override void InsertItem(int index, JToken item) + { + if (Dictionary == null) + { + base.InsertItem(index, item); + } + else + { + string keyForItem = GetKeyForItem(item); + Dictionary[keyForItem] = item; + base.Items.Insert(index, item); + } + } + } + + private JPropertKeyedCollection _properties = new JPropertKeyedCollection(StringComparer.Ordinal); + + ICollection IDictionary.Keys + { + get + { + return _properties.Dictionary.Keys; + } + } + + ICollection IDictionary.Values + { + get + { + return _properties.Dictionary.Values; + } + } + + bool ICollection>.IsReadOnly + { + get + { + return false; + } + } + + protected override IList ChildrenTokens => _properties; + + public override JTokenType Type => JTokenType.Object; + + public override JToken this[object key] + { + get + { + ValidationUtils.ArgumentNotNull(key, "o"); + string text = key as string; + if (text == null) + { + throw new ArgumentException("Accessed JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + } + return this[text]; + } + set + { + ValidationUtils.ArgumentNotNull(key, "o"); + string text = key as string; + if (text == null) + { + throw new ArgumentException("Set JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + } + this[text] = value; + } + } + + public JToken this[string propertyName] + { + get + { + ValidationUtils.ArgumentNotNull(propertyName, "propertyName"); + return Property(propertyName)?.Value; + } + set + { + JProperty jProperty = Property(propertyName); + if (jProperty != null) + { + jProperty.Value = value; + } + else + { + OnPropertyChanging(propertyName); + Add(new JProperty(propertyName, value)); + OnPropertyChanged(propertyName); + } + } + } + + public event PropertyChangedEventHandler PropertyChanged; + + public event Newtonsoft.Json.ObservableSupport.PropertyChangingEventHandler PropertyChanging; + + public JObject() + { + } + + public JObject(JObject other) + : base(other) + { + } + + public JObject(params object[] content) + : this((object)content) + { + } + + public JObject(object content) + { + Add(content); + } + + bool IDictionary.ContainsKey(string key) + { + if (_properties.Dictionary == null) + { + return false; + } + return _properties.Dictionary.ContainsKey(key); + } + + void ICollection>.Add(KeyValuePair item) + { + Add(new JProperty(item.Key, item.Value)); + } + + void ICollection>.Clear() + { + RemoveAll(); + } + + bool ICollection>.Contains(KeyValuePair item) + { + JProperty jProperty = Property(item.Key); + if (jProperty == null) + { + return false; + } + return jProperty.Value == item.Value; + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + if (arrayIndex < 0) + { + throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0."); + } + if (arrayIndex >= array.Length) + { + throw new ArgumentException("arrayIndex is equal to or greater than the length of array."); + } + if (Count > array.Length - arrayIndex) + { + throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); + } + int num = 0; + foreach (JProperty childrenToken in ChildrenTokens) + { + array[arrayIndex + num] = new KeyValuePair(childrenToken.Name, childrenToken.Value); + num++; + } + } + + bool ICollection>.Remove(KeyValuePair item) + { + if (!((ICollection>)this).Contains(item)) + { + return false; + } + ((IDictionary)this).Remove(item.Key); + return true; + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return ((ICustomTypeDescriptor)this).GetProperties((Attribute[])null); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + PropertyDescriptorCollection propertyDescriptorCollection = new PropertyDescriptorCollection(null); + using (IEnumerator> enumerator = GetEnumerator()) + { + while (enumerator.MoveNext()) + { + KeyValuePair current = enumerator.Current; + propertyDescriptorCollection.Add(new JPropertyDescriptor(current.Key, GetTokenPropertyType(current.Value))); + } + return propertyDescriptorCollection; + } + } + + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + return AttributeCollection.Empty; + } + + string ICustomTypeDescriptor.GetClassName() + { + return null; + } + + string ICustomTypeDescriptor.GetComponentName() + { + return null; + } + + TypeConverter ICustomTypeDescriptor.GetConverter() + { + return new TypeConverter(); + } + + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + return null; + } + + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + return null; + } + + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + return null; + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + return EventDescriptorCollection.Empty; + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return EventDescriptorCollection.Empty; + } + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + return null; + } + + internal override bool DeepEquals(JToken node) + { + JObject jObject = node as JObject; + return jObject != null && ContentsEqual(jObject); + } + + internal override void InsertItem(int index, JToken item) + { + if (item == null || item.Type != JTokenType.Comment) + { + base.InsertItem(index, item); + } + } + + internal override void ValidateToken(JToken o, JToken existing) + { + ValidationUtils.ArgumentNotNull(o, "o"); + if (o.Type != JTokenType.Property) + { + throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType())); + } + JProperty jProperty = (JProperty)o; + if (existing != null) + { + JProperty jProperty2 = (JProperty)existing; + if (jProperty.Name == jProperty2.Name) + { + return; + } + } + if (_properties.Dictionary != null && _properties.Dictionary.TryGetValue(jProperty.Name, out existing)) + { + throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, jProperty.Name, GetType())); + } + } + + internal void InternalPropertyChanged(JProperty childProperty) + { + OnPropertyChanged(childProperty.Name); + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, IndexOfItem(childProperty))); + } + + internal void InternalPropertyChanging(JProperty childProperty) + { + OnPropertyChanging(childProperty.Name); + } + + internal override JToken CloneToken() + { + return new JObject(this); + } + + public IEnumerable Properties() + { + return ChildrenTokens.Cast(); + } + + public JProperty Property(string name) + { + if (_properties.Dictionary == null) + { + return null; + } + if (name == null) + { + return null; + } + _properties.Dictionary.TryGetValue(name, out JToken value); + return (JProperty)value; + } + + public JEnumerable PropertyValues() + { + return new JEnumerable(from p in Properties() + select p.Value); + } + + public new static JObject Load(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + if (reader.TokenType == JsonToken.None && !reader.Read()) + { + throw new Exception("Error reading JObject from JsonReader."); + } + if (reader.TokenType != JsonToken.StartObject) + { + throw new Exception("Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + JObject jObject = new JObject(); + jObject.SetLineInfo(reader as IJsonLineInfo); + jObject.ReadTokenFrom(reader); + return jObject; + } + + public new static JObject Parse(string json) + { + JsonReader reader = new JsonTextReader(new StringReader(json)); + return Load(reader); + } + + public new static JObject FromObject(object o) + { + return FromObject(o, new JsonSerializer()); + } + + public new static JObject FromObject(object o, JsonSerializer jsonSerializer) + { + JToken jToken = JToken.FromObjectInternal(o, jsonSerializer); + if (jToken != null && jToken.Type != JTokenType.Object) + { + throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, jToken.Type)); + } + return (JObject)jToken; + } + + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WriteStartObject(); + foreach (JProperty childrenToken in ChildrenTokens) + { + childrenToken.WriteTo(writer, converters); + } + writer.WriteEndObject(); + } + + public void Add(string propertyName, JToken value) + { + Add(new JProperty(propertyName, value)); + } + + public bool Remove(string propertyName) + { + JProperty jProperty = Property(propertyName); + if (jProperty == null) + { + return false; + } + jProperty.Remove(); + return true; + } + + public bool TryGetValue(string propertyName, out JToken value) + { + JProperty jProperty = Property(propertyName); + if (jProperty == null) + { + value = null; + return false; + } + value = jProperty.Value; + return true; + } + + internal override int GetDeepHashCode() + { + return ContentsHashCode(); + } + + public IEnumerator> GetEnumerator() + { + foreach (JProperty childrenToken in ChildrenTokens) + { + yield return new KeyValuePair(childrenToken.Name, childrenToken.Value); + } + } + + protected virtual void OnPropertyChanged(string propertyName) + { + if (this.PropertyChanged != null) + { + this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + protected virtual void OnPropertyChanging(string propertyName) + { + if (this.PropertyChanging != null) + { + this.PropertyChanging(this, new Newtonsoft.Json.ObservableSupport.PropertyChangingEventArgs(propertyName)); + } + } + + private static Type GetTokenPropertyType(JToken token) + { + if (token is JValue) + { + JValue jValue = (JValue)token; + return (jValue.Value == null) ? typeof(object) : jValue.Value.GetType(); + } + return token.GetType(); + } + } +} diff --git a/Newtonsoft.Json.Linq/JPath.cs b/Newtonsoft.Json.Linq/JPath.cs new file mode 100644 index 00000000..17bce73d --- /dev/null +++ b/Newtonsoft.Json.Linq/JPath.cs @@ -0,0 +1,159 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Newtonsoft.Json.Linq +{ + internal class JPath + { + private readonly string _expression; + + private int _currentIndex; + + public List Parts + { + get; + private set; + } + + public JPath(string expression) + { + ValidationUtils.ArgumentNotNull(expression, "expression"); + _expression = expression; + Parts = new List(); + ParseMain(); + } + + private void ParseMain() + { + int num = _currentIndex; + bool flag = false; + while (_currentIndex < _expression.Length) + { + char c = _expression[_currentIndex]; + switch (c) + { + case '(': + case '[': + if (_currentIndex > num) + { + string item2 = _expression.Substring(num, _currentIndex - num); + Parts.Add(item2); + } + ParseIndexer(c); + num = _currentIndex + 1; + flag = true; + break; + case ')': + case ']': + throw new Exception("Unexpected character while parsing path: " + c); + case '.': + if (_currentIndex > num) + { + string item = _expression.Substring(num, _currentIndex - num); + Parts.Add(item); + } + num = _currentIndex + 1; + flag = false; + break; + default: + if (flag) + { + throw new Exception("Unexpected character following indexer: " + c); + } + break; + } + _currentIndex++; + } + if (_currentIndex > num) + { + string item3 = _expression.Substring(num, _currentIndex - num); + Parts.Add(item3); + } + } + + private void ParseIndexer(char indexerOpenChar) + { + _currentIndex++; + char c = (indexerOpenChar != '[') ? ')' : ']'; + int currentIndex = _currentIndex; + int num = 0; + bool flag = false; + while (_currentIndex < _expression.Length) + { + char c2 = _expression[_currentIndex]; + if (!char.IsDigit(c2)) + { + if (c2 == c) + { + flag = true; + break; + } + throw new Exception("Unexpected character while parsing path indexer: " + c2); + } + num++; + _currentIndex++; + } + if (!flag) + { + throw new Exception("Path ended with open indexer. Expected " + c); + } + if (num == 0) + { + throw new Exception("Empty path indexer."); + } + string value = _expression.Substring(currentIndex, num); + Parts.Add(Convert.ToInt32(value, CultureInfo.InvariantCulture)); + } + + internal JToken Evaluate(JToken root, bool errorWhenNoMatch) + { + JToken jToken = root; + foreach (object part in Parts) + { + string text = part as string; + if (text != null) + { + JObject jObject = jToken as JObject; + if (jObject == null) + { + if (errorWhenNoMatch) + { + throw new Exception("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, text, jToken.GetType().Name)); + } + return null; + } + jToken = jObject[text]; + if (jToken == null && errorWhenNoMatch) + { + throw new Exception("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, text)); + } + } + else + { + int num = (int)part; + JArray jArray = jToken as JArray; + if (jArray == null) + { + if (errorWhenNoMatch) + { + throw new Exception("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, num, jToken.GetType().Name)); + } + return null; + } + if (jArray.Count <= num) + { + if (errorWhenNoMatch) + { + throw new IndexOutOfRangeException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, num)); + } + return null; + } + jToken = jArray[num]; + } + } + return jToken; + } + } +} diff --git a/Newtonsoft.Json.Linq/JProperty.cs b/Newtonsoft.Json.Linq/JProperty.cs new file mode 100644 index 00000000..e81d85a4 --- /dev/null +++ b/Newtonsoft.Json.Linq/JProperty.cs @@ -0,0 +1,177 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; + +namespace Newtonsoft.Json.Linq +{ + public class JProperty : JContainer + { + private readonly List _content = new List(); + + private readonly string _name; + + protected override IList ChildrenTokens => _content; + + public string Name + { + [DebuggerStepThrough] + get + { + return _name; + } + } + + public new JToken Value + { + [DebuggerStepThrough] + get + { + return (ChildrenTokens.Count <= 0) ? null : ChildrenTokens[0]; + } + set + { + CheckReentrancy(); + JToken item = value ?? new JValue((object)null); + if (ChildrenTokens.Count == 0) + { + InsertItem(0, item); + } + else + { + SetItem(0, item); + } + } + } + + public override JTokenType Type + { + [DebuggerStepThrough] + get + { + return JTokenType.Property; + } + } + + public JProperty(JProperty other) + : base(other) + { + _name = other.Name; + } + + internal JProperty(string name) + { + ValidationUtils.ArgumentNotNull(name, "name"); + _name = name; + } + + public JProperty(string name, params object[] content) + : this(name, (object)content) + { + } + + public JProperty(string name, object content) + { + ValidationUtils.ArgumentNotNull(name, "name"); + _name = name; + Value = ((!IsMultiContent(content)) ? CreateFromContent(content) : new JArray(content)); + } + + internal override JToken GetItem(int index) + { + if (index != 0) + { + throw new ArgumentOutOfRangeException(); + } + return Value; + } + + internal override void SetItem(int index, JToken item) + { + if (index != 0) + { + throw new ArgumentOutOfRangeException(); + } + if (!JContainer.IsTokenUnchanged(Value, item)) + { + if (base.Parent != null) + { + ((JObject)base.Parent).InternalPropertyChanging(this); + } + base.SetItem(0, item); + if (base.Parent != null) + { + ((JObject)base.Parent).InternalPropertyChanged(this); + } + } + } + + internal override bool RemoveItem(JToken item) + { + throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + } + + internal override void RemoveItemAt(int index) + { + throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + } + + internal override void InsertItem(int index, JToken item) + { + if (Value != null) + { + throw new Exception("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + } + base.InsertItem(0, item); + } + + internal override bool ContainsItem(JToken item) + { + return Value == item; + } + + internal override void ClearItems() + { + throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + } + + internal override bool DeepEquals(JToken node) + { + JProperty jProperty = node as JProperty; + return jProperty != null && _name == jProperty.Name && ContentsEqual(jProperty); + } + + internal override JToken CloneToken() + { + return new JProperty(this); + } + + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WritePropertyName(_name); + Value.WriteTo(writer, converters); + } + + internal override int GetDeepHashCode() + { + return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0); + } + + public new static JProperty Load(JsonReader reader) + { + if (reader.TokenType == JsonToken.None && !reader.Read()) + { + throw new Exception("Error reading JProperty from JsonReader."); + } + if (reader.TokenType != JsonToken.PropertyName) + { + throw new Exception("Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + JProperty jProperty = new JProperty((string)reader.Value); + jProperty.SetLineInfo(reader as IJsonLineInfo); + jProperty.ReadTokenFrom(reader); + return jProperty; + } + } +} diff --git a/Newtonsoft.Json.Linq/JPropertyDescriptor.cs b/Newtonsoft.Json.Linq/JPropertyDescriptor.cs new file mode 100644 index 00000000..6789c096 --- /dev/null +++ b/Newtonsoft.Json.Linq/JPropertyDescriptor.cs @@ -0,0 +1,57 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.ComponentModel; + +namespace Newtonsoft.Json.Linq +{ + public class JPropertyDescriptor : PropertyDescriptor + { + private readonly Type _propertyType; + + public override Type ComponentType => typeof(JObject); + + public override bool IsReadOnly => false; + + public override Type PropertyType => _propertyType; + + protected override int NameHashCode => base.NameHashCode; + + public JPropertyDescriptor(string name, Type propertyType) + : base(name, null) + { + ValidationUtils.ArgumentNotNull(name, "name"); + ValidationUtils.ArgumentNotNull(propertyType, "propertyType"); + _propertyType = propertyType; + } + + private static JObject CastInstance(object instance) + { + return (JObject)instance; + } + + public override bool CanResetValue(object component) + { + return false; + } + + public override object GetValue(object component) + { + return CastInstance(component)[Name]; + } + + public override void ResetValue(object component) + { + } + + public override void SetValue(object component, object value) + { + JToken value2 = (!(value is JToken)) ? new JValue(value) : ((JToken)value); + CastInstance(component)[Name] = value2; + } + + public override bool ShouldSerializeValue(object component) + { + return false; + } + } +} diff --git a/Newtonsoft.Json.Linq/JRaw.cs b/Newtonsoft.Json.Linq/JRaw.cs new file mode 100644 index 00000000..45fa017f --- /dev/null +++ b/Newtonsoft.Json.Linq/JRaw.cs @@ -0,0 +1,38 @@ +using System.Globalization; +using System.IO; + +namespace Newtonsoft.Json.Linq +{ + public class JRaw : JValue + { + public JRaw(JRaw other) + : base(other) + { + } + + public JRaw(object rawJson) + : base(rawJson, JTokenType.Raw) + { + } + + public static JRaw Create(JsonReader reader) + { + using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture)) + { + using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter)) + { + jsonTextWriter.WriteToken(reader); + return new JRaw(stringWriter.ToString()); + IL_002a: + JRaw result; + return result; + } + } + } + + internal override JToken CloneToken() + { + return new JRaw(this); + } + } +} diff --git a/Newtonsoft.Json.Linq/JToken.cs b/Newtonsoft.Json.Linq/JToken.cs new file mode 100644 index 00000000..5d3c5d1f --- /dev/null +++ b/Newtonsoft.Json.Linq/JToken.cs @@ -0,0 +1,923 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; + +namespace Newtonsoft.Json.Linq +{ + public abstract class JToken : IJsonLineInfo, IEnumerable, IEnumerable, ICloneable, IJEnumerable + { + private JContainer _parent; + + private JToken _previous; + + private JToken _next; + + private static JTokenEqualityComparer _equalityComparer; + + private int? _lineNumber; + + private int? _linePosition; + + IJEnumerable IJEnumerable.this[object key] + { + get + { + return this[key]; + } + } + + int IJsonLineInfo.LineNumber + { + get + { + int? lineNumber = _lineNumber; + return lineNumber.HasValue ? lineNumber.Value : 0; + } + } + + int IJsonLineInfo.LinePosition + { + get + { + int? linePosition = _linePosition; + return linePosition.HasValue ? linePosition.Value : 0; + } + } + + public static JTokenEqualityComparer EqualityComparer + { + get + { + if (_equalityComparer == null) + { + _equalityComparer = new JTokenEqualityComparer(); + } + return _equalityComparer; + } + } + + public JContainer Parent + { + [DebuggerStepThrough] + get + { + return _parent; + } + internal set + { + _parent = value; + } + } + + public JToken Root + { + get + { + JContainer parent = Parent; + if (parent == null) + { + return this; + } + while (parent.Parent != null) + { + parent = parent.Parent; + } + return parent; + } + } + + public abstract JTokenType Type + { + get; + } + + public abstract bool HasValues + { + get; + } + + public JToken Next + { + get + { + return _next; + } + internal set + { + _next = value; + } + } + + public JToken Previous + { + get + { + return _previous; + } + internal set + { + _previous = value; + } + } + + public virtual JToken this[object key] + { + get + { + throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + set + { + throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + } + + public virtual JToken First + { + get + { + throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + } + + public virtual JToken Last + { + get + { + throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + } + + internal JToken() + { + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)this).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return Children().GetEnumerator(); + } + + bool IJsonLineInfo.HasLineInfo() + { + int? lineNumber = _lineNumber; + int result; + if (lineNumber.HasValue) + { + int? linePosition = _linePosition; + result = (linePosition.HasValue ? 1 : 0); + } + else + { + result = 0; + } + return (byte)result != 0; + } + + object ICloneable.Clone() + { + return DeepClone(); + } + + internal abstract JToken CloneToken(); + + internal abstract bool DeepEquals(JToken node); + + public static bool DeepEquals(JToken t1, JToken t2) + { + return t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)); + } + + public void AddAfterSelf(object content) + { + if (_parent == null) + { + throw new InvalidOperationException("The parent is missing."); + } + int num = _parent.IndexOfItem(this); + _parent.AddInternal(num + 1, content); + } + + public void AddBeforeSelf(object content) + { + if (_parent == null) + { + throw new InvalidOperationException("The parent is missing."); + } + int index = _parent.IndexOfItem(this); + _parent.AddInternal(index, content); + } + + public IEnumerable Ancestors() + { + for (JToken parent = Parent; parent != null; parent = parent.Parent) + { + yield return parent; + } + } + + public IEnumerable AfterSelf() + { + if (Parent != null) + { + for (JToken o = Next; o != null; o = o.Next) + { + yield return o; + } + } + } + + public IEnumerable BeforeSelf() + { + for (JToken o = Parent.First; o != this; o = o.Next) + { + yield return o; + } + } + + public virtual T Value(object key) + { + JToken token = this[key]; + return token.Convert(); + } + + public virtual JEnumerable Children() + { + return JEnumerable.Empty; + } + + public JEnumerable Children() where T : JToken + { + return new JEnumerable(Children().OfType()); + } + + public virtual IEnumerable Values() + { + throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + + public void Remove() + { + if (_parent == null) + { + throw new InvalidOperationException("The parent is missing."); + } + _parent.RemoveItem(this); + } + + public void Replace(JToken value) + { + if (_parent == null) + { + throw new InvalidOperationException("The parent is missing."); + } + _parent.ReplaceItem(this, value); + } + + public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters); + + public override string ToString() + { + return ToString(Formatting.Indented); + } + + public string ToString(Formatting formatting, params JsonConverter[] converters) + { + using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture)) + { + JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter); + jsonTextWriter.Formatting = formatting; + WriteTo(jsonTextWriter, converters); + return stringWriter.ToString(); + IL_002d: + string result; + return result; + } + } + + private static JValue EnsureValue(JToken value) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + if (value is JProperty) + { + value = ((JProperty)value).Value; + } + return value as JValue; + } + + private static string GetType(JToken token) + { + ValidationUtils.ArgumentNotNull(token, "token"); + if (token is JProperty) + { + token = ((JProperty)token).Value; + } + return token.Type.ToString(); + } + + private static bool IsNullable(JToken o) + { + return o.Type == JTokenType.Undefined || o.Type == JTokenType.Null; + } + + private static bool ValidateFloat(JToken o, bool nullable) + { + return o.Type == JTokenType.Float || o.Type == JTokenType.Integer || (nullable && IsNullable(o)); + } + + private static bool ValidateInteger(JToken o, bool nullable) + { + return o.Type == JTokenType.Integer || (nullable && IsNullable(o)); + } + + private static bool ValidateDate(JToken o, bool nullable) + { + return o.Type == JTokenType.Date || (nullable && IsNullable(o)); + } + + private static bool ValidateBoolean(JToken o, bool nullable) + { + return o.Type == JTokenType.Boolean || (nullable && IsNullable(o)); + } + + private static bool ValidateString(JToken o) + { + return o.Type == JTokenType.String || o.Type == JTokenType.Comment || o.Type == JTokenType.Raw || IsNullable(o); + } + + private static bool ValidateBytes(JToken o) + { + return o.Type == JTokenType.Bytes || IsNullable(o); + } + + internal abstract int GetDeepHashCode(); + + public JsonReader CreateReader() + { + return new JTokenReader(this); + } + + internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer) + { + ValidationUtils.ArgumentNotNull(o, "o"); + ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer"); + using (JTokenWriter jTokenWriter = new JTokenWriter()) + { + jsonSerializer.Serialize(jTokenWriter, o); + return jTokenWriter.Token; + } + } + + public static JToken FromObject(object o) + { + return FromObjectInternal(o, new JsonSerializer()); + } + + public static JToken FromObject(object o, JsonSerializer jsonSerializer) + { + return FromObjectInternal(o, jsonSerializer); + } + + public T ToObject() + { + return ToObject(new JsonSerializer()); + } + + public T ToObject(JsonSerializer jsonSerializer) + { + ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer"); + using (JTokenReader reader = new JTokenReader(this)) + { + return jsonSerializer.Deserialize(reader); + IL_001f: + T result; + return result; + } + } + + public static JToken ReadFrom(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + if (reader.TokenType == JsonToken.None && !reader.Read()) + { + throw new Exception("Error reading JToken from JsonReader."); + } + if (reader.TokenType == JsonToken.StartObject) + { + return JObject.Load(reader); + } + if (reader.TokenType == JsonToken.StartArray) + { + return JArray.Load(reader); + } + if (reader.TokenType == JsonToken.PropertyName) + { + return JProperty.Load(reader); + } + if (reader.TokenType == JsonToken.StartConstructor) + { + return JConstructor.Load(reader); + } + if (!JsonReader.IsStartToken(reader.TokenType)) + { + return new JValue(reader.Value); + } + throw new Exception("Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + + public static JToken Parse(string json) + { + JsonReader reader = new JsonTextReader(new StringReader(json)); + return Load(reader); + } + + public static JToken Load(JsonReader reader) + { + return ReadFrom(reader); + } + + internal void SetLineInfo(IJsonLineInfo lineInfo) + { + if (lineInfo != null && lineInfo.HasLineInfo()) + { + SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition); + } + } + + internal void SetLineInfo(int lineNumber, int linePosition) + { + _lineNumber = lineNumber; + _linePosition = linePosition; + } + + public JToken SelectToken(string path) + { + return SelectToken(path, errorWhenNoMatch: false); + } + + public JToken SelectToken(string path, bool errorWhenNoMatch) + { + JPath jPath = new JPath(path); + return jPath.Evaluate(this, errorWhenNoMatch); + } + + public JToken DeepClone() + { + return CloneToken(); + } + + public static explicit operator bool(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateBoolean(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (bool)jValue.Value; + } + + public static explicit operator DateTimeOffset(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateDate(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (DateTimeOffset)jValue.Value; + } + + public static explicit operator bool?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateBoolean(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (bool?)jValue.Value; + } + + public static explicit operator long(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (long)jValue.Value; + } + + public static explicit operator DateTime?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateDate(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (DateTime?)jValue.Value; + } + + public static explicit operator DateTimeOffset?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateDate(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (DateTimeOffset?)jValue.Value; + } + + public static explicit operator decimal?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateFloat(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (jValue.Value == null) ? null : new decimal?(Convert.ToDecimal(jValue.Value, CultureInfo.InvariantCulture)); + } + + public static explicit operator double?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateFloat(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (double?)jValue.Value; + } + + public static explicit operator int(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return Convert.ToInt32(jValue.Value, CultureInfo.InvariantCulture); + } + + public static explicit operator short(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return Convert.ToInt16(jValue.Value, CultureInfo.InvariantCulture); + } + + public static explicit operator ushort(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return Convert.ToUInt16(jValue.Value, CultureInfo.InvariantCulture); + } + + public static explicit operator int?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (jValue.Value == null) ? null : new int?(Convert.ToInt32(jValue.Value, CultureInfo.InvariantCulture)); + } + + public static explicit operator short?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (jValue.Value == null) ? null : new short?(Convert.ToInt16(jValue.Value, CultureInfo.InvariantCulture)); + } + + public static explicit operator ushort?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (jValue.Value == null) ? null : new ushort?((ushort)Convert.ToInt16(jValue.Value, CultureInfo.InvariantCulture)); + } + + public static explicit operator DateTime(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateDate(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (DateTime)jValue.Value; + } + + public static explicit operator long?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (long?)jValue.Value; + } + + public static explicit operator float?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateFloat(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (jValue.Value == null) ? null : new float?(Convert.ToSingle(jValue.Value, CultureInfo.InvariantCulture)); + } + + public static explicit operator decimal(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateFloat(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return Convert.ToDecimal(jValue.Value, CultureInfo.InvariantCulture); + } + + public static explicit operator uint?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (uint?)jValue.Value; + } + + public static explicit operator ulong?(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: true)) + { + throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (ulong?)jValue.Value; + } + + public static explicit operator double(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateFloat(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (double)jValue.Value; + } + + public static explicit operator float(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateFloat(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return Convert.ToSingle(jValue.Value, CultureInfo.InvariantCulture); + } + + public static explicit operator string(JToken value) + { + if (value == null) + { + return null; + } + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateString(jValue)) + { + throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (string)jValue.Value; + } + + public static explicit operator uint(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return Convert.ToUInt32(jValue.Value, CultureInfo.InvariantCulture); + } + + public static explicit operator ulong(JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateInteger(jValue, nullable: false)) + { + throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return Convert.ToUInt64(jValue.Value, CultureInfo.InvariantCulture); + } + + public static explicit operator byte[](JToken value) + { + JValue jValue = EnsureValue(value); + if (jValue == null || !ValidateBytes(jValue)) + { + throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + return (byte[])jValue.Value; + } + + public static implicit operator JToken(bool value) + { + return new JValue(value); + } + + public static implicit operator JToken(DateTimeOffset value) + { + return new JValue(value); + } + + public static implicit operator JToken(bool? value) + { + return new JValue(value); + } + + public static implicit operator JToken(long value) + { + return new JValue(value); + } + + public static implicit operator JToken(DateTime? value) + { + return new JValue(value); + } + + public static implicit operator JToken(DateTimeOffset? value) + { + return new JValue(value); + } + + public static implicit operator JToken(decimal? value) + { + return new JValue(value); + } + + public static implicit operator JToken(double? value) + { + return new JValue(value); + } + + public static implicit operator JToken(short value) + { + return new JValue(value); + } + + public static implicit operator JToken(ushort value) + { + return new JValue((int)value); + } + + public static implicit operator JToken(int value) + { + return new JValue(value); + } + + public static implicit operator JToken(int? value) + { + return new JValue(value); + } + + public static implicit operator JToken(DateTime value) + { + return new JValue(value); + } + + public static implicit operator JToken(long? value) + { + return new JValue(value); + } + + public static implicit operator JToken(float? value) + { + return new JValue(value); + } + + public static implicit operator JToken(decimal value) + { + return new JValue(value); + } + + public static implicit operator JToken(short? value) + { + return new JValue(value); + } + + public static implicit operator JToken(ushort? value) + { + return new JValue(value); + } + + public static implicit operator JToken(uint? value) + { + return new JValue(value); + } + + public static implicit operator JToken(ulong? value) + { + return new JValue(value); + } + + public static implicit operator JToken(double value) + { + return new JValue(value); + } + + public static implicit operator JToken(float value) + { + return new JValue((double)value); + } + + public static implicit operator JToken(string value) + { + return new JValue(value); + } + + public static implicit operator JToken(uint value) + { + return new JValue(value); + } + + public static implicit operator JToken(ulong value) + { + return new JValue(value); + } + + public static implicit operator JToken(byte[] value) + { + return new JValue(value); + } + } +} diff --git a/Newtonsoft.Json.Linq/JTokenEqualityComparer.cs b/Newtonsoft.Json.Linq/JTokenEqualityComparer.cs new file mode 100644 index 00000000..ec9e73fd --- /dev/null +++ b/Newtonsoft.Json.Linq/JTokenEqualityComparer.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace Newtonsoft.Json.Linq +{ + public class JTokenEqualityComparer : IEqualityComparer + { + public bool Equals(JToken x, JToken y) + { + return JToken.DeepEquals(x, y); + } + + public int GetHashCode(JToken obj) + { + return obj?.GetDeepHashCode() ?? 0; + } + } +} diff --git a/Newtonsoft.Json.Linq/JTokenReader.cs b/Newtonsoft.Json.Linq/JTokenReader.cs new file mode 100644 index 00000000..c1128177 --- /dev/null +++ b/Newtonsoft.Json.Linq/JTokenReader.cs @@ -0,0 +1,255 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; + +namespace Newtonsoft.Json.Linq +{ + public class JTokenReader : JsonReader, IJsonLineInfo + { + private readonly JToken _root; + + private JToken _parent; + + private JToken _current; + + int IJsonLineInfo.LineNumber + { + get + { + if (base.CurrentState == State.Start) + { + return 0; + } + return ((IJsonLineInfo)((!IsEndElement) ? _current : null))?.LineNumber ?? 0; + } + } + + int IJsonLineInfo.LinePosition + { + get + { + if (base.CurrentState == State.Start) + { + return 0; + } + return ((IJsonLineInfo)((!IsEndElement) ? _current : null))?.LinePosition ?? 0; + } + } + + private bool IsEndElement => _current == _parent; + + public JTokenReader(JToken token) + { + ValidationUtils.ArgumentNotNull(token, "token"); + _root = token; + _current = token; + } + + bool IJsonLineInfo.HasLineInfo() + { + if (base.CurrentState == State.Start) + { + return false; + } + return ((IJsonLineInfo)((!IsEndElement) ? _current : null))?.HasLineInfo() ?? false; + } + + public override byte[] ReadAsBytes() + { + Read(); + if (TokenType == JsonToken.String) + { + string text = (string)Value; + byte[] value = (text.Length != 0) ? Convert.FromBase64String(text) : new byte[0]; + SetToken(JsonToken.Bytes, value); + } + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Bytes) + { + return (byte[])Value; + } + throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + public override decimal? ReadAsDecimal() + { + Read(); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float) + { + SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture)); + return (decimal)Value; + } + throw new JsonReaderException("Error reading decimal. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + public override DateTimeOffset? ReadAsDateTimeOffset() + { + Read(); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Date) + { + SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value)); + return (DateTimeOffset)Value; + } + throw new JsonReaderException("Error reading date. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + public override bool Read() + { + if (base.CurrentState != 0) + { + JContainer jContainer = _current as JContainer; + if (jContainer != null && _parent != jContainer) + { + return ReadInto(jContainer); + } + return ReadOver(_current); + } + SetToken(_current); + return true; + } + + private bool ReadOver(JToken t) + { + if (t == _root) + { + return ReadToEnd(); + } + JToken next = t.Next; + if (next == null || next == t || t == t.Parent.Last) + { + if (t.Parent == null) + { + return ReadToEnd(); + } + return SetEnd(t.Parent); + } + _current = next; + SetToken(_current); + return true; + } + + private bool ReadToEnd() + { + return false; + } + + private JsonToken? GetEndToken(JContainer c) + { + switch (c.Type) + { + case JTokenType.Object: + return JsonToken.EndObject; + case JTokenType.Array: + return JsonToken.EndArray; + case JTokenType.Constructor: + return JsonToken.EndConstructor; + case JTokenType.Property: + return null; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type."); + } + } + + private bool ReadInto(JContainer c) + { + JToken first = c.First; + if (first == null) + { + return SetEnd(c); + } + SetToken(first); + _current = first; + _parent = c; + return true; + } + + private bool SetEnd(JContainer c) + { + JsonToken? endToken = GetEndToken(c); + if (endToken.HasValue) + { + SetToken(endToken.Value); + _current = c; + _parent = c; + return true; + } + return ReadOver(c); + } + + private void SetToken(JToken token) + { + switch (token.Type) + { + case JTokenType.Object: + SetToken(JsonToken.StartObject); + break; + case JTokenType.Array: + SetToken(JsonToken.StartArray); + break; + case JTokenType.Constructor: + SetToken(JsonToken.StartConstructor); + break; + case JTokenType.Property: + SetToken(JsonToken.PropertyName, ((JProperty)token).Name); + break; + case JTokenType.Comment: + SetToken(JsonToken.Comment, ((JValue)token).Value); + break; + case JTokenType.Integer: + SetToken(JsonToken.Integer, ((JValue)token).Value); + break; + case JTokenType.Float: + SetToken(JsonToken.Float, ((JValue)token).Value); + break; + case JTokenType.String: + SetToken(JsonToken.String, ((JValue)token).Value); + break; + case JTokenType.Boolean: + SetToken(JsonToken.Boolean, ((JValue)token).Value); + break; + case JTokenType.Null: + SetToken(JsonToken.Null, ((JValue)token).Value); + break; + case JTokenType.Undefined: + SetToken(JsonToken.Undefined, ((JValue)token).Value); + break; + case JTokenType.Date: + SetToken(JsonToken.Date, ((JValue)token).Value); + break; + case JTokenType.Raw: + SetToken(JsonToken.Raw, ((JValue)token).Value); + break; + case JTokenType.Bytes: + SetToken(JsonToken.Bytes, ((JValue)token).Value); + break; + case JTokenType.Guid: + SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); + break; + case JTokenType.Uri: + SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); + break; + case JTokenType.TimeSpan: + SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); + break; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", token.Type, "Unexpected JTokenType."); + } + } + + private string SafeToString(object value) + { + return value?.ToString(); + } + } +} diff --git a/Newtonsoft.Json.Linq/JTokenType.cs b/Newtonsoft.Json.Linq/JTokenType.cs new file mode 100644 index 00000000..8703c715 --- /dev/null +++ b/Newtonsoft.Json.Linq/JTokenType.cs @@ -0,0 +1,24 @@ +namespace Newtonsoft.Json.Linq +{ + public enum JTokenType + { + None, + Object, + Array, + Constructor, + Property, + Comment, + Integer, + Float, + String, + Boolean, + Null, + Undefined, + Date, + Raw, + Bytes, + Guid, + Uri, + TimeSpan + } +} diff --git a/Newtonsoft.Json.Linq/JTokenWriter.cs b/Newtonsoft.Json.Linq/JTokenWriter.cs new file mode 100644 index 00000000..d29dde02 --- /dev/null +++ b/Newtonsoft.Json.Linq/JTokenWriter.cs @@ -0,0 +1,262 @@ +using Newtonsoft.Json.Utilities; +using System; + +namespace Newtonsoft.Json.Linq +{ + public class JTokenWriter : JsonWriter + { + private JContainer _token; + + private JContainer _parent; + + private JValue _value; + + public JToken Token + { + get + { + if (_token != null) + { + return _token; + } + return _value; + } + } + + public JTokenWriter(JContainer container) + { + ValidationUtils.ArgumentNotNull(container, "container"); + _token = container; + _parent = container; + } + + public JTokenWriter() + { + } + + public override void Flush() + { + } + + public override void Close() + { + base.Close(); + } + + public override void WriteStartObject() + { + base.WriteStartObject(); + AddParent(new JObject()); + } + + private void AddParent(JContainer container) + { + if (_parent == null) + { + _token = container; + } + else + { + _parent.Add(container); + } + _parent = container; + } + + private void RemoveParent() + { + _parent = _parent.Parent; + if (_parent != null && _parent.Type == JTokenType.Property) + { + _parent = _parent.Parent; + } + } + + public override void WriteStartArray() + { + base.WriteStartArray(); + AddParent(new JArray()); + } + + public override void WriteStartConstructor(string name) + { + base.WriteStartConstructor(name); + AddParent(new JConstructor(name)); + } + + protected override void WriteEnd(JsonToken token) + { + RemoveParent(); + } + + public override void WritePropertyName(string name) + { + base.WritePropertyName(name); + AddParent(new JProperty(name)); + } + + private void AddValue(object value, JsonToken token) + { + AddValue(new JValue(value), token); + } + + internal void AddValue(JValue value, JsonToken token) + { + if (_parent != null) + { + _parent.Add(value); + if (_parent.Type == JTokenType.Property) + { + _parent = _parent.Parent; + } + } + else + { + _value = value; + } + } + + public override void WriteNull() + { + base.WriteNull(); + AddValue(null, JsonToken.Null); + } + + public override void WriteUndefined() + { + base.WriteUndefined(); + AddValue(null, JsonToken.Undefined); + } + + public override void WriteRaw(string json) + { + base.WriteRaw(json); + AddValue(new JRaw(json), JsonToken.Raw); + } + + public override void WriteComment(string text) + { + base.WriteComment(text); + AddValue(JValue.CreateComment(text), JsonToken.Comment); + } + + public override void WriteValue(string value) + { + base.WriteValue(value); + AddValue(value ?? string.Empty, JsonToken.String); + } + + public override void WriteValue(int value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(uint value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(long value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(ulong value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(float value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Float); + } + + public override void WriteValue(double value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Float); + } + + public override void WriteValue(bool value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Boolean); + } + + public override void WriteValue(short value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(ushort value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(char value) + { + base.WriteValue(value); + AddValue(value.ToString(), JsonToken.String); + } + + public override void WriteValue(byte value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(sbyte value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } + + public override void WriteValue(decimal value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Float); + } + + public override void WriteValue(DateTime value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Date); + } + + public override void WriteValue(DateTimeOffset value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Date); + } + + public override void WriteValue(byte[] value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Bytes); + } + + public override void WriteValue(TimeSpan value) + { + base.WriteValue(value); + AddValue(value, JsonToken.String); + } + + public override void WriteValue(Guid value) + { + base.WriteValue(value); + AddValue(value, JsonToken.String); + } + + public override void WriteValue(Uri value) + { + base.WriteValue(value); + AddValue(value, JsonToken.String); + } + } +} diff --git a/Newtonsoft.Json.Linq/JValue.cs b/Newtonsoft.Json.Linq/JValue.cs new file mode 100644 index 00000000..4c4e6035 --- /dev/null +++ b/Newtonsoft.Json.Linq/JValue.cs @@ -0,0 +1,479 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Newtonsoft.Json.Linq +{ + public class JValue : JToken, IFormattable, IComparable, IEquatable, IComparable + { + private JTokenType _valueType; + + private object _value; + + public override bool HasValues => false; + + public override JTokenType Type => _valueType; + + public new object Value + { + get + { + return _value; + } + set + { + Type type = (_value == null) ? null : _value.GetType(); + Type type2 = value?.GetType(); + if (type != type2) + { + _valueType = GetValueType(_valueType, value); + } + _value = value; + } + } + + internal JValue(object value, JTokenType type) + { + _value = value; + _valueType = type; + } + + public JValue(JValue other) + : this(other.Value, other.Type) + { + } + + public JValue(long value) + : this(value, JTokenType.Integer) + { + } + + public JValue(ulong value) + : this(value, JTokenType.Integer) + { + } + + public JValue(double value) + : this(value, JTokenType.Float) + { + } + + public JValue(DateTime value) + : this(value, JTokenType.Date) + { + } + + public JValue(bool value) + : this(value, JTokenType.Boolean) + { + } + + public JValue(string value) + : this(value, JTokenType.String) + { + } + + public JValue(Guid value) + : this(value, JTokenType.String) + { + } + + public JValue(Uri value) + : this(value, JTokenType.String) + { + } + + public JValue(TimeSpan value) + : this(value, JTokenType.String) + { + } + + public JValue(object value) + : this(value, GetValueType(null, value)) + { + } + + int IComparable.CompareTo(object obj) + { + if (obj == null) + { + return 1; + } + object objB = (!(obj is JValue)) ? obj : ((JValue)obj).Value; + return Compare(_valueType, _value, objB); + } + + internal override bool DeepEquals(JToken node) + { + JValue jValue = node as JValue; + if (jValue == null) + { + return false; + } + return ValuesEquals(this, jValue); + } + + private static int Compare(JTokenType valueType, object objA, object objB) + { + if (objA == null && objB == null) + { + return 0; + } + if (objA != null && objB == null) + { + return 1; + } + if (objA != null || objB == null) + { + switch (valueType) + { + case JTokenType.Integer: + if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) + { + return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture)); + } + if (objA is float || objB is float || objA is double || objB is double) + { + return CompareFloat(objA, objB); + } + return Convert.ToInt64(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToInt64(objB, CultureInfo.InvariantCulture)); + case JTokenType.Float: + return CompareFloat(objA, objB); + case JTokenType.Comment: + case JTokenType.String: + case JTokenType.Raw: + { + string text = Convert.ToString(objA, CultureInfo.InvariantCulture); + string strB = Convert.ToString(objB, CultureInfo.InvariantCulture); + return text.CompareTo(strB); + } + case JTokenType.Boolean: + { + bool flag = Convert.ToBoolean(objA, CultureInfo.InvariantCulture); + bool value3 = Convert.ToBoolean(objB, CultureInfo.InvariantCulture); + return flag.CompareTo(value3); + } + case JTokenType.Date: + { + if (objA is DateTime) + { + DateTime dateTime = Convert.ToDateTime(objA, CultureInfo.InvariantCulture); + DateTime value2 = Convert.ToDateTime(objB, CultureInfo.InvariantCulture); + return dateTime.CompareTo(value2); + } + if (!(objB is DateTimeOffset)) + { + throw new ArgumentException("Object must be of type DateTimeOffset."); + } + DateTimeOffset dateTimeOffset = (DateTimeOffset)objA; + DateTimeOffset other = (DateTimeOffset)objB; + return dateTimeOffset.CompareTo(other); + } + case JTokenType.Bytes: + { + if (!(objB is byte[])) + { + throw new ArgumentException("Object must be of type byte[]."); + } + byte[] array = objA as byte[]; + byte[] array2 = objB as byte[]; + if (array == null) + { + return -1; + } + if (array2 == null) + { + return 1; + } + return MiscellaneousUtils.ByteArrayCompare(array, array2); + } + case JTokenType.Guid: + { + if (!(objB is Guid)) + { + throw new ArgumentException("Object must be of type Guid."); + } + Guid guid = (Guid)objA; + Guid value4 = (Guid)objB; + return guid.CompareTo(value4); + } + case JTokenType.Uri: + { + if (!(objB is Uri)) + { + throw new ArgumentException("Object must be of type Uri."); + } + Uri uri = (Uri)objA; + Uri uri2 = (Uri)objB; + return Comparer.Default.Compare(uri.ToString(), uri2.ToString()); + } + case JTokenType.TimeSpan: + { + if (!(objB is TimeSpan)) + { + throw new ArgumentException("Object must be of type TimeSpan."); + } + TimeSpan timeSpan = (TimeSpan)objA; + TimeSpan value = (TimeSpan)objB; + return timeSpan.CompareTo(value); + } + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType)); + } + } + return -1; + } + + private static int CompareFloat(object objA, object objB) + { + double d = Convert.ToDouble(objA, CultureInfo.InvariantCulture); + double num = Convert.ToDouble(objB, CultureInfo.InvariantCulture); + if (MathUtils.ApproxEquals(d, num)) + { + return 0; + } + return d.CompareTo(num); + } + + internal override JToken CloneToken() + { + return new JValue(this); + } + + public static JValue CreateComment(string value) + { + return new JValue(value, JTokenType.Comment); + } + + public static JValue CreateString(string value) + { + return new JValue(value, JTokenType.String); + } + + private static JTokenType GetValueType(JTokenType? current, object value) + { + if (value == null) + { + return JTokenType.Null; + } + if (value == DBNull.Value) + { + return JTokenType.Null; + } + if (value is string) + { + return GetStringValueType(current); + } + if (value is long || value is int || value is short || value is sbyte || value is ulong || value is uint || value is ushort || value is byte) + { + return JTokenType.Integer; + } + if (value is Enum) + { + return JTokenType.Integer; + } + if (value is double || value is float || value is decimal) + { + return JTokenType.Float; + } + if (value is DateTime) + { + return JTokenType.Date; + } + if (value is DateTimeOffset) + { + return JTokenType.Date; + } + if (value is byte[]) + { + return JTokenType.Bytes; + } + if (value is bool) + { + return JTokenType.Boolean; + } + if (value is Guid) + { + return JTokenType.Guid; + } + if (value is Uri) + { + return JTokenType.Uri; + } + if (value is TimeSpan) + { + return JTokenType.TimeSpan; + } + throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + } + + private static JTokenType GetStringValueType(JTokenType? current) + { + if (current.HasValue) + { + switch (current.Value) + { + case JTokenType.Comment: + case JTokenType.String: + case JTokenType.Raw: + return current.Value; + default: + return JTokenType.String; + } + } + return JTokenType.String; + } + + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + switch (_valueType) + { + case JTokenType.Comment: + writer.WriteComment(_value.ToString()); + break; + case JTokenType.Raw: + writer.WriteRawValue((_value == null) ? null : _value.ToString()); + break; + case JTokenType.Null: + writer.WriteNull(); + break; + case JTokenType.Undefined: + writer.WriteUndefined(); + break; + default: + { + JsonConverter matchingConverter; + if (_value == null || (matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType())) == null) + { + switch (_valueType) + { + case JTokenType.Integer: + writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture)); + break; + case JTokenType.Float: + writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture)); + break; + case JTokenType.String: + writer.WriteValue((_value == null) ? null : _value.ToString()); + break; + case JTokenType.Boolean: + writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture)); + break; + case JTokenType.Date: + if (_value is DateTimeOffset) + { + writer.WriteValue((DateTimeOffset)_value); + } + else + { + writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture)); + } + break; + case JTokenType.Bytes: + writer.WriteValue((byte[])_value); + break; + case JTokenType.Guid: + case JTokenType.Uri: + case JTokenType.TimeSpan: + writer.WriteValue((_value == null) ? null : _value.ToString()); + break; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type."); + } + } + else + { + matchingConverter.WriteJson(writer, _value, new JsonSerializer()); + } + break; + } + } + } + + internal override int GetDeepHashCode() + { + int num = (_value != null) ? _value.GetHashCode() : 0; + return _valueType.GetHashCode() ^ num; + } + + private static bool ValuesEquals(JValue v1, JValue v2) + { + return v1 == v2 || (v1._valueType == v2._valueType && Compare(v1._valueType, v1._value, v2._value) == 0); + } + + public bool Equals(JValue other) + { + if (other == null) + { + return false; + } + return ValuesEquals(this, other); + } + + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + JValue jValue = obj as JValue; + if (jValue != null) + { + return Equals(jValue); + } + return base.Equals(obj); + } + + public override int GetHashCode() + { + if (_value == null) + { + return 0; + } + return _value.GetHashCode(); + } + + public override string ToString() + { + if (_value == null) + { + return string.Empty; + } + return _value.ToString(); + } + + public string ToString(string format) + { + return ToString(format, CultureInfo.CurrentCulture); + } + + public string ToString(IFormatProvider formatProvider) + { + return ToString(null, formatProvider); + } + + public string ToString(string format, IFormatProvider formatProvider) + { + if (_value == null) + { + return string.Empty; + } + IFormattable formattable = _value as IFormattable; + if (formattable != null) + { + return formattable.ToString(format, formatProvider); + } + return _value.ToString(); + } + + public int CompareTo(JValue obj) + { + if (obj == null) + { + return 1; + } + return Compare(_valueType, _value, obj._value); + } + } +} diff --git a/Newtonsoft.Json.Linq/LinqExtensions.cs b/Newtonsoft.Json.Linq/LinqExtensions.cs new file mode 100644 index 00000000..8b661000 --- /dev/null +++ b/Newtonsoft.Json.Linq/LinqExtensions.cs @@ -0,0 +1,164 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace Newtonsoft.Json.Linq +{ + public static class LinqExtensions + { + public static IJEnumerable Ancestors(this IEnumerable source) where T : JToken + { + ValidationUtils.ArgumentNotNull(source, "source"); + return source.SelectMany((T j) => j.Ancestors()).AsJEnumerable(); + } + + public static IJEnumerable Descendants(this IEnumerable source) where T : JContainer + { + ValidationUtils.ArgumentNotNull(source, "source"); + return source.SelectMany((T j) => j.Descendants()).AsJEnumerable(); + } + + public static IJEnumerable Properties(this IEnumerable source) + { + ValidationUtils.ArgumentNotNull(source, "source"); + return source.SelectMany((JObject d) => d.Properties()).AsJEnumerable(); + } + + public static IJEnumerable Values(this IEnumerable source, object key) + { + return source.Values(key).AsJEnumerable(); + } + + public static IJEnumerable Values(this IEnumerable source) + { + return source.Values(null); + } + + public static IEnumerable Values(this IEnumerable source, object key) + { + return source.Values(key); + } + + public static IEnumerable Values(this IEnumerable source) + { + return source.Values(null); + } + + public static U Value(this IEnumerable value) + { + return value.Value(); + } + + public static U Value(this IEnumerable value) where T : JToken + { + ValidationUtils.ArgumentNotNull(value, "source"); + JToken jToken = value as JToken; + if (jToken == null) + { + throw new ArgumentException("Source value must be a JToken."); + } + return jToken.Convert(); + } + + internal static IEnumerable Values(this IEnumerable source, object key) where T : JToken + { + ValidationUtils.ArgumentNotNull(source, "source"); + foreach (T item in source) + { + if (key == null) + { + if (item is JValue) + { + yield return (item as JValue).Convert(); + } + else + { + foreach (JToken item2 in item.Children()) + { + yield return item2.Convert(); + } + } + } + else + { + JToken value = item[key]; + if (value != null) + { + yield return value.Convert(); + } + } + } + } + + public static IJEnumerable Children(this IEnumerable source) where T : JToken + { + return source.Children().AsJEnumerable(); + } + + public static IEnumerable Children(this IEnumerable source) where T : JToken + { + ValidationUtils.ArgumentNotNull(source, "source"); + return source.SelectMany((T c) => c.Children()).Convert(); + } + + internal static IEnumerable Convert(this IEnumerable source) where T : JToken + { + ValidationUtils.ArgumentNotNull(source, "source"); + foreach (T item in source) + { + yield return item.Convert(); + } + } + + internal static U Convert(this T token) where T : JToken + { + if (token == null) + { + return default(U); + } + if (token is U && typeof(U) != typeof(IComparable) && typeof(U) != typeof(IFormattable)) + { + return (U)(object)token; + } + JValue jValue = token as JValue; + if (jValue == null) + { + throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(T))); + } + if (jValue.Value is U) + { + return (U)jValue.Value; + } + Type type = typeof(U); + if (ReflectionUtils.IsNullableType(type)) + { + if (jValue.Value == null) + { + return default(U); + } + type = Nullable.GetUnderlyingType(type); + } + return (U)System.Convert.ChangeType(jValue.Value, type, CultureInfo.InvariantCulture); + } + + public static IJEnumerable AsJEnumerable(this IEnumerable source) + { + return source.AsJEnumerable(); + } + + public static IJEnumerable AsJEnumerable(this IEnumerable source) where T : JToken + { + if (source == null) + { + return null; + } + if (source is IJEnumerable) + { + return (IJEnumerable)source; + } + return new JEnumerable(source); + } + } +} diff --git a/Newtonsoft.Json.ObservableSupport/AddingNewEventArgs.cs b/Newtonsoft.Json.ObservableSupport/AddingNewEventArgs.cs new file mode 100644 index 00000000..deda1fcf --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/AddingNewEventArgs.cs @@ -0,0 +1,20 @@ +namespace Newtonsoft.Json.ObservableSupport +{ + public class AddingNewEventArgs + { + public object NewObject + { + get; + set; + } + + public AddingNewEventArgs() + { + } + + public AddingNewEventArgs(object newObject) + { + NewObject = newObject; + } + } +} diff --git a/Newtonsoft.Json.ObservableSupport/AddingNewEventHandler.cs b/Newtonsoft.Json.ObservableSupport/AddingNewEventHandler.cs new file mode 100644 index 00000000..10692837 --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/AddingNewEventHandler.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.ObservableSupport +{ + public delegate void AddingNewEventHandler(object sender, AddingNewEventArgs e); +} diff --git a/Newtonsoft.Json.ObservableSupport/INotifyCollectionChanged.cs b/Newtonsoft.Json.ObservableSupport/INotifyCollectionChanged.cs new file mode 100644 index 00000000..a8820c10 --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/INotifyCollectionChanged.cs @@ -0,0 +1,7 @@ +namespace Newtonsoft.Json.ObservableSupport +{ + public interface INotifyCollectionChanged + { + event NotifyCollectionChangedEventHandler CollectionChanged; + } +} diff --git a/Newtonsoft.Json.ObservableSupport/INotifyPropertyChanging.cs b/Newtonsoft.Json.ObservableSupport/INotifyPropertyChanging.cs new file mode 100644 index 00000000..4e33608a --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/INotifyPropertyChanging.cs @@ -0,0 +1,7 @@ +namespace Newtonsoft.Json.ObservableSupport +{ + public interface INotifyPropertyChanging + { + event PropertyChangingEventHandler PropertyChanging; + } +} diff --git a/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedAction.cs b/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedAction.cs new file mode 100644 index 00000000..6a3f7421 --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedAction.cs @@ -0,0 +1,11 @@ +namespace Newtonsoft.Json.ObservableSupport +{ + public enum NotifyCollectionChangedAction + { + Add, + Remove, + Replace, + Move, + Reset + } +} diff --git a/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedEventArgs.cs b/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedEventArgs.cs new file mode 100644 index 00000000..0db0911a --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedEventArgs.cs @@ -0,0 +1,109 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Newtonsoft.Json.ObservableSupport +{ + public class NotifyCollectionChangedEventArgs + { + internal NotifyCollectionChangedAction Action + { + get; + set; + } + + internal IList NewItems + { + get; + set; + } + + internal int NewStartingIndex + { + get; + set; + } + + internal IList OldItems + { + get; + set; + } + + internal int OldStartingIndex + { + get; + set; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action) + { + Action = action; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems) + : this(action) + { + NewItems = changedItems; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem) + : this(action) + { + NewItems = new List + { + changedItem + }; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems) + : this(action, newItems) + { + OldItems = oldItems; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + : this(action, changedItems) + { + NewStartingIndex = startingIndex; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index) + : this(action, changedItem) + { + NewStartingIndex = index; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem) + : this(action, newItem) + { + OldItems = new List + { + oldItem + }; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex) + : this(action, newItems, oldItems) + { + NewStartingIndex = startingIndex; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex) + : this(action, changedItems, index) + { + OldStartingIndex = oldIndex; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) + : this(action, changedItem, index) + { + OldStartingIndex = oldIndex; + } + + internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem, int index) + : this(action, newItem, oldItem) + { + NewStartingIndex = index; + } + } +} diff --git a/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedEventHandler.cs b/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedEventHandler.cs new file mode 100644 index 00000000..27ef84c0 --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/NotifyCollectionChangedEventHandler.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.ObservableSupport +{ + public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e); +} diff --git a/Newtonsoft.Json.ObservableSupport/PropertyChangingEventArgs.cs b/Newtonsoft.Json.ObservableSupport/PropertyChangingEventArgs.cs new file mode 100644 index 00000000..c5a77ef5 --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/PropertyChangingEventArgs.cs @@ -0,0 +1,18 @@ +using System; + +namespace Newtonsoft.Json.ObservableSupport +{ + public class PropertyChangingEventArgs : EventArgs + { + public virtual string PropertyName + { + get; + set; + } + + public PropertyChangingEventArgs(string propertyName) + { + PropertyName = propertyName; + } + } +} diff --git a/Newtonsoft.Json.ObservableSupport/PropertyChangingEventHandler.cs b/Newtonsoft.Json.ObservableSupport/PropertyChangingEventHandler.cs new file mode 100644 index 00000000..9fadc8ef --- /dev/null +++ b/Newtonsoft.Json.ObservableSupport/PropertyChangingEventHandler.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.ObservableSupport +{ + public delegate void PropertyChangingEventHandler(object sender, PropertyChangingEventArgs e); +} diff --git a/Newtonsoft.Json.Schema/JsonSchema.cs b/Newtonsoft.Json.Schema/JsonSchema.cs new file mode 100644 index 00000000..0f845354 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchema.cs @@ -0,0 +1,254 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; + +namespace Newtonsoft.Json.Schema +{ + public class JsonSchema + { + private readonly string _internalId = Guid.NewGuid().ToString("N"); + + public string Id + { + get; + set; + } + + public string Title + { + get; + set; + } + + public bool? Required + { + get; + set; + } + + public bool? ReadOnly + { + get; + set; + } + + public bool? Hidden + { + get; + set; + } + + public bool? Transient + { + get; + set; + } + + public string Description + { + get; + set; + } + + public JsonSchemaType? Type + { + get; + set; + } + + public string Pattern + { + get; + set; + } + + public int? MinimumLength + { + get; + set; + } + + public int? MaximumLength + { + get; + set; + } + + public double? DivisibleBy + { + get; + set; + } + + public double? Minimum + { + get; + set; + } + + public double? Maximum + { + get; + set; + } + + public bool? ExclusiveMinimum + { + get; + set; + } + + public bool? ExclusiveMaximum + { + get; + set; + } + + public int? MinimumItems + { + get; + set; + } + + public int? MaximumItems + { + get; + set; + } + + public IList Items + { + get; + set; + } + + public IDictionary Properties + { + get; + set; + } + + public JsonSchema AdditionalProperties + { + get; + set; + } + + public IDictionary PatternProperties + { + get; + set; + } + + public bool AllowAdditionalProperties + { + get; + set; + } + + public string Requires + { + get; + set; + } + + public IList Identity + { + get; + set; + } + + public IList Enum + { + get; + set; + } + + public IDictionary Options + { + get; + set; + } + + public JsonSchemaType? Disallow + { + get; + set; + } + + public JToken Default + { + get; + set; + } + + public JsonSchema Extends + { + get; + set; + } + + public string Format + { + get; + set; + } + + internal string InternalId => _internalId; + + public JsonSchema() + { + AllowAdditionalProperties = true; + } + + public static JsonSchema Read(JsonReader reader) + { + return Read(reader, new JsonSchemaResolver()); + } + + public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + ValidationUtils.ArgumentNotNull(resolver, "resolver"); + JsonSchemaBuilder jsonSchemaBuilder = new JsonSchemaBuilder(resolver); + return jsonSchemaBuilder.Parse(reader); + } + + public static JsonSchema Parse(string json) + { + return Parse(json, new JsonSchemaResolver()); + } + + public static JsonSchema Parse(string json, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(json, "json"); + JsonReader reader = new JsonTextReader(new StringReader(json)); + return Read(reader, resolver); + } + + public void WriteTo(JsonWriter writer) + { + WriteTo(writer, new JsonSchemaResolver()); + } + + public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + ValidationUtils.ArgumentNotNull(resolver, "resolver"); + JsonSchemaWriter jsonSchemaWriter = new JsonSchemaWriter(writer, resolver); + jsonSchemaWriter.WriteSchema(this); + } + + public override string ToString() + { + StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture); + JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter); + jsonTextWriter.Formatting = Formatting.Indented; + WriteTo(jsonTextWriter); + return stringWriter.ToString(); + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaBuilder.cs b/Newtonsoft.Json.Schema/JsonSchemaBuilder.cs new file mode 100644 index 00000000..00edee66 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaBuilder.cs @@ -0,0 +1,402 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace Newtonsoft.Json.Schema +{ + internal class JsonSchemaBuilder + { + private JsonReader _reader; + + private readonly IList _stack; + + private readonly JsonSchemaResolver _resolver; + + private JsonSchema _currentSchema; + + private JsonSchema CurrentSchema => _currentSchema; + + public JsonSchemaBuilder(JsonSchemaResolver resolver) + { + _stack = new List(); + _resolver = resolver; + } + + private void Push(JsonSchema value) + { + _currentSchema = value; + _stack.Add(value); + _resolver.LoadedSchemas.Add(value); + } + + private JsonSchema Pop() + { + JsonSchema currentSchema = _currentSchema; + _stack.RemoveAt(_stack.Count - 1); + _currentSchema = _stack.LastOrDefault(); + return currentSchema; + } + + internal JsonSchema Parse(JsonReader reader) + { + _reader = reader; + if (reader.TokenType == JsonToken.None) + { + _reader.Read(); + } + return BuildSchema(); + } + + private JsonSchema BuildSchema() + { + if (_reader.TokenType != JsonToken.StartObject) + { + throw new Exception("Expected StartObject while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + _reader.Read(); + if (_reader.TokenType == JsonToken.EndObject) + { + Push(new JsonSchema()); + return Pop(); + } + string text = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); + _reader.Read(); + if (text == "$ref") + { + string text2 = (string)_reader.Value; + while (_reader.Read() && _reader.TokenType != JsonToken.EndObject) + { + if (_reader.TokenType == JsonToken.StartObject) + { + throw new Exception("Found StartObject within the schema reference with the Id '{0}'".FormatWith(CultureInfo.InvariantCulture, text2)); + } + } + JsonSchema schema = _resolver.GetSchema(text2); + if (schema == null) + { + throw new Exception("Could not resolve schema reference for Id '{0}'.".FormatWith(CultureInfo.InvariantCulture, text2)); + } + return schema; + } + Push(new JsonSchema()); + ProcessSchemaProperty(text); + while (_reader.Read() && _reader.TokenType != JsonToken.EndObject) + { + text = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); + _reader.Read(); + ProcessSchemaProperty(text); + } + return Pop(); + } + + private void ProcessSchemaProperty(string propertyName) + { + switch (propertyName) + { + case "type": + CurrentSchema.Type = ProcessType(); + break; + case "id": + CurrentSchema.Id = (string)_reader.Value; + break; + case "title": + CurrentSchema.Title = (string)_reader.Value; + break; + case "description": + CurrentSchema.Description = (string)_reader.Value; + break; + case "properties": + ProcessProperties(); + break; + case "items": + ProcessItems(); + break; + case "additionalProperties": + ProcessAdditionalProperties(); + break; + case "patternProperties": + ProcessPatternProperties(); + break; + case "required": + CurrentSchema.Required = (bool)_reader.Value; + break; + case "requires": + CurrentSchema.Requires = (string)_reader.Value; + break; + case "identity": + ProcessIdentity(); + break; + case "minimum": + CurrentSchema.Minimum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture); + break; + case "maximum": + CurrentSchema.Maximum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture); + break; + case "exclusiveMinimum": + CurrentSchema.ExclusiveMinimum = (bool)_reader.Value; + break; + case "exclusiveMaximum": + CurrentSchema.ExclusiveMaximum = (bool)_reader.Value; + break; + case "maxLength": + CurrentSchema.MaximumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture); + break; + case "minLength": + CurrentSchema.MinimumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture); + break; + case "maxItems": + CurrentSchema.MaximumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture); + break; + case "minItems": + CurrentSchema.MinimumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture); + break; + case "divisibleBy": + CurrentSchema.DivisibleBy = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture); + break; + case "disallow": + CurrentSchema.Disallow = ProcessType(); + break; + case "default": + ProcessDefault(); + break; + case "hidden": + CurrentSchema.Hidden = (bool)_reader.Value; + break; + case "readonly": + CurrentSchema.ReadOnly = (bool)_reader.Value; + break; + case "format": + CurrentSchema.Format = (string)_reader.Value; + break; + case "pattern": + CurrentSchema.Pattern = (string)_reader.Value; + break; + case "options": + ProcessOptions(); + break; + case "enum": + ProcessEnum(); + break; + case "extends": + ProcessExtends(); + break; + default: + _reader.Skip(); + break; + } + } + + private void ProcessExtends() + { + CurrentSchema.Extends = BuildSchema(); + } + + private void ProcessEnum() + { + if (_reader.TokenType != JsonToken.StartArray) + { + throw new Exception("Expected StartArray token while parsing enum values, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + CurrentSchema.Enum = new List(); + while (_reader.Read() && _reader.TokenType != JsonToken.EndArray) + { + JToken item = JToken.ReadFrom(_reader); + CurrentSchema.Enum.Add(item); + } + } + + private void ProcessOptions() + { + CurrentSchema.Options = new Dictionary(new JTokenEqualityComparer()); + JsonToken tokenType = _reader.TokenType; + if (tokenType == JsonToken.StartArray) + { + JToken jToken; + while (true) + { + if (!_reader.Read() || _reader.TokenType == JsonToken.EndArray) + { + return; + } + if (_reader.TokenType != JsonToken.StartObject) + { + throw new Exception("Expect object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + string value = null; + jToken = null; + while (_reader.Read() && _reader.TokenType != JsonToken.EndObject) + { + string text = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); + _reader.Read(); + switch (text) + { + case "value": + jToken = JToken.ReadFrom(_reader); + break; + case "label": + value = (string)_reader.Value; + break; + default: + throw new Exception("Unexpected property in JSON schema option: {0}.".FormatWith(CultureInfo.InvariantCulture, text)); + } + } + if (jToken == null) + { + throw new Exception("No value specified for JSON schema option."); + } + if (CurrentSchema.Options.ContainsKey(jToken)) + { + break; + } + CurrentSchema.Options.Add(jToken, value); + } + throw new Exception("Duplicate value in JSON schema option collection: {0}".FormatWith(CultureInfo.InvariantCulture, jToken)); + } + throw new Exception("Expected array token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + + private void ProcessDefault() + { + CurrentSchema.Default = JToken.ReadFrom(_reader); + } + + private void ProcessIdentity() + { + CurrentSchema.Identity = new List(); + switch (_reader.TokenType) + { + case JsonToken.String: + CurrentSchema.Identity.Add(_reader.Value.ToString()); + break; + case JsonToken.StartArray: + while (true) + { + if (!_reader.Read() || _reader.TokenType == JsonToken.EndArray) + { + return; + } + if (_reader.TokenType != JsonToken.String) + { + break; + } + CurrentSchema.Identity.Add(_reader.Value.ToString()); + } + throw new Exception("Exception JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + default: + throw new Exception("Expected array or JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + } + + private void ProcessAdditionalProperties() + { + if (_reader.TokenType == JsonToken.Boolean) + { + CurrentSchema.AllowAdditionalProperties = (bool)_reader.Value; + } + else + { + CurrentSchema.AdditionalProperties = BuildSchema(); + } + } + + private void ProcessPatternProperties() + { + Dictionary dictionary = new Dictionary(); + if (_reader.TokenType != JsonToken.StartObject) + { + throw new Exception("Expected start object token."); + } + while (_reader.Read() && _reader.TokenType != JsonToken.EndObject) + { + string text = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); + _reader.Read(); + if (dictionary.ContainsKey(text)) + { + throw new Exception("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, text)); + } + dictionary.Add(text, BuildSchema()); + } + CurrentSchema.PatternProperties = dictionary; + } + + private void ProcessItems() + { + CurrentSchema.Items = new List(); + switch (_reader.TokenType) + { + case JsonToken.StartObject: + CurrentSchema.Items.Add(BuildSchema()); + break; + case JsonToken.StartArray: + while (_reader.Read() && _reader.TokenType != JsonToken.EndArray) + { + CurrentSchema.Items.Add(BuildSchema()); + } + break; + default: + throw new Exception("Expected array or JSON schema object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + } + + private void ProcessProperties() + { + IDictionary dictionary = new Dictionary(); + if (_reader.TokenType != JsonToken.StartObject) + { + throw new Exception("Expected StartObject token while parsing schema properties, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + while (_reader.Read() && _reader.TokenType != JsonToken.EndObject) + { + string text = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); + _reader.Read(); + if (dictionary.ContainsKey(text)) + { + throw new Exception("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, text)); + } + dictionary.Add(text, BuildSchema()); + } + CurrentSchema.Properties = dictionary; + } + + private JsonSchemaType? ProcessType() + { + switch (_reader.TokenType) + { + case JsonToken.String: + return MapType(_reader.Value.ToString()); + case JsonToken.StartArray: + { + JsonSchemaType? result = JsonSchemaType.None; + while (_reader.Read() && _reader.TokenType != JsonToken.EndArray) + { + if (_reader.TokenType != JsonToken.String) + { + throw new Exception("Exception JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + result = ((!result.HasValue) ? null : new JsonSchemaType?(result.GetValueOrDefault() | MapType(_reader.Value.ToString()))); + } + return result; + } + default: + throw new Exception("Expected array or JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType)); + } + } + + internal static JsonSchemaType MapType(string type) + { + if (!JsonSchemaConstants.JsonSchemaTypeMapping.TryGetValue(type, out JsonSchemaType value)) + { + throw new Exception("Invalid JSON schema type: {0}".FormatWith(CultureInfo.InvariantCulture, type)); + } + return value; + } + + internal static string MapType(JsonSchemaType type) + { + return JsonSchemaConstants.JsonSchemaTypeMapping.Single((KeyValuePair kv) => kv.Value == type).Key; + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaConstants.cs b/Newtonsoft.Json.Schema/JsonSchemaConstants.cs new file mode 100644 index 00000000..171fb02e --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaConstants.cs @@ -0,0 +1,109 @@ +using System.Collections.Generic; + +namespace Newtonsoft.Json.Schema +{ + internal static class JsonSchemaConstants + { + public const string TypePropertyName = "type"; + + public const string PropertiesPropertyName = "properties"; + + public const string ItemsPropertyName = "items"; + + public const string RequiredPropertyName = "required"; + + public const string PatternPropertiesPropertyName = "patternProperties"; + + public const string AdditionalPropertiesPropertyName = "additionalProperties"; + + public const string RequiresPropertyName = "requires"; + + public const string IdentityPropertyName = "identity"; + + public const string MinimumPropertyName = "minimum"; + + public const string MaximumPropertyName = "maximum"; + + public const string ExclusiveMinimumPropertyName = "exclusiveMinimum"; + + public const string ExclusiveMaximumPropertyName = "exclusiveMaximum"; + + public const string MinimumItemsPropertyName = "minItems"; + + public const string MaximumItemsPropertyName = "maxItems"; + + public const string PatternPropertyName = "pattern"; + + public const string MaximumLengthPropertyName = "maxLength"; + + public const string MinimumLengthPropertyName = "minLength"; + + public const string EnumPropertyName = "enum"; + + public const string OptionsPropertyName = "options"; + + public const string ReadOnlyPropertyName = "readonly"; + + public const string TitlePropertyName = "title"; + + public const string DescriptionPropertyName = "description"; + + public const string FormatPropertyName = "format"; + + public const string DefaultPropertyName = "default"; + + public const string TransientPropertyName = "transient"; + + public const string DivisibleByPropertyName = "divisibleBy"; + + public const string HiddenPropertyName = "hidden"; + + public const string DisallowPropertyName = "disallow"; + + public const string ExtendsPropertyName = "extends"; + + public const string IdPropertyName = "id"; + + public const string OptionValuePropertyName = "value"; + + public const string OptionLabelPropertyName = "label"; + + public const string ReferencePropertyName = "$ref"; + + public static readonly IDictionary JsonSchemaTypeMapping = new Dictionary + { + { + "string", + JsonSchemaType.String + }, + { + "object", + JsonSchemaType.Object + }, + { + "integer", + JsonSchemaType.Integer + }, + { + "number", + JsonSchemaType.Float + }, + { + "null", + JsonSchemaType.Null + }, + { + "boolean", + JsonSchemaType.Boolean + }, + { + "array", + JsonSchemaType.Array + }, + { + "any", + JsonSchemaType.Any + } + }; + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaException.cs b/Newtonsoft.Json.Schema/JsonSchemaException.cs new file mode 100644 index 00000000..04f25820 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaException.cs @@ -0,0 +1,47 @@ +using System; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Schema +{ + [Serializable] + public class JsonSchemaException : Exception + { + public int LineNumber + { + get; + private set; + } + + public int LinePosition + { + get; + private set; + } + + public JsonSchemaException() + { + } + + public JsonSchemaException(string message) + : base(message) + { + } + + public JsonSchemaException(string message, Exception innerException) + : base(message, innerException) + { + } + + public JsonSchemaException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + internal JsonSchemaException(string message, Exception innerException, int lineNumber, int linePosition) + : base(message, innerException) + { + LineNumber = lineNumber; + LinePosition = linePosition; + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaGenerator.cs b/Newtonsoft.Json.Schema/JsonSchemaGenerator.cs new file mode 100644 index 00000000..8f63e988 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaGenerator.cs @@ -0,0 +1,367 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; + +namespace Newtonsoft.Json.Schema +{ + public class JsonSchemaGenerator + { + private class TypeSchema + { + public Type Type + { + get; + private set; + } + + public JsonSchema Schema + { + get; + private set; + } + + public TypeSchema(Type type, JsonSchema schema) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(schema, "schema"); + Type = type; + Schema = schema; + } + } + + private IContractResolver _contractResolver; + + private JsonSchemaResolver _resolver; + + private IList _stack = new List(); + + private JsonSchema _currentSchema; + + public UndefinedSchemaIdHandling UndefinedSchemaIdHandling + { + get; + set; + } + + public IContractResolver ContractResolver + { + get + { + if (_contractResolver == null) + { + return DefaultContractResolver.Instance; + } + return _contractResolver; + } + set + { + _contractResolver = value; + } + } + + private JsonSchema CurrentSchema => _currentSchema; + + private void Push(TypeSchema typeSchema) + { + _currentSchema = typeSchema.Schema; + _stack.Add(typeSchema); + _resolver.LoadedSchemas.Add(typeSchema.Schema); + } + + private TypeSchema Pop() + { + TypeSchema result = _stack[_stack.Count - 1]; + _stack.RemoveAt(_stack.Count - 1); + TypeSchema typeSchema = _stack.LastOrDefault(); + if (typeSchema != null) + { + _currentSchema = typeSchema.Schema; + } + else + { + _currentSchema = null; + } + return result; + } + + public JsonSchema Generate(Type type) + { + return Generate(type, new JsonSchemaResolver(), rootSchemaNullable: false); + } + + public JsonSchema Generate(Type type, JsonSchemaResolver resolver) + { + return Generate(type, resolver, rootSchemaNullable: false); + } + + public JsonSchema Generate(Type type, bool rootSchemaNullable) + { + return Generate(type, new JsonSchemaResolver(), rootSchemaNullable); + } + + public JsonSchema Generate(Type type, JsonSchemaResolver resolver, bool rootSchemaNullable) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(resolver, "resolver"); + _resolver = resolver; + return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default, required: false); + } + + private string GetTitle(Type type) + { + JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); + if (jsonContainerAttribute != null && !string.IsNullOrEmpty(jsonContainerAttribute.Title)) + { + return jsonContainerAttribute.Title; + } + return null; + } + + private string GetDescription(Type type) + { + JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); + if (jsonContainerAttribute != null && !string.IsNullOrEmpty(jsonContainerAttribute.Description)) + { + return jsonContainerAttribute.Description; + } + return ReflectionUtils.GetAttribute(type)?.Description; + } + + private string GetTypeId(Type type, bool explicitOnly) + { + JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); + if (jsonContainerAttribute != null && !string.IsNullOrEmpty(jsonContainerAttribute.Id)) + { + return jsonContainerAttribute.Id; + } + if (!explicitOnly) + { + switch (UndefinedSchemaIdHandling) + { + case UndefinedSchemaIdHandling.UseTypeName: + return type.FullName; + case UndefinedSchemaIdHandling.UseAssemblyQualifiedName: + return type.AssemblyQualifiedName; + default: + return null; + } + } + return null; + } + + private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required) + { + ValidationUtils.ArgumentNotNull(type, "type"); + string typeId = GetTypeId(type, explicitOnly: false); + string typeId2 = GetTypeId(type, explicitOnly: true); + if (!string.IsNullOrEmpty(typeId)) + { + JsonSchema schema = _resolver.GetSchema(typeId); + if (schema != null) + { + if (valueRequired != Required.Always && !HasFlag(schema.Type, JsonSchemaType.Null)) + { + schema.Type |= JsonSchemaType.Null; + } + if (required && schema.Required != true) + { + schema.Required = true; + } + return schema; + } + } + if (_stack.Any((TypeSchema tc) => tc.Type == type)) + { + throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type)); + } + JsonContract jsonContract = ContractResolver.ResolveContract(type); + JsonConverter jsonConverter; + if ((jsonConverter = jsonContract.Converter) != null || (jsonConverter = jsonContract.InternalConverter) != null) + { + JsonSchema schema2 = jsonConverter.GetSchema(); + if (schema2 != null) + { + return schema2; + } + } + Push(new TypeSchema(type, new JsonSchema())); + if (typeId2 != null) + { + CurrentSchema.Id = typeId2; + } + if (required) + { + CurrentSchema.Required = true; + } + CurrentSchema.Title = GetTitle(type); + CurrentSchema.Description = GetDescription(type); + if (jsonConverter != null) + { + CurrentSchema.Type = JsonSchemaType.Any; + } + else if (jsonContract is JsonDictionaryContract) + { + CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); + ReflectionUtils.GetDictionaryKeyValueTypes(type, out Type keyType, out Type valueType); + if (keyType != null && typeof(IConvertible).IsAssignableFrom(keyType)) + { + CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, required: false); + } + } + else if (jsonContract is JsonArrayContract) + { + CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired); + CurrentSchema.Id = GetTypeId(type, explicitOnly: false); + bool flag = (JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute)?.AllowNullItems ?? true; + Type collectionItemType = ReflectionUtils.GetCollectionItemType(type); + if (collectionItemType != null) + { + CurrentSchema.Items = new List(); + CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!flag) ? Required.Always : Required.Default, required: false)); + } + } + else if (jsonContract is JsonPrimitiveContract) + { + CurrentSchema.Type = GetJsonSchemaType(type, valueRequired); + if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), inherit: true)) + { + CurrentSchema.Enum = new List(); + CurrentSchema.Options = new Dictionary(); + EnumValues namesAndValues = EnumUtils.GetNamesAndValues(type); + foreach (EnumValue item in namesAndValues) + { + JToken jToken = JToken.FromObject(item.Value); + CurrentSchema.Enum.Add(jToken); + CurrentSchema.Options.Add(jToken, item.Name); + } + } + } + else if (jsonContract is JsonObjectContract) + { + CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); + CurrentSchema.Id = GetTypeId(type, explicitOnly: false); + GenerateObjectSchema(type, (JsonObjectContract)jsonContract); + } + else if (jsonContract is JsonISerializableContract) + { + CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); + CurrentSchema.Id = GetTypeId(type, explicitOnly: false); + GenerateISerializableContract(type, (JsonISerializableContract)jsonContract); + } + else if (jsonContract is JsonStringContract) + { + JsonSchemaType value = (!ReflectionUtils.IsNullable(jsonContract.UnderlyingType)) ? JsonSchemaType.String : AddNullType(JsonSchemaType.String, valueRequired); + CurrentSchema.Type = value; + } + else + { + if (!(jsonContract is JsonLinqContract)) + { + throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContract)); + } + CurrentSchema.Type = JsonSchemaType.Any; + } + return Pop().Schema; + } + + private JsonSchemaType AddNullType(JsonSchemaType type, Required valueRequired) + { + if (valueRequired != Required.Always) + { + return type | JsonSchemaType.Null; + } + return type; + } + + private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) + { + return (value & flag) == flag; + } + + private void GenerateObjectSchema(Type type, JsonObjectContract contract) + { + CurrentSchema.Properties = new Dictionary(); + foreach (JsonProperty property in contract.Properties) + { + if (!property.Ignored) + { + bool flag = property.NullValueHandling == NullValueHandling.Ignore || HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) || property.ShouldSerialize != null || property.GetIsSpecified != null; + JsonSchema jsonSchema = GenerateInternal(property.PropertyType, property.Required, !flag); + if (property.DefaultValue != null) + { + jsonSchema.Default = JToken.FromObject(property.DefaultValue); + } + CurrentSchema.Properties.Add(property.PropertyName, jsonSchema); + } + } + if (type.IsSealed) + { + CurrentSchema.AllowAdditionalProperties = false; + } + } + + private void GenerateISerializableContract(Type type, JsonISerializableContract contract) + { + CurrentSchema.AllowAdditionalProperties = true; + } + + internal static bool HasFlag(JsonSchemaType? value, JsonSchemaType flag) + { + if (!value.HasValue) + { + return true; + } + return (value & flag) == flag; + } + + private JsonSchemaType GetJsonSchemaType(Type type, Required valueRequired) + { + JsonSchemaType jsonSchemaType = JsonSchemaType.None; + if (valueRequired != Required.Always && ReflectionUtils.IsNullable(type)) + { + jsonSchemaType = JsonSchemaType.Null; + if (ReflectionUtils.IsNullableType(type)) + { + type = Nullable.GetUnderlyingType(type); + } + } + TypeCode typeCode = Type.GetTypeCode(type); + switch (typeCode) + { + case TypeCode.Empty: + case TypeCode.Object: + return jsonSchemaType | JsonSchemaType.String; + case TypeCode.DBNull: + return jsonSchemaType | JsonSchemaType.Null; + case TypeCode.Boolean: + return jsonSchemaType | JsonSchemaType.Boolean; + case TypeCode.Char: + return jsonSchemaType | JsonSchemaType.String; + case TypeCode.SByte: + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + return jsonSchemaType | JsonSchemaType.Integer; + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return jsonSchemaType | JsonSchemaType.Float; + case TypeCode.DateTime: + return jsonSchemaType | JsonSchemaType.String; + case TypeCode.String: + return jsonSchemaType | JsonSchemaType.String; + default: + throw new Exception("Unexpected type code '{0}' for type '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeCode, type)); + } + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaModel.cs b/Newtonsoft.Json.Schema/JsonSchemaModel.cs new file mode 100644 index 00000000..7ccb0a84 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaModel.cs @@ -0,0 +1,207 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Schema +{ + internal class JsonSchemaModel + { + public bool Required + { + get; + set; + } + + public JsonSchemaType Type + { + get; + set; + } + + public int? MinimumLength + { + get; + set; + } + + public int? MaximumLength + { + get; + set; + } + + public double? DivisibleBy + { + get; + set; + } + + public double? Minimum + { + get; + set; + } + + public double? Maximum + { + get; + set; + } + + public bool ExclusiveMinimum + { + get; + set; + } + + public bool ExclusiveMaximum + { + get; + set; + } + + public int? MinimumItems + { + get; + set; + } + + public int? MaximumItems + { + get; + set; + } + + public IList Patterns + { + get; + set; + } + + public IList Items + { + get; + set; + } + + public IDictionary Properties + { + get; + set; + } + + public IDictionary PatternProperties + { + get; + set; + } + + public JsonSchemaModel AdditionalProperties + { + get; + set; + } + + public bool AllowAdditionalProperties + { + get; + set; + } + + public IList Enum + { + get; + set; + } + + public JsonSchemaType Disallow + { + get; + set; + } + + public JsonSchemaModel() + { + Type = JsonSchemaType.Any; + AllowAdditionalProperties = true; + Required = false; + } + + public static JsonSchemaModel Create(IList schemata) + { + JsonSchemaModel jsonSchemaModel = new JsonSchemaModel(); + foreach (JsonSchema schematum in schemata) + { + Combine(jsonSchemaModel, schematum); + } + return jsonSchemaModel; + } + + private static void Combine(JsonSchemaModel model, JsonSchema schema) + { + int required2; + if (!model.Required) + { + bool? required = schema.Required; + required2 = ((required.HasValue && required.Value) ? 1 : 0); + } + else + { + required2 = 1; + } + model.Required = ((byte)required2 != 0); + JsonSchemaType type = model.Type; + JsonSchemaType? type2 = schema.Type; + model.Type = (type & ((!type2.HasValue) ? JsonSchemaType.Any : type2.Value)); + model.MinimumLength = MathUtils.Max(model.MinimumLength, schema.MinimumLength); + model.MaximumLength = MathUtils.Min(model.MaximumLength, schema.MaximumLength); + model.DivisibleBy = MathUtils.Max(model.DivisibleBy, schema.DivisibleBy); + model.Minimum = MathUtils.Max(model.Minimum, schema.Minimum); + model.Maximum = MathUtils.Max(model.Maximum, schema.Maximum); + int exclusiveMinimum2; + if (!model.ExclusiveMinimum) + { + bool? exclusiveMinimum = schema.ExclusiveMinimum; + exclusiveMinimum2 = ((exclusiveMinimum.HasValue && exclusiveMinimum.Value) ? 1 : 0); + } + else + { + exclusiveMinimum2 = 1; + } + model.ExclusiveMinimum = ((byte)exclusiveMinimum2 != 0); + int exclusiveMaximum2; + if (!model.ExclusiveMaximum) + { + bool? exclusiveMaximum = schema.ExclusiveMaximum; + exclusiveMaximum2 = ((exclusiveMaximum.HasValue && exclusiveMaximum.Value) ? 1 : 0); + } + else + { + exclusiveMaximum2 = 1; + } + model.ExclusiveMaximum = ((byte)exclusiveMaximum2 != 0); + model.MinimumItems = MathUtils.Max(model.MinimumItems, schema.MinimumItems); + model.MaximumItems = MathUtils.Min(model.MaximumItems, schema.MaximumItems); + model.AllowAdditionalProperties = (model.AllowAdditionalProperties && schema.AllowAdditionalProperties); + if (schema.Enum != null) + { + if (model.Enum == null) + { + model.Enum = new List(); + } + model.Enum.AddRangeDistinct(schema.Enum, new JTokenEqualityComparer()); + } + JsonSchemaType disallow = model.Disallow; + JsonSchemaType? disallow2 = schema.Disallow; + model.Disallow = (disallow | (disallow2.HasValue ? disallow2.Value : JsonSchemaType.None)); + if (schema.Pattern != null) + { + if (model.Patterns == null) + { + model.Patterns = new List(); + } + model.Patterns.AddDistinct(schema.Pattern); + } + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaModelBuilder.cs b/Newtonsoft.Json.Schema/JsonSchemaModelBuilder.cs new file mode 100644 index 00000000..24941eff --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaModelBuilder.cs @@ -0,0 +1,144 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Newtonsoft.Json.Schema +{ + internal class JsonSchemaModelBuilder + { + private JsonSchemaNodeCollection _nodes = new JsonSchemaNodeCollection(); + + private Dictionary _nodeModels = new Dictionary(); + + private JsonSchemaNode _node; + + public JsonSchemaModel Build(JsonSchema schema) + { + _nodes = new JsonSchemaNodeCollection(); + _node = AddSchema(null, schema); + _nodeModels = new Dictionary(); + return BuildNodeModel(_node); + } + + public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema) + { + string id; + if (existingNode != null) + { + if (existingNode.Schemas.Contains(schema)) + { + return existingNode; + } + id = JsonSchemaNode.GetId(existingNode.Schemas.Union(new JsonSchema[1] + { + schema + })); + } + else + { + id = JsonSchemaNode.GetId(new JsonSchema[1] + { + schema + }); + } + if (_nodes.Contains(id)) + { + return _nodes[id]; + } + JsonSchemaNode jsonSchemaNode = (existingNode == null) ? new JsonSchemaNode(schema) : existingNode.Combine(schema); + _nodes.Add(jsonSchemaNode); + AddProperties(schema.Properties, jsonSchemaNode.Properties); + AddProperties(schema.PatternProperties, jsonSchemaNode.PatternProperties); + if (schema.Items != null) + { + for (int i = 0; i < schema.Items.Count; i++) + { + AddItem(jsonSchemaNode, i, schema.Items[i]); + } + } + if (schema.AdditionalProperties != null) + { + AddAdditionalProperties(jsonSchemaNode, schema.AdditionalProperties); + } + if (schema.Extends != null) + { + jsonSchemaNode = AddSchema(jsonSchemaNode, schema.Extends); + } + return jsonSchemaNode; + } + + public void AddProperties(IDictionary source, IDictionary target) + { + if (source != null) + { + foreach (KeyValuePair item in source) + { + AddProperty(target, item.Key, item.Value); + } + } + } + + public void AddProperty(IDictionary target, string propertyName, JsonSchema schema) + { + target.TryGetValue(propertyName, out JsonSchemaNode value); + target[propertyName] = AddSchema(value, schema); + } + + public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema) + { + JsonSchemaNode existingNode = (parentNode.Items.Count <= index) ? null : parentNode.Items[index]; + JsonSchemaNode jsonSchemaNode = AddSchema(existingNode, schema); + if (parentNode.Items.Count <= index) + { + parentNode.Items.Add(jsonSchemaNode); + } + else + { + parentNode.Items[index] = jsonSchemaNode; + } + } + + public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema) + { + parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema); + } + + private JsonSchemaModel BuildNodeModel(JsonSchemaNode node) + { + if (_nodeModels.TryGetValue(node, out JsonSchemaModel value)) + { + return value; + } + value = JsonSchemaModel.Create(node.Schemas); + _nodeModels[node] = value; + foreach (KeyValuePair property in node.Properties) + { + if (value.Properties == null) + { + value.Properties = new Dictionary(); + } + value.Properties[property.Key] = BuildNodeModel(property.Value); + } + foreach (KeyValuePair patternProperty in node.PatternProperties) + { + if (value.PatternProperties == null) + { + value.PatternProperties = new Dictionary(); + } + value.PatternProperties[patternProperty.Key] = BuildNodeModel(patternProperty.Value); + } + for (int i = 0; i < node.Items.Count; i++) + { + if (value.Items == null) + { + value.Items = new List(); + } + value.Items.Add(BuildNodeModel(node.Items[i])); + } + if (node.AdditionalProperties != null) + { + value.AdditionalProperties = BuildNodeModel(node.AdditionalProperties); + } + return value; + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaNode.cs b/Newtonsoft.Json.Schema/JsonSchemaNode.cs new file mode 100644 index 00000000..fe4d48e5 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaNode.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace Newtonsoft.Json.Schema +{ + internal class JsonSchemaNode + { + public string Id + { + get; + private set; + } + + public ReadOnlyCollection Schemas + { + get; + private set; + } + + public Dictionary Properties + { + get; + private set; + } + + public Dictionary PatternProperties + { + get; + private set; + } + + public List Items + { + get; + private set; + } + + public JsonSchemaNode AdditionalProperties + { + get; + set; + } + + public JsonSchemaNode(JsonSchema schema) + { + Schemas = new ReadOnlyCollection(new JsonSchema[1] + { + schema + }); + Properties = new Dictionary(); + PatternProperties = new Dictionary(); + Items = new List(); + Id = GetId(Schemas); + } + + private JsonSchemaNode(JsonSchemaNode source, JsonSchema schema) + { + Schemas = new ReadOnlyCollection(source.Schemas.Union(new JsonSchema[1] + { + schema + }).ToList()); + Properties = new Dictionary(source.Properties); + PatternProperties = new Dictionary(source.PatternProperties); + Items = new List(source.Items); + AdditionalProperties = source.AdditionalProperties; + Id = GetId(Schemas); + } + + public JsonSchemaNode Combine(JsonSchema schema) + { + return new JsonSchemaNode(this, schema); + } + + public static string GetId(IEnumerable schemata) + { + return string.Join("-", (from s in schemata + select s.InternalId).OrderBy((string id) => id, StringComparer.Ordinal).ToArray()); + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaNodeCollection.cs b/Newtonsoft.Json.Schema/JsonSchemaNodeCollection.cs new file mode 100644 index 00000000..54c20f37 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaNodeCollection.cs @@ -0,0 +1,12 @@ +using System.Collections.ObjectModel; + +namespace Newtonsoft.Json.Schema +{ + internal class JsonSchemaNodeCollection : KeyedCollection + { + protected override string GetKeyForItem(JsonSchemaNode item) + { + return item.Id; + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaResolver.cs b/Newtonsoft.Json.Schema/JsonSchemaResolver.cs new file mode 100644 index 00000000..e5a827f4 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaResolver.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Newtonsoft.Json.Schema +{ + public class JsonSchemaResolver + { + public IList LoadedSchemas + { + get; + protected set; + } + + public JsonSchemaResolver() + { + LoadedSchemas = new List(); + } + + public virtual JsonSchema GetSchema(string id) + { + return LoadedSchemas.SingleOrDefault((JsonSchema s) => s.Id == id); + } + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaType.cs b/Newtonsoft.Json.Schema/JsonSchemaType.cs new file mode 100644 index 00000000..a5ef451a --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaType.cs @@ -0,0 +1,18 @@ +using System; + +namespace Newtonsoft.Json.Schema +{ + [Flags] + public enum JsonSchemaType + { + None = 0x0, + String = 0x1, + Float = 0x2, + Integer = 0x4, + Boolean = 0x8, + Object = 0x10, + Array = 0x20, + Null = 0x40, + Any = 0x7F + } +} diff --git a/Newtonsoft.Json.Schema/JsonSchemaWriter.cs b/Newtonsoft.Json.Schema/JsonSchemaWriter.cs new file mode 100644 index 00000000..fdf0e627 --- /dev/null +++ b/Newtonsoft.Json.Schema/JsonSchemaWriter.cs @@ -0,0 +1,204 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Newtonsoft.Json.Schema +{ + internal class JsonSchemaWriter + { + private readonly JsonWriter _writer; + + private readonly JsonSchemaResolver _resolver; + + public JsonSchemaWriter(JsonWriter writer, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + _writer = writer; + _resolver = resolver; + } + + private void ReferenceOrWriteSchema(JsonSchema schema) + { + if (schema.Id != null && _resolver.GetSchema(schema.Id) != null) + { + _writer.WriteStartObject(); + _writer.WritePropertyName("$ref"); + _writer.WriteValue(schema.Id); + _writer.WriteEndObject(); + } + else + { + WriteSchema(schema); + } + } + + public void WriteSchema(JsonSchema schema) + { + ValidationUtils.ArgumentNotNull(schema, "schema"); + if (!_resolver.LoadedSchemas.Contains(schema)) + { + _resolver.LoadedSchemas.Add(schema); + } + _writer.WriteStartObject(); + WritePropertyIfNotNull(_writer, "id", schema.Id); + WritePropertyIfNotNull(_writer, "title", schema.Title); + WritePropertyIfNotNull(_writer, "description", schema.Description); + WritePropertyIfNotNull(_writer, "required", schema.Required); + WritePropertyIfNotNull(_writer, "readonly", schema.ReadOnly); + WritePropertyIfNotNull(_writer, "hidden", schema.Hidden); + WritePropertyIfNotNull(_writer, "transient", schema.Transient); + if (schema.Type.HasValue) + { + WriteType("type", _writer, schema.Type.Value); + } + if (!schema.AllowAdditionalProperties) + { + _writer.WritePropertyName("additionalProperties"); + _writer.WriteValue(schema.AllowAdditionalProperties); + } + else if (schema.AdditionalProperties != null) + { + _writer.WritePropertyName("additionalProperties"); + ReferenceOrWriteSchema(schema.AdditionalProperties); + } + WriteSchemaDictionaryIfNotNull(_writer, "properties", schema.Properties); + WriteSchemaDictionaryIfNotNull(_writer, "patternProperties", schema.PatternProperties); + WriteItems(schema); + WritePropertyIfNotNull(_writer, "minimum", schema.Minimum); + WritePropertyIfNotNull(_writer, "maximum", schema.Maximum); + WritePropertyIfNotNull(_writer, "exclusiveMinimum", schema.ExclusiveMinimum); + WritePropertyIfNotNull(_writer, "exclusiveMaximum", schema.ExclusiveMaximum); + WritePropertyIfNotNull(_writer, "minLength", schema.MinimumLength); + WritePropertyIfNotNull(_writer, "maxLength", schema.MaximumLength); + WritePropertyIfNotNull(_writer, "minItems", schema.MinimumItems); + WritePropertyIfNotNull(_writer, "maxItems", schema.MaximumItems); + WritePropertyIfNotNull(_writer, "divisibleBy", schema.DivisibleBy); + WritePropertyIfNotNull(_writer, "format", schema.Format); + WritePropertyIfNotNull(_writer, "pattern", schema.Pattern); + if (schema.Enum != null) + { + _writer.WritePropertyName("enum"); + _writer.WriteStartArray(); + foreach (JToken item in schema.Enum) + { + item.WriteTo(_writer); + } + _writer.WriteEndArray(); + } + if (schema.Default != null) + { + _writer.WritePropertyName("default"); + schema.Default.WriteTo(_writer); + } + if (schema.Options != null) + { + _writer.WritePropertyName("options"); + _writer.WriteStartArray(); + foreach (KeyValuePair option in schema.Options) + { + _writer.WriteStartObject(); + _writer.WritePropertyName("value"); + option.Key.WriteTo(_writer); + if (option.Value != null) + { + _writer.WritePropertyName("label"); + _writer.WriteValue(option.Value); + } + _writer.WriteEndObject(); + } + _writer.WriteEndArray(); + } + if (schema.Disallow.HasValue) + { + WriteType("disallow", _writer, schema.Disallow.Value); + } + if (schema.Extends != null) + { + _writer.WritePropertyName("extends"); + ReferenceOrWriteSchema(schema.Extends); + } + _writer.WriteEndObject(); + } + + private void WriteSchemaDictionaryIfNotNull(JsonWriter writer, string propertyName, IDictionary properties) + { + if (properties != null) + { + writer.WritePropertyName(propertyName); + writer.WriteStartObject(); + foreach (KeyValuePair property in properties) + { + writer.WritePropertyName(property.Key); + ReferenceOrWriteSchema(property.Value); + } + writer.WriteEndObject(); + } + } + + private void WriteItems(JsonSchema schema) + { + if (!CollectionUtils.IsNullOrEmpty(schema.Items)) + { + _writer.WritePropertyName("items"); + if (schema.Items.Count == 1) + { + ReferenceOrWriteSchema(schema.Items[0]); + } + else + { + _writer.WriteStartArray(); + foreach (JsonSchema item in schema.Items) + { + ReferenceOrWriteSchema(item); + } + _writer.WriteEndArray(); + } + } + } + + private void WriteType(string propertyName, JsonWriter writer, JsonSchemaType type) + { + IList list2; + if (Enum.IsDefined(typeof(JsonSchemaType), type)) + { + List list = new List(); + list.Add(type); + list2 = list; + } + else + { + list2 = (from v in EnumUtils.GetFlagsValues(type) + where v != JsonSchemaType.None + select v).ToList(); + } + if (list2.Count != 0) + { + writer.WritePropertyName(propertyName); + if (list2.Count == 1) + { + writer.WriteValue(JsonSchemaBuilder.MapType(list2[0])); + } + else + { + writer.WriteStartArray(); + foreach (JsonSchemaType item in list2) + { + writer.WriteValue(JsonSchemaBuilder.MapType(item)); + } + writer.WriteEndArray(); + } + } + } + + private void WritePropertyIfNotNull(JsonWriter writer, string propertyName, object value) + { + if (value != null) + { + writer.WritePropertyName(propertyName); + writer.WriteValue(value); + } + } + } +} diff --git a/Newtonsoft.Json.Schema/SchemaExtensions.cs b/Newtonsoft.Json.Schema/SchemaExtensions.cs new file mode 100644 index 00000000..126bee50 --- /dev/null +++ b/Newtonsoft.Json.Schema/SchemaExtensions.cs @@ -0,0 +1,40 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; + +namespace Newtonsoft.Json.Schema +{ + public static class SchemaExtensions + { + public static bool IsValid(this JToken source, JsonSchema schema) + { + bool valid = true; + source.Validate(schema, delegate + { + valid = false; + }); + return valid; + } + + public static void Validate(this JToken source, JsonSchema schema) + { + source.Validate(schema, null); + } + + public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler) + { + ValidationUtils.ArgumentNotNull(source, "source"); + ValidationUtils.ArgumentNotNull(schema, "schema"); + using (JsonValidatingReader jsonValidatingReader = new JsonValidatingReader(source.CreateReader())) + { + jsonValidatingReader.Schema = schema; + if (validationEventHandler != null) + { + jsonValidatingReader.ValidationEventHandler += validationEventHandler; + } + while (jsonValidatingReader.Read()) + { + } + } + } + } +} diff --git a/Newtonsoft.Json.Schema/UndefinedSchemaIdHandling.cs b/Newtonsoft.Json.Schema/UndefinedSchemaIdHandling.cs new file mode 100644 index 00000000..ae5b126c --- /dev/null +++ b/Newtonsoft.Json.Schema/UndefinedSchemaIdHandling.cs @@ -0,0 +1,9 @@ +namespace Newtonsoft.Json.Schema +{ + public enum UndefinedSchemaIdHandling + { + None, + UseTypeName, + UseAssemblyQualifiedName + } +} diff --git a/Newtonsoft.Json.Schema/ValidationEventArgs.cs b/Newtonsoft.Json.Schema/ValidationEventArgs.cs new file mode 100644 index 00000000..c0eb70b8 --- /dev/null +++ b/Newtonsoft.Json.Schema/ValidationEventArgs.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json.Utilities; +using System; + +namespace Newtonsoft.Json.Schema +{ + public class ValidationEventArgs : EventArgs + { + private readonly JsonSchemaException _ex; + + public JsonSchemaException Exception => _ex; + + public string Message => _ex.Message; + + internal ValidationEventArgs(JsonSchemaException ex) + { + ValidationUtils.ArgumentNotNull(ex, "ex"); + _ex = ex; + } + } +} diff --git a/Newtonsoft.Json.Schema/ValidationEventHandler.cs b/Newtonsoft.Json.Schema/ValidationEventHandler.cs new file mode 100644 index 00000000..015da9ac --- /dev/null +++ b/Newtonsoft.Json.Schema/ValidationEventHandler.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.Schema +{ + public delegate void ValidationEventHandler(object sender, ValidationEventArgs e); +} diff --git a/Newtonsoft.Json.Serialization/CachedAttributeGetter.cs b/Newtonsoft.Json.Serialization/CachedAttributeGetter.cs new file mode 100644 index 00000000..b97d5961 --- /dev/null +++ b/Newtonsoft.Json.Serialization/CachedAttributeGetter.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Reflection; + +namespace Newtonsoft.Json.Serialization +{ + internal static class CachedAttributeGetter where T : Attribute + { + private static readonly ThreadSafeStore TypeAttributeCache = new ThreadSafeStore(JsonTypeReflector.GetAttribute); + + public static T GetAttribute(ICustomAttributeProvider type) + { + return TypeAttributeCache.Get(type); + } + } +} diff --git a/Newtonsoft.Json.Serialization/CamelCasePropertyNamesContractResolver.cs b/Newtonsoft.Json.Serialization/CamelCasePropertyNamesContractResolver.cs new file mode 100644 index 00000000..8a9dc0ad --- /dev/null +++ b/Newtonsoft.Json.Serialization/CamelCasePropertyNamesContractResolver.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json.Utilities; + +namespace Newtonsoft.Json.Serialization +{ + public class CamelCasePropertyNamesContractResolver : DefaultContractResolver + { + public CamelCasePropertyNamesContractResolver() + : base(shareCache: true) + { + } + + protected internal override string ResolvePropertyName(string propertyName) + { + return StringUtils.ToCamelCase(propertyName); + } + } +} diff --git a/Newtonsoft.Json.Serialization/DefaultContractResolver.cs b/Newtonsoft.Json.Serialization/DefaultContractResolver.cs new file mode 100644 index 00000000..f3fb7a30 --- /dev/null +++ b/Newtonsoft.Json.Serialization/DefaultContractResolver.cs @@ -0,0 +1,637 @@ +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Serialization +{ + public class DefaultContractResolver : IContractResolver + { + private static readonly IContractResolver _instance = new DefaultContractResolver(shareCache: true); + + private static readonly IList BuiltInConverters = new List + { + new KeyValuePairConverter(), + new XmlNodeConverter(), + new BsonObjectIdConverter() + }; + + private static Dictionary _sharedContractCache; + + private static readonly object _typeContractCacheLock = new object(); + + private Dictionary _instanceContractCache; + + private readonly bool _sharedCache; + + internal static IContractResolver Instance => _instance; + + public bool DynamicCodeGeneration => JsonTypeReflector.DynamicCodeGeneration; + + public BindingFlags DefaultMembersSearchFlags + { + get; + set; + } + + public bool SerializeCompilerGeneratedMembers + { + get; + set; + } + + public DefaultContractResolver() + : this(shareCache: false) + { + } + + public DefaultContractResolver(bool shareCache) + { + DefaultMembersSearchFlags = (BindingFlags.Instance | BindingFlags.Public); + _sharedCache = shareCache; + } + + private Dictionary GetCache() + { + if (_sharedCache) + { + return _sharedContractCache; + } + return _instanceContractCache; + } + + private void UpdateCache(Dictionary cache) + { + if (_sharedCache) + { + _sharedContractCache = cache; + } + else + { + _instanceContractCache = cache; + } + } + + public virtual JsonContract ResolveContract(Type type) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + ResolverContractKey key = new ResolverContractKey(GetType(), type); + Dictionary cache = GetCache(); + if (cache == null || !cache.TryGetValue(key, out JsonContract value)) + { + value = CreateContract(type); + lock (_typeContractCacheLock) + { + cache = GetCache(); + Dictionary dictionary = (cache == null) ? new Dictionary() : new Dictionary(cache); + dictionary[key] = value; + UpdateCache(dictionary); + return value; + } + } + return value; + } + + protected virtual List GetSerializableMembers(Type objectType) + { + DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType); + List list = (from m in ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags) + where !ReflectionUtils.IsIndexedProperty(m) + select m).ToList(); + List list2 = (from m in ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) + where !ReflectionUtils.IsIndexedProperty(m) + select m).ToList(); + List list3 = new List(); + foreach (MemberInfo item in list2) + { + if (SerializeCompilerGeneratedMembers || !item.IsDefined(typeof(CompilerGeneratedAttribute), inherit: true)) + { + if (list.Contains(item)) + { + list3.Add(item); + } + else if (JsonTypeReflector.GetAttribute(item) != null) + { + list3.Add(item); + } + else if (dataContractAttribute != null && JsonTypeReflector.GetAttribute(item) != null) + { + list3.Add(item); + } + } + } + if (objectType.AssignableToTypeName("System.Data.Objects.DataClasses.EntityObject", out Type _)) + { + list3 = list3.Where(ShouldSerializeEntityMember).ToList(); + } + return list3; + } + + private bool ShouldSerializeEntityMember(MemberInfo memberInfo) + { + PropertyInfo propertyInfo = memberInfo as PropertyInfo; + if (propertyInfo != null && propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().FullName == "System.Data.Objects.DataClasses.EntityReference`1") + { + return false; + } + return true; + } + + protected virtual JsonObjectContract CreateObjectContract(Type objectType) + { + JsonObjectContract jsonObjectContract = new JsonObjectContract(objectType); + InitializeContract(jsonObjectContract); + jsonObjectContract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType); + jsonObjectContract.Properties.AddRange(CreateProperties(jsonObjectContract.UnderlyingType, jsonObjectContract.MemberSerialization)); + if (objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any((ConstructorInfo c) => c.IsDefined(typeof(JsonConstructorAttribute), inherit: true))) + { + ConstructorInfo attributeConstructor = GetAttributeConstructor(objectType); + if (attributeConstructor != null) + { + jsonObjectContract.OverrideConstructor = attributeConstructor; + jsonObjectContract.ConstructorParameters.AddRange(CreateConstructorParameters(attributeConstructor, jsonObjectContract.Properties)); + } + } + else if (jsonObjectContract.DefaultCreator == null || jsonObjectContract.DefaultCreatorNonPublic) + { + ConstructorInfo parametrizedConstructor = GetParametrizedConstructor(objectType); + if (parametrizedConstructor != null) + { + jsonObjectContract.ParametrizedConstructor = parametrizedConstructor; + jsonObjectContract.ConstructorParameters.AddRange(CreateConstructorParameters(parametrizedConstructor, jsonObjectContract.Properties)); + } + } + return jsonObjectContract; + } + + private ConstructorInfo GetAttributeConstructor(Type objectType) + { + IList list = (from c in objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + where c.IsDefined(typeof(JsonConstructorAttribute), inherit: true) + select c).ToList(); + if (list.Count > 1) + { + throw new Exception("Multiple constructors with the JsonConstructorAttribute."); + } + if (list.Count == 1) + { + return list[0]; + } + return null; + } + + private ConstructorInfo GetParametrizedConstructor(Type objectType) + { + IList constructors = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public); + if (constructors.Count == 1) + { + return constructors[0]; + } + return null; + } + + protected virtual IList CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) + { + ParameterInfo[] parameters = constructor.GetParameters(); + JsonPropertyCollection jsonPropertyCollection = new JsonPropertyCollection(constructor.DeclaringType); + ParameterInfo[] array = parameters; + foreach (ParameterInfo parameterInfo in array) + { + JsonProperty jsonProperty = memberProperties.GetClosestMatchProperty(parameterInfo.Name); + if (jsonProperty != null && jsonProperty.PropertyType != parameterInfo.ParameterType) + { + jsonProperty = null; + } + JsonProperty jsonProperty2 = CreatePropertyFromConstructorParameter(jsonProperty, parameterInfo); + if (jsonProperty2 != null) + { + jsonPropertyCollection.AddProperty(jsonProperty2); + } + } + return jsonPropertyCollection; + } + + protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo) + { + JsonProperty jsonProperty = new JsonProperty(); + jsonProperty.PropertyType = parameterInfo.ParameterType; + SetPropertySettingsFromAttributes(jsonProperty, parameterInfo, parameterInfo.Name, parameterInfo.Member.DeclaringType, MemberSerialization.OptOut, out bool _, out bool _); + jsonProperty.Readable = false; + jsonProperty.Writable = true; + if (matchingMemberProperty != null) + { + jsonProperty.PropertyName = ((!(jsonProperty.PropertyName != parameterInfo.Name)) ? matchingMemberProperty.PropertyName : jsonProperty.PropertyName); + jsonProperty.Converter = (jsonProperty.Converter ?? matchingMemberProperty.Converter); + jsonProperty.MemberConverter = (jsonProperty.MemberConverter ?? matchingMemberProperty.MemberConverter); + jsonProperty.DefaultValue = (jsonProperty.DefaultValue ?? matchingMemberProperty.DefaultValue); + jsonProperty.Required = ((jsonProperty.Required == Required.Default) ? matchingMemberProperty.Required : jsonProperty.Required); + jsonProperty.IsReference = ((!jsonProperty.IsReference.HasValue) ? matchingMemberProperty.IsReference : jsonProperty.IsReference); + jsonProperty.NullValueHandling = ((!jsonProperty.NullValueHandling.HasValue) ? matchingMemberProperty.NullValueHandling : jsonProperty.NullValueHandling); + jsonProperty.DefaultValueHandling = ((!jsonProperty.DefaultValueHandling.HasValue) ? matchingMemberProperty.DefaultValueHandling : jsonProperty.DefaultValueHandling); + jsonProperty.ReferenceLoopHandling = ((!jsonProperty.ReferenceLoopHandling.HasValue) ? matchingMemberProperty.ReferenceLoopHandling : jsonProperty.ReferenceLoopHandling); + jsonProperty.ObjectCreationHandling = ((!jsonProperty.ObjectCreationHandling.HasValue) ? matchingMemberProperty.ObjectCreationHandling : jsonProperty.ObjectCreationHandling); + jsonProperty.TypeNameHandling = ((!jsonProperty.TypeNameHandling.HasValue) ? matchingMemberProperty.TypeNameHandling : jsonProperty.TypeNameHandling); + } + return jsonProperty; + } + + protected virtual JsonConverter ResolveContractConverter(Type objectType) + { + return JsonTypeReflector.GetJsonConverter(objectType, objectType); + } + + private Func GetDefaultCreator(Type createdType) + { + return JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(createdType); + } + + [SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Runtime.Serialization.DataContractAttribute.#get_IsReference()")] + private void InitializeContract(JsonContract contract) + { + JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.UnderlyingType); + if (jsonContainerAttribute != null) + { + contract.IsReference = jsonContainerAttribute._isReference; + } + else + { + DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.UnderlyingType); + if (dataContractAttribute != null && dataContractAttribute.IsReference) + { + contract.IsReference = true; + } + } + contract.Converter = ResolveContractConverter(contract.UnderlyingType); + contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.UnderlyingType); + if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, nonPublic: true) || contract.CreatedType.IsValueType) + { + contract.DefaultCreator = GetDefaultCreator(contract.CreatedType); + contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType && ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null); + } + ResolveCallbackMethods(contract, contract.UnderlyingType); + } + + private void ResolveCallbackMethods(JsonContract contract, Type t) + { + if (t.BaseType != null) + { + ResolveCallbackMethods(contract, t.BaseType); + } + GetCallbackMethodsForType(t, out MethodInfo onSerializing, out MethodInfo onSerialized, out MethodInfo onDeserializing, out MethodInfo onDeserialized, out MethodInfo onError); + if (onSerializing != null) + { + contract.OnSerializing = onSerializing; + } + if (onSerialized != null) + { + contract.OnSerialized = onSerialized; + } + if (onDeserializing != null) + { + contract.OnDeserializing = onDeserializing; + } + if (onDeserialized != null) + { + contract.OnDeserialized = onDeserialized; + } + if (onError != null) + { + contract.OnError = onError; + } + } + + private void GetCallbackMethodsForType(Type type, out MethodInfo onSerializing, out MethodInfo onSerialized, out MethodInfo onDeserializing, out MethodInfo onDeserialized, out MethodInfo onError) + { + onSerializing = null; + onSerialized = null; + onDeserializing = null; + onDeserialized = null; + onError = null; + MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + foreach (MethodInfo methodInfo in methods) + { + if (!methodInfo.ContainsGenericParameters) + { + Type prevAttributeType = null; + ParameterInfo[] parameters = methodInfo.GetParameters(); + if (IsValidCallback(methodInfo, parameters, typeof(OnSerializingAttribute), onSerializing, ref prevAttributeType)) + { + onSerializing = methodInfo; + } + if (IsValidCallback(methodInfo, parameters, typeof(OnSerializedAttribute), onSerialized, ref prevAttributeType)) + { + onSerialized = methodInfo; + } + if (IsValidCallback(methodInfo, parameters, typeof(OnDeserializingAttribute), onDeserializing, ref prevAttributeType)) + { + onDeserializing = methodInfo; + } + if (IsValidCallback(methodInfo, parameters, typeof(OnDeserializedAttribute), onDeserialized, ref prevAttributeType)) + { + onDeserialized = methodInfo; + } + if (IsValidCallback(methodInfo, parameters, typeof(OnErrorAttribute), onError, ref prevAttributeType)) + { + onError = methodInfo; + } + } + } + } + + protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectType) + { + JsonDictionaryContract jsonDictionaryContract = new JsonDictionaryContract(objectType); + InitializeContract(jsonDictionaryContract); + jsonDictionaryContract.PropertyNameResolver = ResolvePropertyName; + return jsonDictionaryContract; + } + + protected virtual JsonArrayContract CreateArrayContract(Type objectType) + { + JsonArrayContract jsonArrayContract = new JsonArrayContract(objectType); + InitializeContract(jsonArrayContract); + return jsonArrayContract; + } + + protected virtual JsonPrimitiveContract CreatePrimitiveContract(Type objectType) + { + JsonPrimitiveContract jsonPrimitiveContract = new JsonPrimitiveContract(objectType); + InitializeContract(jsonPrimitiveContract); + return jsonPrimitiveContract; + } + + protected virtual JsonLinqContract CreateLinqContract(Type objectType) + { + JsonLinqContract jsonLinqContract = new JsonLinqContract(objectType); + InitializeContract(jsonLinqContract); + return jsonLinqContract; + } + + protected virtual JsonISerializableContract CreateISerializableContract(Type objectType) + { + JsonISerializableContract jsonISerializableContract = new JsonISerializableContract(objectType); + InitializeContract(jsonISerializableContract); + ConstructorInfo constructor = objectType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] + { + typeof(SerializationInfo), + typeof(StreamingContext) + }, null); + if (constructor != null) + { + MethodCall methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructor); + jsonISerializableContract.ISerializableCreator = ((object[] args) => methodCall(null, args)); + } + return jsonISerializableContract; + } + + protected virtual JsonStringContract CreateStringContract(Type objectType) + { + JsonStringContract jsonStringContract = new JsonStringContract(objectType); + InitializeContract(jsonStringContract); + return jsonStringContract; + } + + protected virtual JsonContract CreateContract(Type objectType) + { + Type type = ReflectionUtils.EnsureNotNullableType(objectType); + if (JsonConvert.IsJsonPrimitiveType(type)) + { + return CreatePrimitiveContract(type); + } + if (JsonTypeReflector.GetJsonObjectAttribute(type) != null) + { + return CreateObjectContract(type); + } + if (JsonTypeReflector.GetJsonArrayAttribute(type) != null) + { + return CreateArrayContract(type); + } + if (type == typeof(JToken) || type.IsSubclassOf(typeof(JToken))) + { + return CreateLinqContract(type); + } + if (CollectionUtils.IsDictionaryType(type)) + { + return CreateDictionaryContract(type); + } + if (typeof(IEnumerable).IsAssignableFrom(type)) + { + return CreateArrayContract(type); + } + if (CanConvertToString(type)) + { + return CreateStringContract(type); + } + if (typeof(ISerializable).IsAssignableFrom(type)) + { + return CreateISerializableContract(type); + } + return CreateObjectContract(type); + } + + internal static bool CanConvertToString(Type type) + { + TypeConverter converter = ConvertUtils.GetConverter(type); + if (converter != null && !(converter is ComponentConverter) && !(converter is ReferenceConverter) && converter.GetType() != typeof(TypeConverter) && converter.CanConvertTo(typeof(string))) + { + return true; + } + if (type == typeof(Type) || type.IsSubclassOf(typeof(Type))) + { + return true; + } + return false; + } + + private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType) + { + if (!method.IsDefined(attributeType, inherit: false)) + { + return false; + } + if (currentCallback != null) + { + throw new Exception("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType)); + } + if (prevAttributeType != null) + { + throw new Exception("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method)); + } + if (method.IsVirtual) + { + throw new Exception("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType)); + } + if (method.ReturnType != typeof(void)) + { + throw new Exception("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method)); + } + if (attributeType == typeof(OnErrorAttribute)) + { + if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext)) + { + throw new Exception("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext), typeof(ErrorContext))); + } + } + else if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext)) + { + throw new Exception("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext))); + } + prevAttributeType = attributeType; + return true; + } + + internal static string GetClrTypeFullName(Type type) + { + if (type.IsGenericTypeDefinition || !type.ContainsGenericParameters) + { + return type.FullName; + } + return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", type.Namespace, type.Name); + } + + protected virtual IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + List serializableMembers = GetSerializableMembers(type); + if (serializableMembers == null) + { + throw new JsonSerializationException("Null collection of seralizable members returned."); + } + JsonPropertyCollection jsonPropertyCollection = new JsonPropertyCollection(type); + foreach (MemberInfo item in serializableMembers) + { + JsonProperty jsonProperty = CreateProperty(item, memberSerialization); + if (jsonProperty != null) + { + jsonPropertyCollection.AddProperty(jsonProperty); + } + } + return jsonPropertyCollection.OrderBy(delegate(JsonProperty p) + { + int? order = p.Order; + return (!order.HasValue) ? (-1) : order.Value; + }).ToList(); + } + + protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member) + { + if (DynamicCodeGeneration) + { + return new DynamicValueProvider(member); + } + return new ReflectionValueProvider(member); + } + + protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + JsonProperty jsonProperty = new JsonProperty(); + jsonProperty.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member); + jsonProperty.ValueProvider = CreateMemberValueProvider(member); + SetPropertySettingsFromAttributes(jsonProperty, member, member.Name, member.DeclaringType, memberSerialization, out bool allowNonPublicAccess, out bool hasExplicitAttribute); + jsonProperty.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess); + jsonProperty.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess, hasExplicitAttribute); + jsonProperty.ShouldSerialize = CreateShouldSerializeTest(member); + SetIsSpecifiedActions(jsonProperty, member, allowNonPublicAccess); + return jsonProperty; + } + + private void SetPropertySettingsFromAttributes(JsonProperty property, ICustomAttributeProvider attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess, out bool hasExplicitAttribute) + { + hasExplicitAttribute = false; + DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType); + DataMemberAttribute dataMemberAttribute = (dataContractAttribute == null || !(attributeProvider is MemberInfo)) ? null : JsonTypeReflector.GetDataMemberAttribute((MemberInfo)attributeProvider); + JsonPropertyAttribute attribute = JsonTypeReflector.GetAttribute(attributeProvider); + if (attribute != null) + { + hasExplicitAttribute = true; + } + bool flag = JsonTypeReflector.GetAttribute(attributeProvider) != null; + string propertyName = (attribute != null && attribute.PropertyName != null) ? attribute.PropertyName : ((dataMemberAttribute == null || dataMemberAttribute.Name == null) ? name : dataMemberAttribute.Name); + property.PropertyName = ResolvePropertyName(propertyName); + property.UnderlyingName = name; + if (attribute != null) + { + property.Required = attribute.Required; + property.Order = attribute._order; + } + else if (dataMemberAttribute != null) + { + property.Required = (dataMemberAttribute.IsRequired ? Required.AllowNull : Required.Default); + property.Order = ((dataMemberAttribute.Order == -1) ? null : new int?(dataMemberAttribute.Order)); + } + else + { + property.Required = Required.Default; + } + property.Ignored = (flag || (memberSerialization == MemberSerialization.OptIn && attribute == null && dataMemberAttribute == null)); + property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType); + property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType); + property.DefaultValue = JsonTypeReflector.GetAttribute(attributeProvider)?.Value; + property.NullValueHandling = attribute?._nullValueHandling; + property.DefaultValueHandling = attribute?._defaultValueHandling; + property.ReferenceLoopHandling = attribute?._referenceLoopHandling; + property.ObjectCreationHandling = attribute?._objectCreationHandling; + property.TypeNameHandling = attribute?._typeNameHandling; + property.IsReference = attribute?._isReference; + allowNonPublicAccess = false; + if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic) + { + allowNonPublicAccess = true; + } + if (attribute != null) + { + allowNonPublicAccess = true; + } + if (dataMemberAttribute != null) + { + allowNonPublicAccess = true; + hasExplicitAttribute = true; + } + } + + private Predicate CreateShouldSerializeTest(MemberInfo member) + { + MethodInfo method = member.DeclaringType.GetMethod("ShouldSerialize" + member.Name, new Type[0]); + if (method == null || method.ReturnType != typeof(bool)) + { + return null; + } + MethodCall shouldSerializeCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(method); + return (object o) => (bool)shouldSerializeCall(o); + } + + private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member, bool allowNonPublicAccess) + { + MemberInfo memberInfo = member.DeclaringType.GetProperty(member.Name + "Specified"); + if (memberInfo == null) + { + memberInfo = member.DeclaringType.GetField(member.Name + "Specified"); + } + if (memberInfo != null && ReflectionUtils.GetMemberUnderlyingType(memberInfo) == typeof(bool)) + { + Func specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(memberInfo); + property.GetIsSpecified = ((object o) => (bool)specifiedPropertyGet(o)); + if (ReflectionUtils.CanSetMemberValue(memberInfo, allowNonPublicAccess, canSetReadOnly: false)) + { + property.SetIsSpecified = JsonTypeReflector.ReflectionDelegateFactory.CreateSet(memberInfo); + } + } + } + + protected internal virtual string ResolvePropertyName(string propertyName) + { + return propertyName; + } + } +} diff --git a/Newtonsoft.Json.Serialization/DefaultReferenceResolver.cs b/Newtonsoft.Json.Serialization/DefaultReferenceResolver.cs new file mode 100644 index 00000000..39b6e50f --- /dev/null +++ b/Newtonsoft.Json.Serialization/DefaultReferenceResolver.cs @@ -0,0 +1,58 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; + +namespace Newtonsoft.Json.Serialization +{ + internal class DefaultReferenceResolver : IReferenceResolver + { + private int _referenceCount; + + private BidirectionalDictionary GetMappings(object context) + { + JsonSerializerInternalBase jsonSerializerInternalBase; + if (context is JsonSerializerInternalBase) + { + jsonSerializerInternalBase = (JsonSerializerInternalBase)context; + } + else + { + if (!(context is JsonSerializerProxy)) + { + throw new Exception("The DefaultReferenceResolver can only be used internally."); + } + jsonSerializerInternalBase = ((JsonSerializerProxy)context).GetInternalSerializer(); + } + return jsonSerializerInternalBase.DefaultReferenceMappings; + } + + public object ResolveReference(object context, string reference) + { + GetMappings(context).TryGetByFirst(reference, out object second); + return second; + } + + public string GetReference(object context, object value) + { + BidirectionalDictionary mappings = GetMappings(context); + if (!mappings.TryGetBySecond(value, out string first)) + { + _referenceCount++; + first = _referenceCount.ToString(CultureInfo.InvariantCulture); + mappings.Add(first, value); + } + return first; + } + + public void AddReference(object context, string reference, object value) + { + GetMappings(context).Add(reference, value); + } + + public bool IsReferenced(object context, object value) + { + string first; + return GetMappings(context).TryGetBySecond(value, out first); + } + } +} diff --git a/Newtonsoft.Json.Serialization/DefaultSerializationBinder.cs b/Newtonsoft.Json.Serialization/DefaultSerializationBinder.cs new file mode 100644 index 00000000..f402b534 --- /dev/null +++ b/Newtonsoft.Json.Serialization/DefaultSerializationBinder.cs @@ -0,0 +1,73 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Serialization +{ + public class DefaultSerializationBinder : SerializationBinder + { + internal struct TypeNameKey : IEquatable + { + internal readonly string AssemblyName; + + internal readonly string TypeName; + + public TypeNameKey(string assemblyName, string typeName) + { + AssemblyName = assemblyName; + TypeName = typeName; + } + + public override int GetHashCode() + { + return ((AssemblyName != null) ? AssemblyName.GetHashCode() : 0) ^ ((TypeName != null) ? TypeName.GetHashCode() : 0); + } + + public override bool Equals(object obj) + { + if (!(obj is TypeNameKey)) + { + return false; + } + return Equals((TypeNameKey)obj); + } + + public bool Equals(TypeNameKey other) + { + return AssemblyName == other.AssemblyName && TypeName == other.TypeName; + } + } + + internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder(); + + private readonly ThreadSafeStore _typeCache = new ThreadSafeStore(GetTypeFromTypeNameKey); + + private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey) + { + string assemblyName = typeNameKey.AssemblyName; + string typeName = typeNameKey.TypeName; + if (assemblyName != null) + { + Assembly assembly = Assembly.LoadWithPartialName(assemblyName); + if (assembly == null) + { + throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName)); + } + Type type = assembly.GetType(typeName); + if (type == null) + { + throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName)); + } + return type; + } + return Type.GetType(typeName); + } + + public override Type BindToType(string assemblyName, string typeName) + { + return _typeCache.Get(new TypeNameKey(assemblyName, typeName)); + } + } +} diff --git a/Newtonsoft.Json.Serialization/DynamicValueProvider.cs b/Newtonsoft.Json.Serialization/DynamicValueProvider.cs new file mode 100644 index 00000000..f76ef482 --- /dev/null +++ b/Newtonsoft.Json.Serialization/DynamicValueProvider.cs @@ -0,0 +1,61 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; +using System.Reflection; + +namespace Newtonsoft.Json.Serialization +{ + public class DynamicValueProvider : IValueProvider + { + private readonly MemberInfo _memberInfo; + + private Func _getter; + + private Action _setter; + + public DynamicValueProvider(MemberInfo memberInfo) + { + ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); + _memberInfo = memberInfo; + } + + public void SetValue(object target, object value) + { + try + { + if (_setter == null) + { + _setter = DynamicReflectionDelegateFactory.Instance.CreateSet(_memberInfo); + } + _setter(target, value); + } + catch (Exception innerException) + { + throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), innerException); + IL_0067:; + } + } + + public object GetValue(object target) + { + try + { + if (_getter == null) + { + _getter = DynamicReflectionDelegateFactory.Instance.CreateGet(_memberInfo); + } + return _getter(target); + IL_0033: + object result; + return result; + } + catch (Exception innerException) + { + throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), innerException); + IL_006c: + object result; + return result; + } + } + } +} diff --git a/Newtonsoft.Json.Serialization/ErrorContext.cs b/Newtonsoft.Json.Serialization/ErrorContext.cs new file mode 100644 index 00000000..f567b812 --- /dev/null +++ b/Newtonsoft.Json.Serialization/ErrorContext.cs @@ -0,0 +1,38 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public class ErrorContext + { + public Exception Error + { + get; + private set; + } + + public object OriginalObject + { + get; + private set; + } + + public object Member + { + get; + private set; + } + + public bool Handled + { + get; + set; + } + + internal ErrorContext(object originalObject, object member, Exception error) + { + OriginalObject = originalObject; + Member = member; + Error = error; + } + } +} diff --git a/Newtonsoft.Json.Serialization/ErrorEventArgs.cs b/Newtonsoft.Json.Serialization/ErrorEventArgs.cs new file mode 100644 index 00000000..62781451 --- /dev/null +++ b/Newtonsoft.Json.Serialization/ErrorEventArgs.cs @@ -0,0 +1,25 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public class ErrorEventArgs : EventArgs + { + public object CurrentObject + { + get; + private set; + } + + public ErrorContext ErrorContext + { + get; + private set; + } + + public ErrorEventArgs(object currentObject, ErrorContext errorContext) + { + CurrentObject = currentObject; + ErrorContext = errorContext; + } + } +} diff --git a/Newtonsoft.Json.Serialization/IContractResolver.cs b/Newtonsoft.Json.Serialization/IContractResolver.cs new file mode 100644 index 00000000..e111bbfe --- /dev/null +++ b/Newtonsoft.Json.Serialization/IContractResolver.cs @@ -0,0 +1,9 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public interface IContractResolver + { + JsonContract ResolveContract(Type type); + } +} diff --git a/Newtonsoft.Json.Serialization/IMetadataTypeAttribute.cs b/Newtonsoft.Json.Serialization/IMetadataTypeAttribute.cs new file mode 100644 index 00000000..3e4d8012 --- /dev/null +++ b/Newtonsoft.Json.Serialization/IMetadataTypeAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + internal interface IMetadataTypeAttribute + { + Type MetadataClassType + { + get; + } + } +} diff --git a/Newtonsoft.Json.Serialization/IReferenceResolver.cs b/Newtonsoft.Json.Serialization/IReferenceResolver.cs new file mode 100644 index 00000000..df028764 --- /dev/null +++ b/Newtonsoft.Json.Serialization/IReferenceResolver.cs @@ -0,0 +1,13 @@ +namespace Newtonsoft.Json.Serialization +{ + public interface IReferenceResolver + { + object ResolveReference(object context, string reference); + + string GetReference(object context, object value); + + bool IsReferenced(object context, object value); + + void AddReference(object context, string reference, object value); + } +} diff --git a/Newtonsoft.Json.Serialization/IValueProvider.cs b/Newtonsoft.Json.Serialization/IValueProvider.cs new file mode 100644 index 00000000..c93639fd --- /dev/null +++ b/Newtonsoft.Json.Serialization/IValueProvider.cs @@ -0,0 +1,9 @@ +namespace Newtonsoft.Json.Serialization +{ + public interface IValueProvider + { + void SetValue(object target, object value); + + object GetValue(object target); + } +} diff --git a/Newtonsoft.Json.Serialization/JsonArrayContract.cs b/Newtonsoft.Json.Serialization/JsonArrayContract.cs new file mode 100644 index 00000000..f0fb7c6a --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonArrayContract.cs @@ -0,0 +1,104 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonArrayContract : JsonContract + { + private readonly bool _isCollectionItemTypeNullableType; + + private readonly Type _genericCollectionDefinitionType; + + private Type _genericWrapperType; + + private MethodCall _genericWrapperCreator; + + internal Type CollectionItemType + { + get; + private set; + } + + public JsonArrayContract(Type underlyingType) + : base(underlyingType) + { + if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType)) + { + CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0]; + } + else if (underlyingType.IsGenericType && underlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + _genericCollectionDefinitionType = typeof(IEnumerable<>); + CollectionItemType = underlyingType.GetGenericArguments()[0]; + } + else + { + CollectionItemType = ReflectionUtils.GetCollectionItemType(base.UnderlyingType); + } + if (CollectionItemType != null) + { + _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType); + } + if (IsTypeGenericCollectionInterface(base.UnderlyingType)) + { + base.CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType); + } + else if (typeof(HashSet<>).IsAssignableFrom(base.UnderlyingType)) + { + base.CreatedType = ReflectionUtils.MakeGenericType(typeof(HashSet<>), CollectionItemType); + } + } + + internal IWrappedCollection CreateWrapper(object list) + { + if ((list is IList && (CollectionItemType == null || !_isCollectionItemTypeNullableType)) || base.UnderlyingType.IsArray) + { + return new CollectionWrapper((IList)list); + } + if (_genericCollectionDefinitionType != null) + { + EnsureGenericWrapperCreator(); + return (IWrappedCollection)_genericWrapperCreator(null, list); + } + IList list2 = ((IEnumerable)list).Cast().ToList(); + if (CollectionItemType != null) + { + Array array = Array.CreateInstance(CollectionItemType, list2.Count); + for (int i = 0; i < list2.Count; i++) + { + array.SetValue(list2[i], i); + } + list2 = array; + } + return new CollectionWrapper(list2); + } + + private void EnsureGenericWrapperCreator() + { + if (_genericWrapperType == null) + { + _genericWrapperType = ReflectionUtils.MakeGenericType(typeof(CollectionWrapper<>), CollectionItemType); + Type type = (!ReflectionUtils.InheritsGenericDefinition(_genericCollectionDefinitionType, typeof(List<>)) && _genericCollectionDefinitionType.GetGenericTypeDefinition() != typeof(IEnumerable<>)) ? _genericCollectionDefinitionType : ReflectionUtils.MakeGenericType(typeof(ICollection<>), CollectionItemType); + ConstructorInfo constructor = _genericWrapperType.GetConstructor(new Type[1] + { + type + }); + _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructor); + } + } + + private bool IsTypeGenericCollectionInterface(Type type) + { + if (!type.IsGenericType) + { + return false; + } + Type genericTypeDefinition = type.GetGenericTypeDefinition(); + return genericTypeDefinition == typeof(IList<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IEnumerable<>); + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonContract.cs b/Newtonsoft.Json.Serialization/JsonContract.cs new file mode 100644 index 00000000..be023300 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonContract.cs @@ -0,0 +1,145 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Serialization +{ + public abstract class JsonContract + { + public Type UnderlyingType + { + get; + private set; + } + + public Type CreatedType + { + get; + set; + } + + public bool? IsReference + { + get; + set; + } + + public JsonConverter Converter + { + get; + set; + } + + internal JsonConverter InternalConverter + { + get; + set; + } + + public MethodInfo OnDeserialized + { + get; + set; + } + + public MethodInfo OnDeserializing + { + get; + set; + } + + public MethodInfo OnSerialized + { + get; + set; + } + + public MethodInfo OnSerializing + { + get; + set; + } + + public Func DefaultCreator + { + get; + set; + } + + public bool DefaultCreatorNonPublic + { + get; + set; + } + + public MethodInfo OnError + { + get; + set; + } + + internal JsonContract(Type underlyingType) + { + ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType"); + UnderlyingType = underlyingType; + CreatedType = underlyingType; + } + + internal void InvokeOnSerializing(object o, StreamingContext context) + { + if (OnSerializing != null) + { + OnSerializing.Invoke(o, new object[1] + { + context + }); + } + } + + internal void InvokeOnSerialized(object o, StreamingContext context) + { + if (OnSerialized != null) + { + OnSerialized.Invoke(o, new object[1] + { + context + }); + } + } + + internal void InvokeOnDeserializing(object o, StreamingContext context) + { + if (OnDeserializing != null) + { + OnDeserializing.Invoke(o, new object[1] + { + context + }); + } + } + + internal void InvokeOnDeserialized(object o, StreamingContext context) + { + if (OnDeserialized != null) + { + OnDeserialized.Invoke(o, new object[1] + { + context + }); + } + } + + internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext) + { + if (OnError != null) + { + OnError.Invoke(o, new object[2] + { + context, + errorContext + }); + } + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonDictionaryContract.cs b/Newtonsoft.Json.Serialization/JsonDictionaryContract.cs new file mode 100644 index 00000000..389d1414 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonDictionaryContract.cs @@ -0,0 +1,95 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonDictionaryContract : JsonContract + { + private readonly bool _isDictionaryValueTypeNullableType; + + private readonly Type _genericCollectionDefinitionType; + + private Type _genericWrapperType; + + private MethodCall _genericWrapperCreator; + + public Func PropertyNameResolver + { + get; + set; + } + + internal Type DictionaryKeyType + { + get; + private set; + } + + internal Type DictionaryValueType + { + get; + private set; + } + + public JsonDictionaryContract(Type underlyingType) + : base(underlyingType) + { + Type keyType; + Type valueType; + if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<, >), out _genericCollectionDefinitionType)) + { + keyType = _genericCollectionDefinitionType.GetGenericArguments()[0]; + valueType = _genericCollectionDefinitionType.GetGenericArguments()[1]; + } + else + { + ReflectionUtils.GetDictionaryKeyValueTypes(base.UnderlyingType, out keyType, out valueType); + } + DictionaryKeyType = keyType; + DictionaryValueType = valueType; + if (DictionaryValueType != null) + { + _isDictionaryValueTypeNullableType = ReflectionUtils.IsNullableType(DictionaryValueType); + } + if (IsTypeGenericDictionaryInterface(base.UnderlyingType)) + { + base.CreatedType = ReflectionUtils.MakeGenericType(typeof(Dictionary<, >), keyType, valueType); + } + else if (base.UnderlyingType == typeof(IDictionary)) + { + base.CreatedType = typeof(Dictionary); + } + } + + internal IWrappedDictionary CreateWrapper(object dictionary) + { + if (dictionary is IDictionary && (DictionaryValueType == null || !_isDictionaryValueTypeNullableType)) + { + return new DictionaryWrapper((IDictionary)dictionary); + } + if (_genericWrapperType == null) + { + _genericWrapperType = ReflectionUtils.MakeGenericType(typeof(DictionaryWrapper<, >), DictionaryKeyType, DictionaryValueType); + ConstructorInfo constructor = _genericWrapperType.GetConstructor(new Type[1] + { + _genericCollectionDefinitionType + }); + _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructor); + } + return (IWrappedDictionary)_genericWrapperCreator(null, dictionary); + } + + private bool IsTypeGenericDictionaryInterface(Type type) + { + if (!type.IsGenericType) + { + return false; + } + Type genericTypeDefinition = type.GetGenericTypeDefinition(); + return genericTypeDefinition == typeof(IDictionary<, >); + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonFormatterConverter.cs b/Newtonsoft.Json.Serialization/JsonFormatterConverter.cs new file mode 100644 index 00000000..1a0ddfe4 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonFormatterConverter.cs @@ -0,0 +1,122 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Serialization +{ + internal class JsonFormatterConverter : IFormatterConverter + { + private readonly JsonSerializer _serializer; + + public JsonFormatterConverter(JsonSerializer serializer) + { + ValidationUtils.ArgumentNotNull(serializer, "serializer"); + _serializer = serializer; + } + + private T GetTokenValue(object value) + { + ValidationUtils.ArgumentNotNull(value, "value"); + JValue jValue = (JValue)value; + return (T)System.Convert.ChangeType(jValue.Value, typeof(T), CultureInfo.InvariantCulture); + } + + public object Convert(object value, Type type) + { + ValidationUtils.ArgumentNotNull(value, "value"); + JToken jToken = value as JToken; + if (jToken == null) + { + throw new ArgumentException("Value is not a JToken.", "value"); + } + return _serializer.Deserialize(jToken.CreateReader(), type); + } + + public object Convert(object value, TypeCode typeCode) + { + ValidationUtils.ArgumentNotNull(value, "value"); + if (value is JValue) + { + value = ((JValue)value).Value; + } + return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture); + } + + public bool ToBoolean(object value) + { + return GetTokenValue(value); + } + + public byte ToByte(object value) + { + return GetTokenValue(value); + } + + public char ToChar(object value) + { + return GetTokenValue(value); + } + + public DateTime ToDateTime(object value) + { + return GetTokenValue(value); + } + + public decimal ToDecimal(object value) + { + return GetTokenValue(value); + } + + public double ToDouble(object value) + { + return GetTokenValue(value); + } + + public short ToInt16(object value) + { + return GetTokenValue(value); + } + + public int ToInt32(object value) + { + return GetTokenValue(value); + } + + public long ToInt64(object value) + { + return GetTokenValue(value); + } + + public sbyte ToSByte(object value) + { + return GetTokenValue(value); + } + + public float ToSingle(object value) + { + return GetTokenValue(value); + } + + public string ToString(object value) + { + return GetTokenValue(value); + } + + public ushort ToUInt16(object value) + { + return GetTokenValue(value); + } + + public uint ToUInt32(object value) + { + return GetTokenValue(value); + } + + public ulong ToUInt64(object value) + { + return GetTokenValue(value); + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonISerializableContract.cs b/Newtonsoft.Json.Serialization/JsonISerializableContract.cs new file mode 100644 index 00000000..abd0cf9e --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonISerializableContract.cs @@ -0,0 +1,18 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonISerializableContract : JsonContract + { + public ObjectConstructor ISerializableCreator + { + get; + set; + } + + public JsonISerializableContract(Type underlyingType) + : base(underlyingType) + { + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonLinqContract.cs b/Newtonsoft.Json.Serialization/JsonLinqContract.cs new file mode 100644 index 00000000..9172daf1 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonLinqContract.cs @@ -0,0 +1,12 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonLinqContract : JsonContract + { + public JsonLinqContract(Type underlyingType) + : base(underlyingType) + { + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonObjectContract.cs b/Newtonsoft.Json.Serialization/JsonObjectContract.cs new file mode 100644 index 00000000..1d9117b0 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonObjectContract.cs @@ -0,0 +1,45 @@ +using System; +using System.Reflection; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonObjectContract : JsonContract + { + public MemberSerialization MemberSerialization + { + get; + set; + } + + public JsonPropertyCollection Properties + { + get; + private set; + } + + public JsonPropertyCollection ConstructorParameters + { + get; + private set; + } + + public ConstructorInfo OverrideConstructor + { + get; + set; + } + + public ConstructorInfo ParametrizedConstructor + { + get; + set; + } + + public JsonObjectContract(Type underlyingType) + : base(underlyingType) + { + Properties = new JsonPropertyCollection(base.UnderlyingType); + ConstructorParameters = new JsonPropertyCollection(base.UnderlyingType); + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonPrimitiveContract.cs b/Newtonsoft.Json.Serialization/JsonPrimitiveContract.cs new file mode 100644 index 00000000..63c8e0e1 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonPrimitiveContract.cs @@ -0,0 +1,12 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonPrimitiveContract : JsonContract + { + public JsonPrimitiveContract(Type underlyingType) + : base(underlyingType) + { + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonProperty.cs b/Newtonsoft.Json.Serialization/JsonProperty.cs new file mode 100644 index 00000000..af19d39a --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonProperty.cs @@ -0,0 +1,138 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonProperty + { + public string PropertyName + { + get; + set; + } + + public int? Order + { + get; + set; + } + + public string UnderlyingName + { + get; + set; + } + + public IValueProvider ValueProvider + { + get; + set; + } + + public Type PropertyType + { + get; + set; + } + + public JsonConverter Converter + { + get; + set; + } + + public JsonConverter MemberConverter + { + get; + set; + } + + public bool Ignored + { + get; + set; + } + + public bool Readable + { + get; + set; + } + + public bool Writable + { + get; + set; + } + + public object DefaultValue + { + get; + set; + } + + public Required Required + { + get; + set; + } + + public bool? IsReference + { + get; + set; + } + + public NullValueHandling? NullValueHandling + { + get; + set; + } + + public DefaultValueHandling? DefaultValueHandling + { + get; + set; + } + + public ReferenceLoopHandling? ReferenceLoopHandling + { + get; + set; + } + + public ObjectCreationHandling? ObjectCreationHandling + { + get; + set; + } + + public TypeNameHandling? TypeNameHandling + { + get; + set; + } + + public Predicate ShouldSerialize + { + get; + set; + } + + public Predicate GetIsSpecified + { + get; + set; + } + + public Action SetIsSpecified + { + get; + set; + } + + public override string ToString() + { + return PropertyName; + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonPropertyCollection.cs b/Newtonsoft.Json.Serialization/JsonPropertyCollection.cs new file mode 100644 index 00000000..ae461843 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonPropertyCollection.cs @@ -0,0 +1,68 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonPropertyCollection : KeyedCollection + { + private readonly Type _type; + + public JsonPropertyCollection(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + _type = type; + } + + protected override string GetKeyForItem(JsonProperty item) + { + return item.PropertyName; + } + + public void AddProperty(JsonProperty property) + { + if (Contains(property.PropertyName)) + { + if (property.Ignored) + { + return; + } + JsonProperty jsonProperty = base[property.PropertyName]; + if (!jsonProperty.Ignored) + { + throw new JsonSerializationException("A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _type)); + } + Remove(jsonProperty); + } + Add(property); + } + + public JsonProperty GetClosestMatchProperty(string propertyName) + { + JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal); + if (property == null) + { + property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase); + } + return property; + } + + public JsonProperty GetProperty(string propertyName, StringComparison comparisonType) + { + using (IEnumerator enumerator = GetEnumerator()) + { + while (enumerator.MoveNext()) + { + JsonProperty current = enumerator.Current; + if (string.Equals(propertyName, current.PropertyName, comparisonType)) + { + return current; + } + } + } + return null; + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonSerializerInternalBase.cs b/Newtonsoft.Json.Serialization/JsonSerializerInternalBase.cs new file mode 100644 index 00000000..f655f835 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonSerializerInternalBase.cs @@ -0,0 +1,84 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace Newtonsoft.Json.Serialization +{ + internal abstract class JsonSerializerInternalBase + { + private class ReferenceEqualsEqualityComparer : IEqualityComparer + { + bool IEqualityComparer.Equals(object x, object y) + { + return object.ReferenceEquals(x, y); + } + + int IEqualityComparer.GetHashCode(object obj) + { + return RuntimeHelpers.GetHashCode(obj); + } + } + + private ErrorContext _currentErrorContext; + + private BidirectionalDictionary _mappings; + + internal JsonSerializer Serializer + { + get; + private set; + } + + internal BidirectionalDictionary DefaultReferenceMappings + { + get + { + if (_mappings == null) + { + _mappings = new BidirectionalDictionary(EqualityComparer.Default, new ReferenceEqualsEqualityComparer()); + } + return _mappings; + } + } + + protected JsonSerializerInternalBase(JsonSerializer serializer) + { + ValidationUtils.ArgumentNotNull(serializer, "serializer"); + Serializer = serializer; + } + + protected ErrorContext GetErrorContext(object currentObject, object member, Exception error) + { + if (_currentErrorContext == null) + { + _currentErrorContext = new ErrorContext(currentObject, member, error); + } + if (_currentErrorContext.Error != error) + { + throw new InvalidOperationException("Current error context error is different to requested error."); + } + return _currentErrorContext; + } + + protected void ClearErrorContext() + { + if (_currentErrorContext == null) + { + throw new InvalidOperationException("Could not clear error context. Error context is already null."); + } + _currentErrorContext = null; + } + + protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, Exception ex) + { + ErrorContext errorContext = GetErrorContext(currentObject, keyValue, ex); + contract.InvokeOnError(currentObject, Serializer.Context, errorContext); + if (!errorContext.Handled) + { + Serializer.OnError(new ErrorEventArgs(currentObject, errorContext)); + } + return errorContext.Handled; + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonSerializerInternalReader.cs b/Newtonsoft.Json.Serialization/JsonSerializerInternalReader.cs new file mode 100644 index 00000000..1246b3fc --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonSerializerInternalReader.cs @@ -0,0 +1,1017 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Serialization +{ + internal class JsonSerializerInternalReader : JsonSerializerInternalBase + { + internal enum PropertyPresence + { + None, + Null, + Value + } + + private JsonSerializerProxy _internalSerializer; + + private JsonFormatterConverter _formatterConverter; + + public JsonSerializerInternalReader(JsonSerializer serializer) + : base(serializer) + { + } + + public void Populate(JsonReader reader, object target) + { + ValidationUtils.ArgumentNotNull(target, "target"); + Type type = target.GetType(); + JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(type); + if (reader.TokenType == JsonToken.None) + { + reader.Read(); + } + if (reader.TokenType == JsonToken.StartArray) + { + if (!(jsonContract is JsonArrayContract)) + { + throw new JsonSerializationException("Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, type)); + } + PopulateList(CollectionUtils.CreateCollectionWrapper(target), reader, null, (JsonArrayContract)jsonContract); + } + else + { + if (reader.TokenType != JsonToken.StartObject) + { + throw new JsonSerializationException("Unexpected initial token '{0}' when populating object. Expected JSON object or array.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + CheckedRead(reader); + string id = null; + if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), "$id", StringComparison.Ordinal)) + { + CheckedRead(reader); + id = ((reader.Value == null) ? null : reader.Value.ToString()); + CheckedRead(reader); + } + if (jsonContract is JsonDictionaryContract) + { + PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract)jsonContract, id); + } + else + { + if (!(jsonContract is JsonObjectContract)) + { + throw new JsonSerializationException("Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, type)); + } + PopulateObject(target, reader, (JsonObjectContract)jsonContract, id); + } + } + } + + private JsonContract GetContractSafe(Type type) + { + if (type == null) + { + return null; + } + return base.Serializer.ContractResolver.ResolveContract(type); + } + + private JsonContract GetContractSafe(Type type, object value) + { + if (value == null) + { + return GetContractSafe(type); + } + return base.Serializer.ContractResolver.ResolveContract(value.GetType()); + } + + public object Deserialize(JsonReader reader, Type objectType) + { + if (reader == null) + { + throw new ArgumentNullException("reader"); + } + if (reader.TokenType == JsonToken.None && !ReadForType(reader, objectType, null)) + { + return null; + } + return CreateValueNonProperty(reader, objectType, GetContractSafe(objectType)); + } + + private JsonSerializerProxy GetInternalSerializer() + { + if (_internalSerializer == null) + { + _internalSerializer = new JsonSerializerProxy(this); + } + return _internalSerializer; + } + + private JsonFormatterConverter GetFormatterConverter() + { + if (_formatterConverter == null) + { + _formatterConverter = new JsonFormatterConverter(GetInternalSerializer()); + } + return _formatterConverter; + } + + private JToken CreateJToken(JsonReader reader, JsonContract contract) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + if (contract != null && contract.UnderlyingType == typeof(JRaw)) + { + return JRaw.Create(reader); + } + using (JTokenWriter jTokenWriter = new JTokenWriter()) + { + jTokenWriter.WriteToken(reader); + return jTokenWriter.Token; + } + } + + private JToken CreateJObject(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + using (JTokenWriter jTokenWriter = new JTokenWriter()) + { + jTokenWriter.WriteStartObject(); + if (reader.TokenType == JsonToken.PropertyName) + { + jTokenWriter.WriteToken(reader, reader.Depth - 1); + } + else + { + jTokenWriter.WriteEndObject(); + } + return jTokenWriter.Token; + } + } + + private object CreateValueProperty(JsonReader reader, JsonProperty property, object target, bool gottenCurrentValue, object currentValue) + { + JsonContract contractSafe = GetContractSafe(property.PropertyType, currentValue); + Type propertyType = property.PropertyType; + JsonConverter converter = GetConverter(contractSafe, property.MemberConverter); + if (converter != null && converter.CanRead) + { + if (!gottenCurrentValue && target != null && property.Readable) + { + currentValue = property.ValueProvider.GetValue(target); + } + return converter.ReadJson(reader, propertyType, currentValue, GetInternalSerializer()); + } + return CreateValueInternal(reader, propertyType, contractSafe, property, currentValue); + } + + private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract) + { + JsonConverter converter = GetConverter(contract, null); + if (converter != null && converter.CanRead) + { + return converter.ReadJson(reader, objectType, null, GetInternalSerializer()); + } + return CreateValueInternal(reader, objectType, contract, null, null); + } + + private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) + { + if (contract is JsonLinqContract) + { + return CreateJToken(reader, contract); + } + do + { + switch (reader.TokenType) + { + case JsonToken.StartObject: + return CreateObject(reader, objectType, contract, member, existingValue); + case JsonToken.StartArray: + return CreateList(reader, objectType, contract, member, existingValue, null); + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.Boolean: + case JsonToken.Date: + case JsonToken.Bytes: + return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType); + case JsonToken.String: + if (string.IsNullOrEmpty((string)reader.Value) && objectType != null && ReflectionUtils.IsNullableType(objectType)) + { + return null; + } + if (objectType == typeof(byte[])) + { + return Convert.FromBase64String((string)reader.Value); + } + return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType); + case JsonToken.StartConstructor: + case JsonToken.EndConstructor: + return reader.Value.ToString(); + case JsonToken.Null: + case JsonToken.Undefined: + if (objectType == typeof(DBNull)) + { + return DBNull.Value; + } + return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType); + case JsonToken.Raw: + return new JRaw((string)reader.Value); + default: + throw new JsonSerializationException("Unexpected token while deserializing object: " + reader.TokenType); + case JsonToken.Comment: + break; + } + } + while (reader.Read()); + throw new JsonSerializationException("Unexpected end when deserializing object."); + } + + private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter) + { + JsonConverter result = null; + if (memberConverter != null) + { + result = memberConverter; + } + else if (contract != null) + { + JsonConverter matchingConverter; + if (contract.Converter != null) + { + result = contract.Converter; + } + else if ((matchingConverter = base.Serializer.GetMatchingConverter(contract.UnderlyingType)) != null) + { + result = matchingConverter; + } + else if (contract.InternalConverter != null) + { + result = contract.InternalConverter; + } + } + return result; + } + + private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) + { + CheckedRead(reader); + string text = null; + if (reader.TokenType == JsonToken.PropertyName) + { + bool flag; + do + { + string a = reader.Value.ToString(); + if (string.Equals(a, "$ref", StringComparison.Ordinal)) + { + CheckedRead(reader); + if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null) + { + throw new JsonSerializationException("JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, "$ref")); + } + string text2 = (reader.Value == null) ? null : reader.Value.ToString(); + CheckedRead(reader); + if (text2 != null) + { + if (reader.TokenType == JsonToken.PropertyName) + { + throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, "$ref")); + } + return base.Serializer.ReferenceResolver.ResolveReference(this, text2); + } + flag = true; + } + else if (string.Equals(a, "$type", StringComparison.Ordinal)) + { + CheckedRead(reader); + string text3 = reader.Value.ToString(); + CheckedRead(reader); + TypeNameHandling? typeNameHandling = member?.TypeNameHandling; + if (((!typeNameHandling.HasValue) ? base.Serializer.TypeNameHandling : typeNameHandling.Value) != 0) + { + ReflectionUtils.SplitFullyQualifiedTypeName(text3, out string typeName, out string assemblyName); + Type type; + try + { + type = base.Serializer.Binder.BindToType(assemblyName, typeName); + } + catch (Exception innerException) + { + throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, text3), innerException); + IL_01a6:; + } + if (type == null) + { + throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, text3)); + } + if (objectType != null && !objectType.IsAssignableFrom(type)) + { + throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); + } + objectType = type; + contract = GetContractSafe(type); + } + flag = true; + } + else if (string.Equals(a, "$id", StringComparison.Ordinal)) + { + CheckedRead(reader); + text = ((reader.Value == null) ? null : reader.Value.ToString()); + CheckedRead(reader); + flag = true; + } + else + { + if (string.Equals(a, "$values", StringComparison.Ordinal)) + { + CheckedRead(reader); + object result = CreateList(reader, objectType, contract, member, existingValue, text); + CheckedRead(reader); + return result; + } + flag = false; + } + } + while (flag && reader.TokenType == JsonToken.PropertyName); + } + if (!HasDefinedType(objectType)) + { + return CreateJObject(reader); + } + if (contract == null) + { + throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + JsonDictionaryContract jsonDictionaryContract = contract as JsonDictionaryContract; + if (jsonDictionaryContract != null) + { + if (existingValue == null) + { + return CreateAndPopulateDictionary(reader, jsonDictionaryContract, text); + } + return PopulateDictionary(jsonDictionaryContract.CreateWrapper(existingValue), reader, jsonDictionaryContract, text); + } + JsonObjectContract jsonObjectContract = contract as JsonObjectContract; + if (jsonObjectContract != null) + { + if (existingValue == null) + { + return CreateAndPopulateObject(reader, jsonObjectContract, text); + } + return PopulateObject(existingValue, reader, jsonObjectContract, text); + } + JsonPrimitiveContract jsonPrimitiveContract = contract as JsonPrimitiveContract; + if (jsonPrimitiveContract != null && reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), "$value", StringComparison.Ordinal)) + { + CheckedRead(reader); + object result2 = CreateValueInternal(reader, objectType, jsonPrimitiveContract, member, existingValue); + CheckedRead(reader); + return result2; + } + JsonISerializableContract jsonISerializableContract = contract as JsonISerializableContract; + if (jsonISerializableContract != null) + { + return CreateISerializable(reader, jsonISerializableContract, text); + } + throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + + private JsonArrayContract EnsureArrayContract(Type objectType, JsonContract contract) + { + if (contract == null) + { + throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + JsonArrayContract jsonArrayContract = contract as JsonArrayContract; + if (jsonArrayContract == null) + { + throw new JsonSerializationException("Cannot deserialize JSON array into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + return jsonArrayContract; + } + + private void CheckedRead(JsonReader reader) + { + if (!reader.Read()) + { + throw new JsonSerializationException("Unexpected end when deserializing object."); + } + } + + private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string reference) + { + if (HasDefinedType(objectType)) + { + JsonArrayContract jsonArrayContract = EnsureArrayContract(objectType, contract); + if (existingValue == null) + { + return CreateAndPopulateList(reader, reference, jsonArrayContract); + } + return PopulateList(jsonArrayContract.CreateWrapper(existingValue), reader, reference, jsonArrayContract); + } + return CreateJToken(reader, contract); + } + + private bool HasDefinedType(Type type) + { + return type != null && type != typeof(object) && !typeof(JToken).IsAssignableFrom(type); + } + + private object EnsureType(object value, CultureInfo culture, Type targetType) + { + if (targetType == null) + { + return value; + } + Type objectType = ReflectionUtils.GetObjectType(value); + if (objectType != targetType) + { + try + { + return ConvertUtils.ConvertOrCast(value, culture, targetType); + IL_0024: + return value; + } + catch (Exception innerException) + { + throw new JsonSerializationException("Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, FormatValueForPrint(value), targetType), innerException); + IL_0054: + return value; + } + } + return value; + } + + private string FormatValueForPrint(object value) + { + if (value == null) + { + return "{null}"; + } + if (value is string) + { + return "\"" + value + "\""; + } + return value.ToString(); + } + + private void SetPropertyValue(JsonProperty property, JsonReader reader, object target) + { + if (property.Ignored) + { + reader.Skip(); + } + else + { + object obj = null; + bool flag = false; + bool gottenCurrentValue = false; + ObjectCreationHandling valueOrDefault = property.ObjectCreationHandling.GetValueOrDefault(base.Serializer.ObjectCreationHandling); + if ((valueOrDefault == ObjectCreationHandling.Auto || valueOrDefault == ObjectCreationHandling.Reuse) && (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject) && property.Readable) + { + obj = property.ValueProvider.GetValue(target); + gottenCurrentValue = true; + flag = (obj != null && !property.PropertyType.IsArray && !ReflectionUtils.InheritsGenericDefinition(property.PropertyType, typeof(ReadOnlyCollection<>)) && !property.PropertyType.IsValueType); + } + if (!property.Writable && !flag) + { + reader.Skip(); + } + else if (property.NullValueHandling.GetValueOrDefault(base.Serializer.NullValueHandling) == NullValueHandling.Ignore && reader.TokenType == JsonToken.Null) + { + reader.Skip(); + } + else if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(base.Serializer.DefaultValueHandling), DefaultValueHandling.Ignore) && JsonReader.IsPrimitiveToken(reader.TokenType) && MiscellaneousUtils.ValueEquals(reader.Value, property.DefaultValue)) + { + reader.Skip(); + } + else + { + object currentValue = (!flag) ? null : obj; + object obj2 = CreateValueProperty(reader, property, target, gottenCurrentValue, currentValue); + if ((!flag || obj2 != obj) && ShouldSetPropertyValue(property, obj2)) + { + property.ValueProvider.SetValue(target, obj2); + if (property.SetIsSpecified != null) + { + property.SetIsSpecified(target, true); + } + } + } + } + } + + private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) + { + return (value & flag) == flag; + } + + private bool ShouldSetPropertyValue(JsonProperty property, object value) + { + if (property.NullValueHandling.GetValueOrDefault(base.Serializer.NullValueHandling) == NullValueHandling.Ignore && value == null) + { + return false; + } + if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(base.Serializer.DefaultValueHandling), DefaultValueHandling.Ignore) && MiscellaneousUtils.ValueEquals(value, property.DefaultValue)) + { + return false; + } + if (!property.Writable) + { + return false; + } + return true; + } + + private object CreateAndPopulateDictionary(JsonReader reader, JsonDictionaryContract contract, string id) + { + if (contract.DefaultCreator == null || (contract.DefaultCreatorNonPublic && base.Serializer.ConstructorHandling != ConstructorHandling.AllowNonPublicDefaultConstructor)) + { + throw new JsonSerializationException("Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + object dictionary = contract.DefaultCreator(); + IWrappedDictionary wrappedDictionary = contract.CreateWrapper(dictionary); + PopulateDictionary(wrappedDictionary, reader, contract, id); + return wrappedDictionary.UnderlyingDictionary; + } + + private object PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, string id) + { + if (id != null) + { + base.Serializer.ReferenceResolver.AddReference(this, id, dictionary.UnderlyingDictionary); + } + contract.InvokeOnDeserializing(dictionary.UnderlyingDictionary, base.Serializer.Context); + int depth = reader.Depth; + do + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + { + object obj = reader.Value; + try + { + try + { + obj = EnsureType(obj, CultureInfo.InvariantCulture, contract.DictionaryKeyType); + } + catch (Exception innerException) + { + throw new JsonSerializationException("Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), innerException); + IL_00b2:; + } + if (!ReadForType(reader, contract.DictionaryValueType, null)) + { + throw new JsonSerializationException("Unexpected end when deserializing object."); + } + dictionary[obj] = CreateValueNonProperty(reader, contract.DictionaryValueType, GetContractSafe(contract.DictionaryValueType)); + } + catch (Exception ex) + { + if (!IsErrorHandled(dictionary, contract, obj, ex)) + { + throw; + } + HandleError(reader, depth); + } + break; + } + case JsonToken.EndObject: + contract.InvokeOnDeserialized(dictionary.UnderlyingDictionary, base.Serializer.Context); + return dictionary.UnderlyingDictionary; + default: + throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); + case JsonToken.Comment: + break; + } + } + while (reader.Read()); + throw new JsonSerializationException("Unexpected end when deserializing object."); + } + + private object CreateAndPopulateList(JsonReader reader, string reference, JsonArrayContract contract) + { + return CollectionUtils.CreateAndPopulateList(contract.CreatedType, delegate(IList l, bool isTemporaryListReference) + { + if (reference != null && isTemporaryListReference) + { + throw new JsonSerializationException("Cannot preserve reference to array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + if (contract.OnSerializing != null && isTemporaryListReference) + { + throw new JsonSerializationException("Cannot call OnSerializing on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + if (contract.OnError != null && isTemporaryListReference) + { + throw new JsonSerializationException("Cannot call OnError on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + PopulateList(contract.CreateWrapper(l), reader, reference, contract); + }); + } + + private bool ReadForTypeArrayHack(JsonReader reader, Type t) + { + try + { + return ReadForType(reader, t, null); + IL_000f: + bool result; + return result; + } + catch (JsonReaderException) + { + if (reader.TokenType != JsonToken.EndArray) + { + throw; + } + return true; + IL_002b: + bool result; + return result; + } + } + + private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, string reference, JsonArrayContract contract) + { + object underlyingCollection = wrappedList.UnderlyingCollection; + if (wrappedList.IsFixedSize) + { + reader.Skip(); + return wrappedList.UnderlyingCollection; + } + if (reference != null) + { + base.Serializer.ReferenceResolver.AddReference(this, reference, underlyingCollection); + } + contract.InvokeOnDeserializing(underlyingCollection, base.Serializer.Context); + int depth = reader.Depth; + while (ReadForTypeArrayHack(reader, contract.CollectionItemType)) + { + switch (reader.TokenType) + { + case JsonToken.EndArray: + contract.InvokeOnDeserialized(underlyingCollection, base.Serializer.Context); + return wrappedList.UnderlyingCollection; + default: + try + { + object value = CreateValueNonProperty(reader, contract.CollectionItemType, GetContractSafe(contract.CollectionItemType)); + wrappedList.Add(value); + } + catch (Exception ex) + { + if (!IsErrorHandled(underlyingCollection, contract, wrappedList.Count, ex)) + { + throw; + } + HandleError(reader, depth); + } + break; + case JsonToken.Comment: + break; + } + } + throw new JsonSerializationException("Unexpected end when deserializing array."); + } + + private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, string id) + { + Type underlyingType = contract.UnderlyingType; + SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, GetFormatterConverter()); + bool flag = false; + do + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + { + string text = reader.Value.ToString(); + if (!reader.Read()) + { + throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text)); + } + serializationInfo.AddValue(text, JToken.ReadFrom(reader)); + break; + } + case JsonToken.EndObject: + flag = true; + break; + default: + throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); + case JsonToken.Comment: + break; + } + } + while (!flag && reader.Read()); + if (contract.ISerializableCreator == null) + { + throw new JsonSerializationException("ISerializable type '{0}' does not have a valid constructor. To correctly implement ISerializable a constructor that takes SerializationInfo and StreamingContext parameters should be present.".FormatWith(CultureInfo.InvariantCulture, underlyingType)); + } + object obj = contract.ISerializableCreator(serializationInfo, base.Serializer.Context); + if (id != null) + { + base.Serializer.ReferenceResolver.AddReference(this, id, obj); + } + contract.InvokeOnDeserializing(obj, base.Serializer.Context); + contract.InvokeOnDeserialized(obj, base.Serializer.Context); + return obj; + } + + private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id) + { + object obj = null; + if (contract.UnderlyingType.IsInterface || contract.UnderlyingType.IsAbstract) + { + throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + if (contract.OverrideConstructor != null) + { + if (contract.OverrideConstructor.GetParameters().Length > 0) + { + return CreateObjectFromNonDefaultConstructor(reader, contract, contract.OverrideConstructor, id); + } + obj = contract.OverrideConstructor.Invoke(null); + } + else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || base.Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) + { + obj = contract.DefaultCreator(); + } + else if (contract.ParametrizedConstructor != null) + { + return CreateObjectFromNonDefaultConstructor(reader, contract, contract.ParametrizedConstructor, id); + } + if (obj == null) + { + throw new JsonSerializationException("Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + PopulateObject(obj, reader, contract, id); + return obj; + } + + private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id) + { + ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); + Type underlyingType = contract.UnderlyingType; + IDictionary dictionary = ResolvePropertyAndConstructorValues(contract, reader, underlyingType); + IDictionary dictionary2 = ((IEnumerable)constructorInfo.GetParameters()).ToDictionary((Func)((ParameterInfo p) => p), (Func)((ParameterInfo p) => null)); + IDictionary dictionary3 = new Dictionary(); + foreach (KeyValuePair item in dictionary) + { + ParameterInfo key = dictionary2.ForgivingCaseSensitiveFind((KeyValuePair kv) => kv.Key.Name, item.Key.UnderlyingName).Key; + if (key != null) + { + dictionary2[key] = item.Value; + } + else + { + dictionary3.Add(item); + } + } + object obj = constructorInfo.Invoke(dictionary2.Values.ToArray()); + if (id != null) + { + base.Serializer.ReferenceResolver.AddReference(this, id, obj); + } + contract.InvokeOnDeserializing(obj, base.Serializer.Context); + foreach (KeyValuePair item2 in dictionary3) + { + JsonProperty key2 = item2.Key; + object value = item2.Value; + if (ShouldSetPropertyValue(item2.Key, item2.Value)) + { + key2.ValueProvider.SetValue(obj, value); + } + else if (!key2.Writable && value != null) + { + JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(key2.PropertyType); + if (jsonContract is JsonArrayContract) + { + JsonArrayContract jsonArrayContract = jsonContract as JsonArrayContract; + object value2 = key2.ValueProvider.GetValue(obj); + if (value2 != null) + { + IWrappedCollection wrappedCollection = jsonArrayContract.CreateWrapper(value2); + IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value); + foreach (object item3 in wrappedCollection2) + { + wrappedCollection.Add(item3); + } + } + } + else if (jsonContract is JsonDictionaryContract) + { + JsonDictionaryContract jsonDictionaryContract = jsonContract as JsonDictionaryContract; + object value3 = key2.ValueProvider.GetValue(obj); + if (value3 != null) + { + IWrappedDictionary wrappedDictionary = jsonDictionaryContract.CreateWrapper(value3); + IWrappedDictionary wrappedDictionary2 = jsonDictionaryContract.CreateWrapper(value); + foreach (DictionaryEntry item4 in (IEnumerable)wrappedDictionary2) + { + wrappedDictionary.Add(item4.Key, item4.Value); + } + } + } + } + } + contract.InvokeOnDeserialized(obj, base.Serializer.Context); + return obj; + } + + private IDictionary ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonReader reader, Type objectType) + { + IDictionary dictionary = new Dictionary(); + bool flag = false; + do + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + { + string text = reader.Value.ToString(); + JsonProperty jsonProperty = contract.ConstructorParameters.GetClosestMatchProperty(text) ?? contract.Properties.GetClosestMatchProperty(text); + if (jsonProperty != null) + { + if (!ReadForType(reader, jsonProperty.PropertyType, jsonProperty.Converter)) + { + throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text)); + } + if (!jsonProperty.Ignored) + { + dictionary[jsonProperty] = CreateValueProperty(reader, jsonProperty, null, /*gottenCurrentValue:*/ true, null); + } + else + { + reader.Skip(); + } + } + else + { + if (!reader.Read()) + { + throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text)); + } + if (base.Serializer.MissingMemberHandling == MissingMemberHandling.Error) + { + throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, objectType.Name)); + } + reader.Skip(); + } + break; + } + case JsonToken.EndObject: + flag = true; + break; + default: + throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); + case JsonToken.Comment: + break; + } + } + while (!flag && reader.Read()); + return dictionary; + } + + private bool ReadForType(JsonReader reader, Type t, JsonConverter propertyConverter) + { + if (GetConverter(GetContractSafe(t), propertyConverter) != null) + { + return reader.Read(); + } + if (t == typeof(byte[])) + { + reader.ReadAsBytes(); + return true; + } + if (t == typeof(decimal) || t == typeof(decimal?)) + { + reader.ReadAsDecimal(); + return true; + } + if (t == typeof(DateTimeOffset) || t == typeof(DateTimeOffset?)) + { + reader.ReadAsDateTimeOffset(); + return true; + } + do + { + if (!reader.Read()) + { + return false; + } + } + while (reader.TokenType == JsonToken.Comment); + return true; + } + + private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id) + { + contract.InvokeOnDeserializing(newObject, base.Serializer.Context); + Dictionary dictionary = contract.Properties.ToDictionary((JsonProperty m) => m, (JsonProperty m) => PropertyPresence.None); + if (id != null) + { + base.Serializer.ReferenceResolver.AddReference(this, id, newObject); + } + int depth = reader.Depth; + do + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + { + string text = reader.Value.ToString(); + try + { + JsonProperty closestMatchProperty = contract.Properties.GetClosestMatchProperty(text); + if (closestMatchProperty == null) + { + if (base.Serializer.MissingMemberHandling == MissingMemberHandling.Error) + { + throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, contract.UnderlyingType.Name)); + } + reader.Skip(); + } + else + { + if (!ReadForType(reader, closestMatchProperty.PropertyType, closestMatchProperty.Converter)) + { + throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text)); + } + SetPropertyPresence(reader, closestMatchProperty, dictionary); + SetPropertyValue(closestMatchProperty, reader, newObject); + } + } + catch (Exception ex) + { + if (!IsErrorHandled(newObject, contract, text, ex)) + { + throw; + } + HandleError(reader, depth); + } + break; + } + case JsonToken.EndObject: + foreach (KeyValuePair item in dictionary) + { + JsonProperty key = item.Key; + switch (item.Value) + { + case PropertyPresence.None: + if (key.Required == Required.AllowNull || key.Required == Required.Always) + { + throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName)); + } + if (HasFlag(key.DefaultValueHandling.GetValueOrDefault(base.Serializer.DefaultValueHandling), DefaultValueHandling.Populate) && key.Writable) + { + key.ValueProvider.SetValue(newObject, EnsureType(key.DefaultValue, CultureInfo.InvariantCulture, key.PropertyType)); + } + break; + case PropertyPresence.Null: + if (key.Required == Required.Always) + { + throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName)); + } + break; + } + } + contract.InvokeOnDeserialized(newObject, base.Serializer.Context); + return newObject; + default: + throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); + case JsonToken.Comment: + break; + } + } + while (reader.Read()); + throw new JsonSerializationException("Unexpected end when deserializing object."); + } + + private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dictionary requiredProperties) + { + if (property != null) + { + requiredProperties[property] = ((reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined) ? PropertyPresence.Null : PropertyPresence.Value); + } + } + + private void HandleError(JsonReader reader, int initialDepth) + { + ClearErrorContext(); + reader.Skip(); + while (reader.Depth > initialDepth + 1) + { + reader.Read(); + } + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonSerializerInternalWriter.cs b/Newtonsoft.Json.Serialization/JsonSerializerInternalWriter.cs new file mode 100644 index 00000000..446b4bb8 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonSerializerInternalWriter.cs @@ -0,0 +1,517 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Runtime.Serialization; +using System.Security; +using UnityEngine; + +namespace Newtonsoft.Json.Serialization +{ + internal class JsonSerializerInternalWriter : JsonSerializerInternalBase + { + private JsonSerializerProxy _internalSerializer; + + private List _serializeStack; + + private List SerializeStack + { + get + { + if (_serializeStack == null) + { + _serializeStack = new List(); + } + return _serializeStack; + } + } + + public JsonSerializerInternalWriter(JsonSerializer serializer) + : base(serializer) + { + } + + public void Serialize(JsonWriter jsonWriter, object value) + { + if (jsonWriter == null) + { + throw new ArgumentNullException("jsonWriter"); + } + SerializeValue(jsonWriter, value, GetContractSafe(value), null, null); + } + + private JsonSerializerProxy GetInternalSerializer() + { + if (_internalSerializer == null) + { + _internalSerializer = new JsonSerializerProxy(this); + } + return _internalSerializer; + } + + private JsonContract GetContractSafe(object value) + { + if (value == null) + { + return null; + } + return base.Serializer.ContractResolver.ResolveContract(value.GetType()); + } + + private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContract collectionValueContract) + { + if (contract.UnderlyingType == typeof(byte[]) && ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract)) + { + writer.WriteStartObject(); + WriteTypeProperty(writer, contract.CreatedType); + writer.WritePropertyName("$value"); + writer.WriteValue(value); + writer.WriteEndObject(); + } + else + { + writer.WriteValue(value); + } + } + + private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContract collectionValueContract) + { + JsonConverter jsonConverter = member?.Converter; + if (value == null) + { + writer.WriteNull(); + } + else if ((jsonConverter != null || (jsonConverter = valueContract.Converter) != null || (jsonConverter = base.Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null || (jsonConverter = valueContract.InternalConverter) != null) && jsonConverter.CanWrite) + { + SerializeConvertable(writer, jsonConverter, value, valueContract); + } + else if (valueContract is JsonPrimitiveContract) + { + SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, collectionValueContract); + } + else if (valueContract is JsonStringContract) + { + SerializeString(writer, value, (JsonStringContract)valueContract); + } + else if (valueContract is JsonObjectContract) + { + SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionValueContract); + } + else if (valueContract is JsonDictionaryContract) + { + JsonDictionaryContract jsonDictionaryContract = (JsonDictionaryContract)valueContract; + SerializeDictionary(writer, jsonDictionaryContract.CreateWrapper(value), jsonDictionaryContract, member, collectionValueContract); + } + else if (valueContract is JsonArrayContract) + { + JsonArrayContract jsonArrayContract = (JsonArrayContract)valueContract; + SerializeList(writer, jsonArrayContract.CreateWrapper(value), jsonArrayContract, member, collectionValueContract); + } + else if (valueContract is JsonLinqContract) + { + ((JToken)value).WriteTo(writer, (base.Serializer.Converters == null) ? null : base.Serializer.Converters.ToArray()); + } + else if (valueContract is JsonISerializableContract) + { + SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract); + } + } + + private bool ShouldWriteReference(object value, JsonProperty property, JsonContract contract) + { + if (value == null) + { + return false; + } + if (contract is JsonPrimitiveContract) + { + return false; + } + bool? flag = null; + if (property != null) + { + flag = property.IsReference; + } + if (!flag.HasValue) + { + flag = contract.IsReference; + } + if (!flag.HasValue) + { + flag = ((!(contract is JsonArrayContract)) ? new bool?(HasFlag(base.Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects)) : new bool?(HasFlag(base.Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays))); + } + if (!flag.Value) + { + return false; + } + return base.Serializer.ReferenceResolver.IsReferenced(this, value); + } + + private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract) + { + string propertyName = property.PropertyName; + object defaultValue = property.DefaultValue; + if ((property.NullValueHandling.GetValueOrDefault(base.Serializer.NullValueHandling) != NullValueHandling.Ignore || memberValue != null) && (!HasFlag(property.DefaultValueHandling.GetValueOrDefault(base.Serializer.DefaultValueHandling), DefaultValueHandling.Ignore) || !MiscellaneousUtils.ValueEquals(memberValue, defaultValue))) + { + if (ShouldWriteReference(memberValue, property, contract)) + { + writer.WritePropertyName(propertyName); + WriteReference(writer, memberValue); + } + else if (CheckForCircularReference(memberValue, property.ReferenceLoopHandling, contract)) + { + if (memberValue == null && property.Required == Required.Always) + { + throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); + } + writer.WritePropertyName(propertyName); + SerializeValue(writer, memberValue, contract, property, null); + } + } + } + + private bool CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract) + { + if (value == null || contract is JsonPrimitiveContract) + { + return true; + } + if (SerializeStack.IndexOf(value) != -1) + { + switch ((value is Vector2 || value is Vector3 || value is Vector4 || value is Color || value is Color32) ? ReferenceLoopHandling.Ignore : referenceLoopHandling.GetValueOrDefault(base.Serializer.ReferenceLoopHandling)) + { + case ReferenceLoopHandling.Error: + throw new JsonSerializationException("Self referencing loop detected for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + case ReferenceLoopHandling.Ignore: + return false; + case ReferenceLoopHandling.Serialize: + return true; + default: + throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, base.Serializer.ReferenceLoopHandling)); + } + } + return true; + } + + private void WriteReference(JsonWriter writer, object value) + { + writer.WriteStartObject(); + writer.WritePropertyName("$ref"); + writer.WriteValue(base.Serializer.ReferenceResolver.GetReference(this, value)); + writer.WriteEndObject(); + } + + internal static bool TryConvertToString(object value, Type type, out string s) + { + TypeConverter converter = ConvertUtils.GetConverter(type); + if (converter != null && !(converter is ComponentConverter) && converter.GetType() != typeof(TypeConverter) && converter.CanConvertTo(typeof(string))) + { + s = converter.ConvertToInvariantString(value); + return true; + } + if (value is Type) + { + s = ((Type)value).AssemblyQualifiedName; + return true; + } + s = null; + return false; + } + + private void SerializeString(JsonWriter writer, object value, JsonStringContract contract) + { + contract.InvokeOnSerializing(value, base.Serializer.Context); + TryConvertToString(value, contract.UnderlyingType, out string s); + writer.WriteValue(s); + contract.InvokeOnSerialized(value, base.Serializer.Context); + } + + private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContract collectionValueContract) + { + contract.InvokeOnSerializing(value, base.Serializer.Context); + SerializeStack.Add(value); + writer.WriteStartObject(); + bool? isReference = contract.IsReference; + if ((!isReference.HasValue) ? HasFlag(base.Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects) : isReference.Value) + { + writer.WritePropertyName("$id"); + writer.WriteValue(base.Serializer.ReferenceResolver.GetReference(this, value)); + } + if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract)) + { + WriteTypeProperty(writer, contract.UnderlyingType); + } + int top = writer.Top; + foreach (JsonProperty property in contract.Properties) + { + try + { + if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value)) + { + object value2 = property.ValueProvider.GetValue(value); + JsonContract contractSafe = GetContractSafe(value2); + WriteMemberInfoProperty(writer, value2, property, contractSafe); + } + } + catch (Exception ex) + { + if (!IsErrorHandled(value, contract, property.PropertyName, ex)) + { + throw; + } + HandleError(writer, top); + } + } + writer.WriteEndObject(); + SerializeStack.RemoveAt(SerializeStack.Count - 1); + contract.InvokeOnSerialized(value, base.Serializer.Context); + } + + private void WriteTypeProperty(JsonWriter writer, Type type) + { + writer.WritePropertyName("$type"); + writer.WriteValue(ReflectionUtils.GetTypeName(type, base.Serializer.TypeNameAssemblyFormat, base.Serializer.Binder)); + } + + private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) + { + return (value & flag) == flag; + } + + private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag) + { + return (value & flag) == flag; + } + + private bool HasFlag(TypeNameHandling value, TypeNameHandling flag) + { + return (value & flag) == flag; + } + + private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract) + { + if (ShouldWriteReference(value, null, contract)) + { + WriteReference(writer, value); + } + else if (CheckForCircularReference(value, null, contract)) + { + SerializeStack.Add(value); + converter.WriteJson(writer, value, GetInternalSerializer()); + SerializeStack.RemoveAt(SerializeStack.Count - 1); + } + } + + private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContract collectionValueContract) + { + contract.InvokeOnSerializing(values.UnderlyingCollection, base.Serializer.Context); + SerializeStack.Add(values.UnderlyingCollection); + bool? isReference = contract.IsReference; + bool flag = (!isReference.HasValue) ? HasFlag(base.Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays) : isReference.Value; + bool flag2 = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract); + if (flag || flag2) + { + writer.WriteStartObject(); + if (flag) + { + writer.WritePropertyName("$id"); + writer.WriteValue(base.Serializer.ReferenceResolver.GetReference(this, values.UnderlyingCollection)); + } + if (flag2) + { + WriteTypeProperty(writer, values.UnderlyingCollection.GetType()); + } + writer.WritePropertyName("$values"); + } + JsonContract collectionValueContract2 = base.Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object)); + writer.WriteStartArray(); + int top = writer.Top; + int num = 0; + foreach (object value in values) + { + try + { + JsonContract contractSafe = GetContractSafe(value); + if (ShouldWriteReference(value, null, contractSafe)) + { + WriteReference(writer, value); + } + else if (CheckForCircularReference(value, null, contract)) + { + SerializeValue(writer, value, contractSafe, null, collectionValueContract2); + } + } + catch (Exception ex) + { + if (!IsErrorHandled(values.UnderlyingCollection, contract, num, ex)) + { + throw; + } + HandleError(writer, top); + } + finally + { + num++; + } + } + writer.WriteEndArray(); + if (flag || flag2) + { + writer.WriteEndObject(); + } + SerializeStack.RemoveAt(SerializeStack.Count - 1); + contract.InvokeOnSerialized(values.UnderlyingCollection, base.Serializer.Context); + } + + [SecuritySafeCritical] + [SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Security.SecuritySafeCriticalAttribute")] + private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract) + { + contract.InvokeOnSerializing(value, base.Serializer.Context); + SerializeStack.Add(value); + writer.WriteStartObject(); + SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter()); + value.GetObjectData(serializationInfo, base.Serializer.Context); + SerializationInfoEnumerator enumerator = serializationInfo.GetEnumerator(); + while (enumerator.MoveNext()) + { + SerializationEntry current = enumerator.Current; + writer.WritePropertyName(current.Name); + SerializeValue(writer, current.Value, GetContractSafe(current.Value), null, null); + } + writer.WriteEndObject(); + SerializeStack.RemoveAt(SerializeStack.Count - 1); + contract.InvokeOnSerialized(value, base.Serializer.Context); + } + + private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContract collectionValueContract) + { + TypeNameHandling? typeNameHandling = member?.TypeNameHandling; + if (HasFlag((!typeNameHandling.HasValue) ? base.Serializer.TypeNameHandling : typeNameHandling.Value, typeNameHandlingFlag)) + { + return true; + } + if (member != null) + { + TypeNameHandling? typeNameHandling2 = member.TypeNameHandling; + if (((!typeNameHandling2.HasValue) ? base.Serializer.TypeNameHandling : typeNameHandling2.Value) == TypeNameHandling.Auto && contract.UnderlyingType != member.PropertyType) + { + JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(member.PropertyType); + if (contract.UnderlyingType != jsonContract.CreatedType) + { + return true; + } + } + } + else if (collectionValueContract != null && base.Serializer.TypeNameHandling == TypeNameHandling.Auto && contract.UnderlyingType != collectionValueContract.UnderlyingType) + { + return true; + } + return false; + } + + private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContract collectionValueContract) + { + contract.InvokeOnSerializing(values.UnderlyingDictionary, base.Serializer.Context); + SerializeStack.Add(values.UnderlyingDictionary); + writer.WriteStartObject(); + bool? isReference = contract.IsReference; + if ((!isReference.HasValue) ? HasFlag(base.Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects) : isReference.Value) + { + writer.WritePropertyName("$id"); + writer.WriteValue(base.Serializer.ReferenceResolver.GetReference(this, values.UnderlyingDictionary)); + } + if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract)) + { + WriteTypeProperty(writer, values.UnderlyingDictionary.GetType()); + } + JsonContract collectionValueContract2 = base.Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object)); + int top = writer.Top; + IDictionaryEnumerator enumerator = values.GetEnumerator(); + try + { + while (enumerator.MoveNext()) + { + DictionaryEntry entry = (DictionaryEntry)enumerator.Current; + string propertyName = GetPropertyName(entry); + propertyName = ((contract.PropertyNameResolver == null) ? propertyName : contract.PropertyNameResolver(propertyName)); + try + { + object value = entry.Value; + JsonContract contractSafe = GetContractSafe(value); + if (ShouldWriteReference(value, null, contractSafe)) + { + writer.WritePropertyName(propertyName); + WriteReference(writer, value); + } + else if (CheckForCircularReference(value, null, contract)) + { + writer.WritePropertyName(propertyName); + SerializeValue(writer, value, contractSafe, null, collectionValueContract2); + } + } + catch (Exception ex) + { + if (!IsErrorHandled(values.UnderlyingDictionary, contract, propertyName, ex)) + { + throw; + } + HandleError(writer, top); + } + } + } + finally + { + (enumerator as IDisposable)?.Dispose(); + } + writer.WriteEndObject(); + SerializeStack.RemoveAt(SerializeStack.Count - 1); + contract.InvokeOnSerialized(values.UnderlyingDictionary, base.Serializer.Context); + } + + private string GetPropertyName(DictionaryEntry entry) + { + if (entry.Key is IConvertible) + { + return Convert.ToString(entry.Key, CultureInfo.InvariantCulture); + } + if (TryConvertToString(entry.Key, entry.Key.GetType(), out string s)) + { + return s; + } + return entry.Key.ToString(); + } + + private void HandleError(JsonWriter writer, int initialDepth) + { + ClearErrorContext(); + while (writer.Top > initialDepth) + { + writer.WriteEnd(); + } + } + + private bool ShouldSerialize(JsonProperty property, object target) + { + if (property.ShouldSerialize == null) + { + return true; + } + return property.ShouldSerialize(target); + } + + private bool IsSpecified(JsonProperty property, object target) + { + if (property.GetIsSpecified == null) + { + return true; + } + return property.GetIsSpecified(target); + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonSerializerProxy.cs b/Newtonsoft.Json.Serialization/JsonSerializerProxy.cs new file mode 100644 index 00000000..7f3d1bf9 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonSerializerProxy.cs @@ -0,0 +1,242 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters; + +namespace Newtonsoft.Json.Serialization +{ + internal class JsonSerializerProxy : JsonSerializer + { + private readonly JsonSerializerInternalReader _serializerReader; + + private readonly JsonSerializerInternalWriter _serializerWriter; + + private readonly JsonSerializer _serializer; + + public override IReferenceResolver ReferenceResolver + { + get + { + return _serializer.ReferenceResolver; + } + set + { + _serializer.ReferenceResolver = value; + } + } + + public override JsonConverterCollection Converters => _serializer.Converters; + + public override DefaultValueHandling DefaultValueHandling + { + get + { + return _serializer.DefaultValueHandling; + } + set + { + _serializer.DefaultValueHandling = value; + } + } + + public override IContractResolver ContractResolver + { + get + { + return _serializer.ContractResolver; + } + set + { + _serializer.ContractResolver = value; + } + } + + public override MissingMemberHandling MissingMemberHandling + { + get + { + return _serializer.MissingMemberHandling; + } + set + { + _serializer.MissingMemberHandling = value; + } + } + + public override NullValueHandling NullValueHandling + { + get + { + return _serializer.NullValueHandling; + } + set + { + _serializer.NullValueHandling = value; + } + } + + public override ObjectCreationHandling ObjectCreationHandling + { + get + { + return _serializer.ObjectCreationHandling; + } + set + { + _serializer.ObjectCreationHandling = value; + } + } + + public override ReferenceLoopHandling ReferenceLoopHandling + { + get + { + return _serializer.ReferenceLoopHandling; + } + set + { + _serializer.ReferenceLoopHandling = value; + } + } + + public override PreserveReferencesHandling PreserveReferencesHandling + { + get + { + return _serializer.PreserveReferencesHandling; + } + set + { + _serializer.PreserveReferencesHandling = value; + } + } + + public override TypeNameHandling TypeNameHandling + { + get + { + return _serializer.TypeNameHandling; + } + set + { + _serializer.TypeNameHandling = value; + } + } + + public override FormatterAssemblyStyle TypeNameAssemblyFormat + { + get + { + return _serializer.TypeNameAssemblyFormat; + } + set + { + _serializer.TypeNameAssemblyFormat = value; + } + } + + public override ConstructorHandling ConstructorHandling + { + get + { + return _serializer.ConstructorHandling; + } + set + { + _serializer.ConstructorHandling = value; + } + } + + public override SerializationBinder Binder + { + get + { + return _serializer.Binder; + } + set + { + _serializer.Binder = value; + } + } + + public override StreamingContext Context + { + get + { + return _serializer.Context; + } + set + { + _serializer.Context = value; + } + } + + public override event EventHandler Error + { + add + { + _serializer.Error += value; + } + remove + { + _serializer.Error -= value; + } + } + + public JsonSerializerProxy(JsonSerializerInternalReader serializerReader) + { + ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader"); + _serializerReader = serializerReader; + _serializer = serializerReader.Serializer; + } + + public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter) + { + ValidationUtils.ArgumentNotNull(serializerWriter, "serializerWriter"); + _serializerWriter = serializerWriter; + _serializer = serializerWriter.Serializer; + } + + internal JsonSerializerInternalBase GetInternalSerializer() + { + if (_serializerReader != null) + { + return _serializerReader; + } + return _serializerWriter; + } + + internal override object DeserializeInternal(JsonReader reader, Type objectType) + { + if (_serializerReader != null) + { + return _serializerReader.Deserialize(reader, objectType); + } + return _serializer.Deserialize(reader, objectType); + } + + internal override void PopulateInternal(JsonReader reader, object target) + { + if (_serializerReader != null) + { + _serializerReader.Populate(reader, target); + } + else + { + _serializer.Populate(reader, target); + } + } + + internal override void SerializeInternal(JsonWriter jsonWriter, object value) + { + if (_serializerWriter != null) + { + _serializerWriter.Serialize(jsonWriter, value); + } + else + { + _serializer.Serialize(jsonWriter, value); + } + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonStringContract.cs b/Newtonsoft.Json.Serialization/JsonStringContract.cs new file mode 100644 index 00000000..a4064df9 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonStringContract.cs @@ -0,0 +1,12 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + public class JsonStringContract : JsonContract + { + public JsonStringContract(Type underlyingType) + : base(underlyingType) + { + } + } +} diff --git a/Newtonsoft.Json.Serialization/JsonTypeReflector.cs b/Newtonsoft.Json.Serialization/JsonTypeReflector.cs new file mode 100644 index 00000000..9844fbb1 --- /dev/null +++ b/Newtonsoft.Json.Serialization/JsonTypeReflector.cs @@ -0,0 +1,297 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; +using System.Security.Permissions; + +namespace Newtonsoft.Json.Serialization +{ + internal static class JsonTypeReflector + { + public const string IdPropertyName = "$id"; + + public const string RefPropertyName = "$ref"; + + public const string TypePropertyName = "$type"; + + public const string ValuePropertyName = "$value"; + + public const string ArrayValuesPropertyName = "$values"; + + public const string ShouldSerializePrefix = "ShouldSerialize"; + + public const string SpecifiedPostfix = "Specified"; + + private const string MetadataTypeAttributeTypeName = "System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + + private static readonly ThreadSafeStore JsonConverterTypeCache = new ThreadSafeStore(GetJsonConverterTypeFromAttribute); + + private static readonly ThreadSafeStore AssociatedMetadataTypesCache = new ThreadSafeStore(GetAssociateMetadataTypeFromAttribute); + + private static Type _cachedMetadataTypeAttributeType; + + private static bool? _dynamicCodeGeneration; + + public static bool DynamicCodeGeneration + { + get + { + bool? dynamicCodeGeneration = _dynamicCodeGeneration; + if (!dynamicCodeGeneration.HasValue) + { + try + { + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); + new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand(); + new SecurityPermission(SecurityPermissionFlag.SkipVerification).Demand(); + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); + new SecurityPermission(PermissionState.Unrestricted).Demand(); + _dynamicCodeGeneration = true; + } + catch (Exception) + { + _dynamicCodeGeneration = false; + } + } + return _dynamicCodeGeneration.Value; + } + } + + public static ReflectionDelegateFactory ReflectionDelegateFactory + { + get + { + if (DynamicCodeGeneration) + { + return DynamicReflectionDelegateFactory.Instance; + } + return LateBoundReflectionDelegateFactory.Instance; + } + } + + public static JsonContainerAttribute GetJsonContainerAttribute(Type type) + { + return CachedAttributeGetter.GetAttribute(type); + } + + public static JsonObjectAttribute GetJsonObjectAttribute(Type type) + { + return GetJsonContainerAttribute(type) as JsonObjectAttribute; + } + + public static JsonArrayAttribute GetJsonArrayAttribute(Type type) + { + return GetJsonContainerAttribute(type) as JsonArrayAttribute; + } + + public static DataContractAttribute GetDataContractAttribute(Type type) + { + DataContractAttribute dataContractAttribute = null; + Type type2 = type; + while (dataContractAttribute == null && type2 != null) + { + dataContractAttribute = CachedAttributeGetter.GetAttribute(type2); + type2 = type2.BaseType; + } + return dataContractAttribute; + } + + public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo) + { + if (memberInfo.MemberType == MemberTypes.Field) + { + return CachedAttributeGetter.GetAttribute(memberInfo); + } + PropertyInfo propertyInfo = (PropertyInfo)memberInfo; + DataMemberAttribute attribute = CachedAttributeGetter.GetAttribute(propertyInfo); + if (attribute == null && propertyInfo.IsVirtual()) + { + Type type = propertyInfo.DeclaringType; + while (attribute == null && type != null) + { + PropertyInfo propertyInfo2 = (PropertyInfo)ReflectionUtils.GetMemberInfoFromType(type, propertyInfo); + if (propertyInfo2 != null && propertyInfo2.IsVirtual()) + { + attribute = CachedAttributeGetter.GetAttribute(propertyInfo2); + } + type = type.BaseType; + } + } + return attribute; + } + + public static MemberSerialization GetObjectMemberSerialization(Type objectType) + { + JsonObjectAttribute jsonObjectAttribute = GetJsonObjectAttribute(objectType); + if (jsonObjectAttribute == null) + { + DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType); + if (dataContractAttribute != null) + { + return MemberSerialization.OptIn; + } + return MemberSerialization.OptOut; + } + return jsonObjectAttribute.MemberSerialization; + } + + private static Type GetJsonConverterType(ICustomAttributeProvider attributeProvider) + { + return JsonConverterTypeCache.Get(attributeProvider); + } + + private static Type GetJsonConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider) + { + return GetAttribute(attributeProvider)?.ConverterType; + } + + public static JsonConverter GetJsonConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType) + { + Type jsonConverterType = GetJsonConverterType(attributeProvider); + if (jsonConverterType != null) + { + JsonConverter jsonConverter = JsonConverterAttribute.CreateJsonConverterInstance(jsonConverterType); + if (!jsonConverter.CanConvert(targetConvertedType)) + { + throw new JsonSerializationException("JsonConverter {0} on {1} is not compatible with member type {2}.".FormatWith(CultureInfo.InvariantCulture, jsonConverter.GetType().Name, attributeProvider, targetConvertedType.Name)); + } + return jsonConverter; + } + return null; + } + + public static TypeConverter GetTypeConverter(Type type) + { + return TypeDescriptor.GetConverter(type); + } + + private static Type GetAssociatedMetadataType(Type type) + { + return AssociatedMetadataTypesCache.Get(type); + } + + private static Type GetAssociateMetadataTypeFromAttribute(Type type) + { + Type metadataTypeAttributeType = GetMetadataTypeAttributeType(); + if (metadataTypeAttributeType == null) + { + return null; + } + object obj = type.GetCustomAttributes(metadataTypeAttributeType, inherit: true).SingleOrDefault(); + if (obj == null) + { + return null; + } + object obj2; + if (DynamicCodeGeneration) + { + IMetadataTypeAttribute metadataTypeAttribute = DynamicWrapper.CreateWrapper(obj); + obj2 = metadataTypeAttribute; + } + else + { + obj2 = new LateBoundMetadataTypeAttribute(obj); + } + IMetadataTypeAttribute metadataTypeAttribute2 = (IMetadataTypeAttribute)obj2; + return metadataTypeAttribute2.MetadataClassType; + } + + private static Type GetMetadataTypeAttributeType() + { + if (_cachedMetadataTypeAttributeType == null) + { + Type type = Type.GetType("System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"); + if (type == null) + { + return null; + } + _cachedMetadataTypeAttributeType = type; + } + return _cachedMetadataTypeAttributeType; + } + + private static T GetAttribute(Type type) where T : Attribute + { + Type associatedMetadataType = GetAssociatedMetadataType(type); + T attribute; + if (associatedMetadataType != null) + { + attribute = ReflectionUtils.GetAttribute(associatedMetadataType, inherit: true); + if (attribute != null) + { + return attribute; + } + } + attribute = ReflectionUtils.GetAttribute(type, inherit: true); + if (attribute != null) + { + return attribute; + } + Type[] interfaces = type.GetInterfaces(); + foreach (Type attributeProvider in interfaces) + { + attribute = ReflectionUtils.GetAttribute(attributeProvider, inherit: true); + if (attribute != null) + { + return attribute; + } + } + return (T)null; + } + + private static T GetAttribute(MemberInfo memberInfo) where T : Attribute + { + Type associatedMetadataType = GetAssociatedMetadataType(memberInfo.DeclaringType); + T attribute; + if (associatedMetadataType != null) + { + MemberInfo memberInfoFromType = ReflectionUtils.GetMemberInfoFromType(associatedMetadataType, memberInfo); + if (memberInfoFromType != null) + { + attribute = ReflectionUtils.GetAttribute(memberInfoFromType, inherit: true); + if (attribute != null) + { + return attribute; + } + } + } + attribute = ReflectionUtils.GetAttribute(memberInfo, inherit: true); + if (attribute != null) + { + return attribute; + } + Type[] interfaces = memberInfo.DeclaringType.GetInterfaces(); + foreach (Type targetType in interfaces) + { + MemberInfo memberInfoFromType2 = ReflectionUtils.GetMemberInfoFromType(targetType, memberInfo); + if (memberInfoFromType2 != null) + { + attribute = ReflectionUtils.GetAttribute(memberInfoFromType2, inherit: true); + if (attribute != null) + { + return attribute; + } + } + } + return (T)null; + } + + public static T GetAttribute(ICustomAttributeProvider attributeProvider) where T : Attribute + { + Type type = attributeProvider as Type; + if (type != null) + { + return GetAttribute(type); + } + MemberInfo memberInfo = attributeProvider as MemberInfo; + if (memberInfo != null) + { + return GetAttribute(memberInfo); + } + return ReflectionUtils.GetAttribute(attributeProvider, inherit: true); + } + } +} diff --git a/Newtonsoft.Json.Serialization/LateBoundMetadataTypeAttribute.cs b/Newtonsoft.Json.Serialization/LateBoundMetadataTypeAttribute.cs new file mode 100644 index 00000000..cca0b6d9 --- /dev/null +++ b/Newtonsoft.Json.Serialization/LateBoundMetadataTypeAttribute.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Reflection; + +namespace Newtonsoft.Json.Serialization +{ + internal class LateBoundMetadataTypeAttribute : IMetadataTypeAttribute + { + private static PropertyInfo _metadataClassTypeProperty; + + private readonly object _attribute; + + public Type MetadataClassType + { + get + { + if (_metadataClassTypeProperty == null) + { + _metadataClassTypeProperty = _attribute.GetType().GetProperty("MetadataClassType"); + } + return (Type)ReflectionUtils.GetMemberValue(_metadataClassTypeProperty, _attribute); + } + } + + public LateBoundMetadataTypeAttribute(object attribute) + { + _attribute = attribute; + } + } +} diff --git a/Newtonsoft.Json.Serialization/ObjectConstructor.cs b/Newtonsoft.Json.Serialization/ObjectConstructor.cs new file mode 100644 index 00000000..2032d27f --- /dev/null +++ b/Newtonsoft.Json.Serialization/ObjectConstructor.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.Serialization +{ + public delegate object ObjectConstructor(params object[] args); +} diff --git a/Newtonsoft.Json.Serialization/OnErrorAttribute.cs b/Newtonsoft.Json.Serialization/OnErrorAttribute.cs new file mode 100644 index 00000000..95e90f74 --- /dev/null +++ b/Newtonsoft.Json.Serialization/OnErrorAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + [AttributeUsage(AttributeTargets.Method, Inherited = false)] + public sealed class OnErrorAttribute : Attribute + { + } +} diff --git a/Newtonsoft.Json.Serialization/ReflectionValueProvider.cs b/Newtonsoft.Json.Serialization/ReflectionValueProvider.cs new file mode 100644 index 00000000..b08e46a9 --- /dev/null +++ b/Newtonsoft.Json.Serialization/ReflectionValueProvider.cs @@ -0,0 +1,49 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; +using System.Reflection; + +namespace Newtonsoft.Json.Serialization +{ + public class ReflectionValueProvider : IValueProvider + { + private readonly MemberInfo _memberInfo; + + public ReflectionValueProvider(MemberInfo memberInfo) + { + ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); + _memberInfo = memberInfo; + } + + public void SetValue(object target, object value) + { + try + { + ReflectionUtils.SetMemberValue(_memberInfo, target, value); + } + catch (Exception innerException) + { + throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), innerException); + IL_0046:; + } + } + + public object GetValue(object target) + { + try + { + return ReflectionUtils.GetMemberValue(_memberInfo, target); + IL_0012: + object result; + return result; + } + catch (Exception innerException) + { + throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), innerException); + IL_004b: + object result; + return result; + } + } + } +} diff --git a/Newtonsoft.Json.Serialization/ResolverContractKey.cs b/Newtonsoft.Json.Serialization/ResolverContractKey.cs new file mode 100644 index 00000000..2639f1fc --- /dev/null +++ b/Newtonsoft.Json.Serialization/ResolverContractKey.cs @@ -0,0 +1,36 @@ +using System; + +namespace Newtonsoft.Json.Serialization +{ + internal struct ResolverContractKey : IEquatable + { + private readonly Type _resolverType; + + private readonly Type _contractType; + + public ResolverContractKey(Type resolverType, Type contractType) + { + _resolverType = resolverType; + _contractType = contractType; + } + + public override int GetHashCode() + { + return _resolverType.GetHashCode() ^ _contractType.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (!(obj is ResolverContractKey)) + { + return false; + } + return Equals((ResolverContractKey)obj); + } + + public bool Equals(ResolverContractKey other) + { + return _resolverType == other._resolverType && _contractType == other._contractType; + } + } +} diff --git a/Newtonsoft.Json.Utilities/Base64Encoder.cs b/Newtonsoft.Json.Utilities/Base64Encoder.cs new file mode 100644 index 00000000..c411aa58 --- /dev/null +++ b/Newtonsoft.Json.Utilities/Base64Encoder.cs @@ -0,0 +1,102 @@ +using System; +using System.IO; + +namespace Newtonsoft.Json.Utilities +{ + internal class Base64Encoder + { + private const int Base64LineSize = 76; + + private const int LineSizeInBytes = 57; + + private readonly char[] _charsLine = new char[76]; + + private readonly TextWriter _writer; + + private byte[] _leftOverBytes; + + private int _leftOverBytesCount; + + public Base64Encoder(TextWriter writer) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + _writer = writer; + } + + public void Encode(byte[] buffer, int index, int count) + { + if (buffer == null) + { + throw new ArgumentNullException("buffer"); + } + if (index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + if (count < 0) + { + throw new ArgumentOutOfRangeException("count"); + } + if (count > buffer.Length - index) + { + throw new ArgumentOutOfRangeException("count"); + } + if (_leftOverBytesCount > 0) + { + int num = _leftOverBytesCount; + while (num < 3 && count > 0) + { + _leftOverBytes[num++] = buffer[index++]; + count--; + } + if (count == 0 && num < 3) + { + _leftOverBytesCount = num; + return; + } + int count2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0); + WriteChars(_charsLine, 0, count2); + } + _leftOverBytesCount = count % 3; + if (_leftOverBytesCount > 0) + { + count -= _leftOverBytesCount; + if (_leftOverBytes == null) + { + _leftOverBytes = new byte[3]; + } + for (int i = 0; i < _leftOverBytesCount; i++) + { + _leftOverBytes[i] = buffer[index + count + i]; + } + } + int num4 = index + count; + int num5 = 57; + while (index < num4) + { + if (index + num5 > num4) + { + num5 = num4 - index; + } + int count3 = Convert.ToBase64CharArray(buffer, index, num5, _charsLine, 0); + WriteChars(_charsLine, 0, count3); + index += num5; + } + } + + public void Flush() + { + if (_leftOverBytesCount > 0) + { + int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0); + WriteChars(_charsLine, 0, count); + _leftOverBytesCount = 0; + } + } + + private void WriteChars(char[] chars, int index, int count) + { + _writer.Write(chars, index, count); + } + } +} diff --git a/Newtonsoft.Json.Utilities/BidirectionalDictionary.cs b/Newtonsoft.Json.Utilities/BidirectionalDictionary.cs new file mode 100644 index 00000000..ffe23f4e --- /dev/null +++ b/Newtonsoft.Json.Utilities/BidirectionalDictionary.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Utilities +{ + internal class BidirectionalDictionary + { + private readonly IDictionary _firstToSecond; + + private readonly IDictionary _secondToFirst; + + public BidirectionalDictionary() + : this((IEqualityComparer)EqualityComparer.Default, (IEqualityComparer)EqualityComparer.Default) + { + } + + public BidirectionalDictionary(IEqualityComparer firstEqualityComparer, IEqualityComparer secondEqualityComparer) + { + _firstToSecond = new Dictionary(firstEqualityComparer); + _secondToFirst = new Dictionary(secondEqualityComparer); + } + + public void Add(TFirst first, TSecond second) + { + if (_firstToSecond.ContainsKey(first) || _secondToFirst.ContainsKey(second)) + { + throw new ArgumentException("Duplicate first or second"); + } + _firstToSecond.Add(first, second); + _secondToFirst.Add(second, first); + } + + public bool TryGetByFirst(TFirst first, out TSecond second) + { + return _firstToSecond.TryGetValue(first, out second); + } + + public bool TryGetBySecond(TSecond second, out TFirst first) + { + return _secondToFirst.TryGetValue(second, out first); + } + } +} diff --git a/Newtonsoft.Json.Utilities/CollectionUtils.cs b/Newtonsoft.Json.Utilities/CollectionUtils.cs new file mode 100644 index 00000000..7a5835a7 --- /dev/null +++ b/Newtonsoft.Json.Utilities/CollectionUtils.cs @@ -0,0 +1,556 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Reflection; + +namespace Newtonsoft.Json.Utilities +{ + internal static class CollectionUtils + { + public static IEnumerable CastValid(this IEnumerable enumerable) + { + ValidationUtils.ArgumentNotNull(enumerable, "enumerable"); + return (from object o in enumerable + where o is T + select o).Cast(); + } + + public static List CreateList(params T[] values) + { + return new List(values); + } + + public static bool IsNullOrEmpty(ICollection collection) + { + if (collection != null) + { + return collection.Count == 0; + } + return true; + } + + public static bool IsNullOrEmpty(ICollection collection) + { + if (collection != null) + { + return collection.Count == 0; + } + return true; + } + + public static bool IsNullOrEmptyOrDefault(IList list) + { + if (IsNullOrEmpty(list)) + { + return true; + } + return ReflectionUtils.ItemsUnitializedValue(list); + } + + public static IList Slice(IList list, int? start, int? end) + { + return Slice(list, start, end, null); + } + + public static IList Slice(IList list, int? start, int? end, int? step) + { + if (list == null) + { + throw new ArgumentNullException("list"); + } + if (step.GetValueOrDefault() == 0 && step.HasValue) + { + throw new ArgumentException("Step cannot be zero.", "step"); + } + List list2 = new List(); + if (list.Count == 0) + { + return list2; + } + int num = (!step.HasValue) ? 1 : step.Value; + int num2 = start.HasValue ? start.Value : 0; + int num3 = (!end.HasValue) ? list.Count : end.Value; + num2 = ((num2 >= 0) ? num2 : (list.Count + num2)); + num3 = ((num3 >= 0) ? num3 : (list.Count + num3)); + num2 = Math.Max(num2, 0); + num3 = Math.Min(num3, list.Count - 1); + for (int i = num2; i < num3; i += num) + { + list2.Add(list[i]); + } + return list2; + } + + public static Dictionary> GroupBy(ICollection source, Func keySelector) + { + if (keySelector == null) + { + throw new ArgumentNullException("keySelector"); + } + Dictionary> dictionary = new Dictionary>(); + foreach (V item in source) + { + K key = keySelector(item); + if (!dictionary.TryGetValue(key, out List value)) + { + value = new List(); + dictionary.Add(key, value); + } + value.Add(item); + } + return dictionary; + } + + public static void AddRange(this IList initial, IEnumerable collection) + { + if (initial == null) + { + throw new ArgumentNullException("initial"); + } + if (collection != null) + { + foreach (T item in collection) + { + initial.Add(item); + } + } + } + + public static void AddRange(this IList initial, IEnumerable collection) + { + ValidationUtils.ArgumentNotNull(initial, "initial"); + ListWrapper initial2 = new ListWrapper(initial); + initial2.AddRange(collection.Cast()); + } + + public static List Distinct(List collection) + { + List list = new List(); + foreach (T item in collection) + { + if (!list.Contains(item)) + { + list.Add(item); + } + } + return list; + } + + public static List> Flatten(params IList[] lists) + { + List> list = new List>(); + Dictionary currentSet = new Dictionary(); + Recurse(new List>(lists), 0, currentSet, list); + return list; + } + + private static void Recurse(IList> global, int current, Dictionary currentSet, List> flattenedResult) + { + IList list = global[current]; + for (int i = 0; i < list.Count; i++) + { + currentSet[current] = list[i]; + if (current == global.Count - 1) + { + List list2 = new List(); + for (int j = 0; j < currentSet.Count; j++) + { + list2.Add(currentSet[j]); + } + flattenedResult.Add(list2); + } + else + { + Recurse(global, current + 1, currentSet, flattenedResult); + } + } + } + + public static List CreateList(ICollection collection) + { + if (collection == null) + { + throw new ArgumentNullException("collection"); + } + T[] array = new T[collection.Count]; + collection.CopyTo(array, 0); + return new List(array); + } + + public static bool ListEquals(IList a, IList b) + { + if (a == null || b == null) + { + return a == null && b == null; + } + if (a.Count != b.Count) + { + return false; + } + EqualityComparer @default = EqualityComparer.Default; + for (int i = 0; i < a.Count; i++) + { + if (!@default.Equals(a[i], b[i])) + { + return false; + } + } + return true; + } + + public static bool TryGetSingleItem(IList list, out T value) + { + return TryGetSingleItem(list, /*returnDefaultIfEmpty:*/ false, out value); + } + + public static bool TryGetSingleItem(IList list, bool returnDefaultIfEmpty, out T value) + { + return MiscellaneousUtils.TryAction(() => GetSingleItem(list, returnDefaultIfEmpty), out value); + } + + public static T GetSingleItem(IList list) + { + return GetSingleItem(list, /*returnDefaultIfEmpty:*/ false); + } + + public static T GetSingleItem(IList list, bool returnDefaultIfEmpty) + { + if (list.Count == 1) + { + return list[0]; + } + if (returnDefaultIfEmpty && list.Count == 0) + { + return default(T); + } + throw new Exception("Expected single {0} in list but got {1}.".FormatWith(CultureInfo.InvariantCulture, typeof(T), list.Count)); + } + + public static IList Minus(IList list, IList minus) + { + ValidationUtils.ArgumentNotNull(list, "list"); + List list2 = new List(list.Count); + foreach (T item in list) + { + if (minus == null || !minus.Contains(item)) + { + list2.Add(item); + } + } + return list2; + } + + public static IList CreateGenericList(Type listType) + { + ValidationUtils.ArgumentNotNull(listType, "listType"); + return (IList)ReflectionUtils.CreateGeneric(typeof(List<>), listType); + } + + public static IDictionary CreateGenericDictionary(Type keyType, Type valueType) + { + ValidationUtils.ArgumentNotNull(keyType, "keyType"); + ValidationUtils.ArgumentNotNull(valueType, "valueType"); + return (IDictionary)ReflectionUtils.CreateGeneric(typeof(Dictionary<, >), keyType, valueType); + } + + public static bool IsListType(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + if (type.IsArray) + { + return true; + } + if (typeof(IList).IsAssignableFrom(type)) + { + return true; + } + if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IList<>))) + { + return true; + } + return false; + } + + public static bool IsCollectionType(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + if (type.IsArray) + { + return true; + } + if (typeof(ICollection).IsAssignableFrom(type)) + { + return true; + } + if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(ICollection<>))) + { + return true; + } + return false; + } + + public static bool IsDictionaryType(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + if (typeof(IDictionary).IsAssignableFrom(type)) + { + return true; + } + if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IDictionary<, >))) + { + return true; + } + return false; + } + + public static IWrappedCollection CreateCollectionWrapper(object list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + if (ReflectionUtils.ImplementsGenericDefinition(list.GetType(), typeof(ICollection<>), out Type collectionDefinition)) + { + Type collectionItemType = ReflectionUtils.GetCollectionItemType(collectionDefinition); + Func, object> instanceCreator = delegate(Type t, IList a) + { + ConstructorInfo constructor = t.GetConstructor(new Type[1] + { + collectionDefinition + }); + return constructor.Invoke(new object[1] + { + list + }); + }; + return (IWrappedCollection)ReflectionUtils.CreateGeneric(typeof(CollectionWrapper<>), new Type[1] + { + collectionItemType + }, instanceCreator, list); + } + if (list is IList) + { + return new CollectionWrapper((IList)list); + } + throw new Exception("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType())); + } + + public static IWrappedList CreateListWrapper(object list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + if (ReflectionUtils.ImplementsGenericDefinition(list.GetType(), typeof(IList<>), out Type listDefinition)) + { + Type collectionItemType = ReflectionUtils.GetCollectionItemType(listDefinition); + Func, object> instanceCreator = delegate(Type t, IList a) + { + ConstructorInfo constructor = t.GetConstructor(new Type[1] + { + listDefinition + }); + return constructor.Invoke(new object[1] + { + list + }); + }; + return (IWrappedList)ReflectionUtils.CreateGeneric(typeof(ListWrapper<>), new Type[1] + { + collectionItemType + }, instanceCreator, list); + } + if (list is IList) + { + return new ListWrapper((IList)list); + } + throw new Exception("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType())); + } + + public static IWrappedDictionary CreateDictionaryWrapper(object dictionary) + { + ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); + if (ReflectionUtils.ImplementsGenericDefinition(dictionary.GetType(), typeof(IDictionary<, >), out Type dictionaryDefinition)) + { + Type dictionaryKeyType = ReflectionUtils.GetDictionaryKeyType(dictionaryDefinition); + Type dictionaryValueType = ReflectionUtils.GetDictionaryValueType(dictionaryDefinition); + Func, object> instanceCreator = delegate(Type t, IList a) + { + ConstructorInfo constructor = t.GetConstructor(new Type[1] + { + dictionaryDefinition + }); + return constructor.Invoke(new object[1] + { + dictionary + }); + }; + return (IWrappedDictionary)ReflectionUtils.CreateGeneric(typeof(DictionaryWrapper<, >), new Type[2] + { + dictionaryKeyType, + dictionaryValueType + }, instanceCreator, dictionary); + } + if (dictionary is IDictionary) + { + return new DictionaryWrapper((IDictionary)dictionary); + } + throw new Exception("Can not create DictionaryWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, dictionary.GetType())); + } + + public static object CreateAndPopulateList(Type listType, Action populateList) + { + ValidationUtils.ArgumentNotNull(listType, "listType"); + ValidationUtils.ArgumentNotNull(populateList, "populateList"); + bool flag = false; + IList list; + Type implementingType; + if (listType.IsArray) + { + list = new List(); + flag = true; + } + else if (!ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>), out implementingType)) + { + list = (typeof(IList).IsAssignableFrom(listType) ? (ReflectionUtils.IsInstantiatableType(listType) ? ((IList)Activator.CreateInstance(listType)) : ((listType != typeof(IList)) ? null : new List())) : ((!ReflectionUtils.ImplementsGenericDefinition(listType, typeof(ICollection<>))) ? null : ((!ReflectionUtils.IsInstantiatableType(listType)) ? null : CreateCollectionWrapper(Activator.CreateInstance(listType))))); + } + else + { + Type type = implementingType.GetGenericArguments()[0]; + Type type2 = ReflectionUtils.MakeGenericType(typeof(IEnumerable<>), type); + bool flag2 = false; + ConstructorInfo[] constructors = listType.GetConstructors(); + foreach (ConstructorInfo constructorInfo in constructors) + { + IList parameters = constructorInfo.GetParameters(); + if (parameters.Count == 1 && type2.IsAssignableFrom(parameters[0].ParameterType)) + { + flag2 = true; + break; + } + } + if (!flag2) + { + throw new Exception("Read-only type {0} does not have a public constructor that takes a type that implements {1}.".FormatWith(CultureInfo.InvariantCulture, listType, type2)); + } + list = CreateGenericList(type); + flag = true; + } + if (list == null) + { + throw new Exception("Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, listType)); + } + populateList(list, flag); + if (flag) + { + if (listType.IsArray) + { + list = ToArray(((List)list).ToArray(), ReflectionUtils.GetCollectionItemType(listType)); + } + else if (ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>))) + { + list = (IList)ReflectionUtils.CreateInstance(listType, list); + } + } + else if (list is IWrappedCollection) + { + return ((IWrappedCollection)list).UnderlyingCollection; + } + return list; + } + + public static Array ToArray(Array initial, Type type) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + Array array = Array.CreateInstance(type, initial.Length); + Array.Copy(initial, 0, array, 0, initial.Length); + return array; + } + + public static bool AddDistinct(this IList list, T value) + { + return list.AddDistinct(value, EqualityComparer.Default); + } + + public static bool AddDistinct(this IList list, T value, IEqualityComparer comparer) + { + if (list.ContainsValue(value, comparer)) + { + return false; + } + list.Add(value); + return true; + } + + public static bool ContainsValue(this IEnumerable source, TSource value, IEqualityComparer comparer) + { + if (comparer == null) + { + comparer = EqualityComparer.Default; + } + if (source == null) + { + throw new ArgumentNullException("source"); + } + foreach (TSource item in source) + { + if (comparer.Equals(item, value)) + { + return true; + } + } + return false; + } + + public static bool AddRangeDistinct(this IList list, IEnumerable values) + { + return list.AddRangeDistinct(values, EqualityComparer.Default); + } + + public static bool AddRangeDistinct(this IList list, IEnumerable values, IEqualityComparer comparer) + { + bool result = true; + foreach (T value in values) + { + if (!list.AddDistinct(value, comparer)) + { + result = false; + } + } + return result; + } + + public static int IndexOf(this IEnumerable collection, Func predicate) + { + int num = 0; + foreach (T item in collection) + { + if (predicate(item)) + { + return num; + } + num++; + } + return -1; + } + + public static int IndexOf(this IEnumerable list, TSource value) where TSource : IEquatable + { + return list.IndexOf(value, EqualityComparer.Default); + } + + public static int IndexOf(this IEnumerable list, TSource value, IEqualityComparer comparer) + { + int num = 0; + foreach (TSource item in list) + { + if (comparer.Equals(item, value)) + { + return num; + } + num++; + } + return -1; + } + } +} diff --git a/Newtonsoft.Json.Utilities/CollectionWrapper.cs b/Newtonsoft.Json.Utilities/CollectionWrapper.cs new file mode 100644 index 00000000..af25e096 --- /dev/null +++ b/Newtonsoft.Json.Utilities/CollectionWrapper.cs @@ -0,0 +1,281 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; + +namespace Newtonsoft.Json.Utilities +{ + internal class CollectionWrapper : IEnumerable, IWrappedCollection, IList, ICollection, ICollection, IEnumerable + { + private readonly IList _list; + + private readonly ICollection _genericCollection; + + private object _syncRoot; + + bool IList.IsFixedSize + { + get + { + if (_genericCollection != null) + { + return _genericCollection.IsReadOnly; + } + return _list.IsFixedSize; + } + } + + object IList.this[int index] + { + get + { + if (_genericCollection != null) + { + throw new Exception("Wrapped ICollection does not support indexer."); + } + return _list[index]; + } + set + { + if (_genericCollection != null) + { + throw new Exception("Wrapped ICollection does not support indexer."); + } + VerifyValueType(value); + _list[index] = (T)value; + } + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + { + Interlocked.CompareExchange(ref _syncRoot, new object(), null); + } + return _syncRoot; + } + } + + public virtual int Count + { + get + { + if (_genericCollection != null) + { + return _genericCollection.Count; + } + return _list.Count; + } + } + + public virtual bool IsReadOnly + { + get + { + if (_genericCollection != null) + { + return _genericCollection.IsReadOnly; + } + return _list.IsReadOnly; + } + } + + public object UnderlyingCollection + { + get + { + if (_genericCollection != null) + { + return _genericCollection; + } + return _list; + } + } + + public CollectionWrapper(IList list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + if (list is ICollection) + { + _genericCollection = (ICollection)list; + } + else + { + _list = list; + } + } + + public CollectionWrapper(ICollection list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + _genericCollection = list; + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (_genericCollection != null) + { + return _genericCollection.GetEnumerator(); + } + return _list.GetEnumerator(); + } + + int IList.Add(object value) + { + VerifyValueType(value); + Add((T)value); + return Count - 1; + } + + bool IList.Contains(object value) + { + if (IsCompatibleObject(value)) + { + return Contains((T)value); + } + return false; + } + + int IList.IndexOf(object value) + { + if (_genericCollection != null) + { + throw new Exception("Wrapped ICollection does not support IndexOf."); + } + if (IsCompatibleObject(value)) + { + return _list.IndexOf((T)value); + } + return -1; + } + + void IList.RemoveAt(int index) + { + if (_genericCollection != null) + { + throw new Exception("Wrapped ICollection does not support RemoveAt."); + } + _list.RemoveAt(index); + } + + void IList.Insert(int index, object value) + { + if (_genericCollection != null) + { + throw new Exception("Wrapped ICollection does not support Insert."); + } + VerifyValueType(value); + _list.Insert(index, (T)value); + } + + void IList.Remove(object value) + { + if (IsCompatibleObject(value)) + { + Remove((T)value); + } + } + + void ICollection.CopyTo(Array array, int arrayIndex) + { + CopyTo((T[])array, arrayIndex); + } + + public virtual void Add(T item) + { + if (_genericCollection != null) + { + _genericCollection.Add(item); + } + else + { + _list.Add(item); + } + } + + public virtual void Clear() + { + if (_genericCollection != null) + { + _genericCollection.Clear(); + } + else + { + _list.Clear(); + } + } + + public virtual bool Contains(T item) + { + if (_genericCollection != null) + { + return _genericCollection.Contains(item); + } + return _list.Contains(item); + } + + public virtual void CopyTo(T[] array, int arrayIndex) + { + if (_genericCollection != null) + { + _genericCollection.CopyTo(array, arrayIndex); + } + else + { + _list.CopyTo(array, arrayIndex); + } + } + + public virtual bool Remove(T item) + { + if (_genericCollection != null) + { + return _genericCollection.Remove(item); + } + bool flag = _list.Contains(item); + if (flag) + { + _list.Remove(item); + } + return flag; + } + + public virtual IEnumerator GetEnumerator() + { + if (_genericCollection != null) + { + return _genericCollection.GetEnumerator(); + } + return _list.Cast().GetEnumerator(); + } + + private static void VerifyValueType(object value) + { + if (!IsCompatibleObject(value)) + { + throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value"); + } + } + + private static bool IsCompatibleObject(object value) + { + if (!(value is T) && (value != null || (typeof(T).IsValueType && !ReflectionUtils.IsNullableType(typeof(T))))) + { + return false; + } + return true; + } + } +} diff --git a/Newtonsoft.Json.Utilities/ConvertUtils.cs b/Newtonsoft.Json.Utilities/ConvertUtils.cs new file mode 100644 index 00000000..fc2ccd97 --- /dev/null +++ b/Newtonsoft.Json.Utilities/ConvertUtils.cs @@ -0,0 +1,318 @@ +using Newtonsoft.Json.Serialization; +using System; +using System.ComponentModel; +using System.Globalization; +using System.Reflection; + +namespace Newtonsoft.Json.Utilities +{ + internal static class ConvertUtils + { + internal struct TypeConvertKey : IEquatable + { + private readonly Type _initialType; + + private readonly Type _targetType; + + public Type InitialType => _initialType; + + public Type TargetType => _targetType; + + public TypeConvertKey(Type initialType, Type targetType) + { + _initialType = initialType; + _targetType = targetType; + } + + public override int GetHashCode() + { + return _initialType.GetHashCode() ^ _targetType.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (!(obj is TypeConvertKey)) + { + return false; + } + return Equals((TypeConvertKey)obj); + } + + public bool Equals(TypeConvertKey other) + { + return _initialType == other._initialType && _targetType == other._targetType; + } + } + + private static readonly ThreadSafeStore> CastConverters = new ThreadSafeStore>(CreateCastConverter); + + private static Func CreateCastConverter(TypeConvertKey t) + { + MethodInfo method = t.TargetType.GetMethod("op_Implicit", new Type[1] + { + t.InitialType + }); + if (method == null) + { + method = t.TargetType.GetMethod("op_Explicit", new Type[1] + { + t.InitialType + }); + } + if (method == null) + { + return null; + } + MethodCall call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(method); + return (object o) => call(null, o); + } + + public static bool CanConvertType(Type initialType, Type targetType, bool allowTypeNameToString) + { + ValidationUtils.ArgumentNotNull(initialType, "initialType"); + ValidationUtils.ArgumentNotNull(targetType, "targetType"); + if (ReflectionUtils.IsNullableType(targetType)) + { + targetType = Nullable.GetUnderlyingType(targetType); + } + if (targetType == initialType) + { + return true; + } + if (typeof(IConvertible).IsAssignableFrom(initialType) && typeof(IConvertible).IsAssignableFrom(targetType)) + { + return true; + } + if (initialType == typeof(DateTime) && targetType == typeof(DateTimeOffset)) + { + return true; + } + if (initialType == typeof(Guid) && (targetType == typeof(Guid) || targetType == typeof(string))) + { + return true; + } + if (initialType == typeof(Type) && targetType == typeof(string)) + { + return true; + } + TypeConverter converter = GetConverter(initialType); + if (converter != null && !IsComponentConverter(converter) && converter.CanConvertTo(targetType) && (allowTypeNameToString || converter.GetType() != typeof(TypeConverter))) + { + return true; + } + TypeConverter converter2 = GetConverter(targetType); + if (converter2 != null && !IsComponentConverter(converter2) && converter2.CanConvertFrom(initialType)) + { + return true; + } + if (initialType == typeof(DBNull) && ReflectionUtils.IsNullable(targetType)) + { + return true; + } + return false; + } + + private static bool IsComponentConverter(TypeConverter converter) + { + return converter is ComponentConverter; + } + + public static T Convert(object initialValue) + { + return Convert(initialValue, CultureInfo.CurrentCulture); + } + + public static T Convert(object initialValue, CultureInfo culture) + { + return (T)Convert(initialValue, culture, typeof(T)); + } + + public static object Convert(object initialValue, CultureInfo culture, Type targetType) + { + if (initialValue == null) + { + throw new ArgumentNullException("initialValue"); + } + if (ReflectionUtils.IsNullableType(targetType)) + { + targetType = Nullable.GetUnderlyingType(targetType); + } + Type type = initialValue.GetType(); + if (targetType == type) + { + return initialValue; + } + if (initialValue is string && typeof(Type).IsAssignableFrom(targetType)) + { + return Type.GetType((string)initialValue, throwOnError: true); + } + if (targetType.IsInterface || targetType.IsGenericTypeDefinition || targetType.IsAbstract) + { + throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType"); + } + if (initialValue is IConvertible && typeof(IConvertible).IsAssignableFrom(targetType)) + { + if (targetType.IsEnum) + { + if (initialValue is string) + { + return Enum.Parse(targetType, initialValue.ToString(), ignoreCase: true); + } + if (IsInteger(initialValue)) + { + return Enum.ToObject(targetType, initialValue); + } + } + return System.Convert.ChangeType(initialValue, targetType, culture); + } + if (initialValue is DateTime && targetType == typeof(DateTimeOffset)) + { + return new DateTimeOffset((DateTime)initialValue); + } + if (initialValue is string) + { + if (targetType == typeof(Guid)) + { + return new Guid((string)initialValue); + } + if (targetType == typeof(Uri)) + { + return new Uri((string)initialValue); + } + if (targetType == typeof(TimeSpan)) + { + return TimeSpan.Parse((string)initialValue); + } + } + TypeConverter converter = GetConverter(type); + if (converter != null && converter.CanConvertTo(targetType)) + { + return converter.ConvertTo(null, culture, initialValue, targetType); + } + TypeConverter converter2 = GetConverter(targetType); + if (converter2 != null && converter2.CanConvertFrom(type)) + { + return converter2.ConvertFrom(null, culture, initialValue); + } + if (initialValue == DBNull.Value) + { + if (ReflectionUtils.IsNullable(targetType)) + { + return EnsureTypeAssignable(null, type, targetType); + } + throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, type, targetType)); + } + throw new Exception("Can not convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, type, targetType)); + } + + public static bool TryConvert(object initialValue, out T convertedValue) + { + return TryConvert(initialValue, CultureInfo.CurrentCulture, out convertedValue); + } + + public static bool TryConvert(object initialValue, CultureInfo culture, out T convertedValue) + { + return MiscellaneousUtils.TryAction(delegate + { + TryConvert(initialValue, CultureInfo.CurrentCulture, typeof(T), out object convertedValue2); + return (T)convertedValue2; + }, out convertedValue); + } + + public static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object convertedValue) + { + return MiscellaneousUtils.TryAction(() => Convert(initialValue, culture, targetType), out convertedValue); + } + + public static T ConvertOrCast(object initialValue) + { + return ConvertOrCast(initialValue, CultureInfo.CurrentCulture); + } + + public static T ConvertOrCast(object initialValue, CultureInfo culture) + { + return (T)ConvertOrCast(initialValue, culture, typeof(T)); + } + + public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType) + { + if (targetType == typeof(object)) + { + return initialValue; + } + if (initialValue == null && ReflectionUtils.IsNullable(targetType)) + { + return null; + } + if (TryConvert(initialValue, culture, targetType, out object convertedValue)) + { + return convertedValue; + } + return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue), targetType); + } + + public static bool TryConvertOrCast(object initialValue, out T convertedValue) + { + return TryConvertOrCast(initialValue, CultureInfo.CurrentCulture, out convertedValue); + } + + public static bool TryConvertOrCast(object initialValue, CultureInfo culture, out T convertedValue) + { + return MiscellaneousUtils.TryAction(delegate + { + TryConvertOrCast(initialValue, CultureInfo.CurrentCulture, typeof(T), out object convertedValue2); + return (T)convertedValue2; + }, out convertedValue); + } + + public static bool TryConvertOrCast(object initialValue, CultureInfo culture, Type targetType, out object convertedValue) + { + return MiscellaneousUtils.TryAction(() => ConvertOrCast(initialValue, culture, targetType), out convertedValue); + } + + private static object EnsureTypeAssignable(object value, Type initialType, Type targetType) + { + Type type = value?.GetType(); + if (value != null) + { + if (targetType.IsAssignableFrom(type)) + { + return value; + } + Func func = CastConverters.Get(new TypeConvertKey(type, targetType)); + if (func != null) + { + return func(value); + } + } + else if (ReflectionUtils.IsNullable(targetType)) + { + return null; + } + throw new Exception("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, (initialType == null) ? "{null}" : initialType.ToString(), targetType)); + } + + internal static TypeConverter GetConverter(Type t) + { + return JsonTypeReflector.GetTypeConverter(t); + } + + public static bool IsInteger(object value) + { + switch (System.Convert.GetTypeCode(value)) + { + case TypeCode.SByte: + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + return true; + default: + return false; + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/Creator.cs b/Newtonsoft.Json.Utilities/Creator.cs new file mode 100644 index 00000000..83c9e371 --- /dev/null +++ b/Newtonsoft.Json.Utilities/Creator.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.Utilities +{ + internal delegate T Creator(); +} diff --git a/Newtonsoft.Json.Utilities/D1.cs b/Newtonsoft.Json.Utilities/D1.cs new file mode 100644 index 00000000..12942f65 --- /dev/null +++ b/Newtonsoft.Json.Utilities/D1.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.Utilities +{ + public delegate object D1(); +} diff --git a/Newtonsoft.Json.Utilities/DateTimeUtils.cs b/Newtonsoft.Json.Utilities/DateTimeUtils.cs new file mode 100644 index 00000000..2e500d85 --- /dev/null +++ b/Newtonsoft.Json.Utilities/DateTimeUtils.cs @@ -0,0 +1,30 @@ +using System; +using System.Globalization; +using System.Xml; + +namespace Newtonsoft.Json.Utilities +{ + internal static class DateTimeUtils + { + public static string GetLocalOffset(this DateTime d) + { + TimeSpan utcOffset = TimeZoneInfo.Local.GetUtcOffset(d); + return utcOffset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture) + ":" + utcOffset.Minutes.ToString("00;00", CultureInfo.InvariantCulture); + } + + public static XmlDateTimeSerializationMode ToSerializationMode(DateTimeKind kind) + { + switch (kind) + { + case DateTimeKind.Local: + return XmlDateTimeSerializationMode.Local; + case DateTimeKind.Unspecified: + return XmlDateTimeSerializationMode.Unspecified; + case DateTimeKind.Utc: + return XmlDateTimeSerializationMode.Utc; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("kind", kind, "Unexpected DateTimeKind value."); + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/DictionaryWrapper.cs b/Newtonsoft.Json.Utilities/DictionaryWrapper.cs new file mode 100644 index 00000000..ed4fa84d --- /dev/null +++ b/Newtonsoft.Json.Utilities/DictionaryWrapper.cs @@ -0,0 +1,419 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Newtonsoft.Json.Utilities +{ + internal class DictionaryWrapper : IEnumerable, IWrappedDictionary, ICollection, IDictionary, IDictionary, ICollection>, IEnumerable> + { + private struct DictionaryEnumerator : IEnumerator, IDictionaryEnumerator + { + private readonly IEnumerator> _e; + + public DictionaryEntry Entry => (DictionaryEntry)Current; + + public object Key => Entry.Key; + + public object Value => Entry.Value; + + public object Current => new DictionaryEntry(_e.Current.Key, _e.Current.Value); + + public DictionaryEnumerator(IEnumerator> e) + { + ValidationUtils.ArgumentNotNull(e, "e"); + _e = e; + } + + public bool MoveNext() + { + return _e.MoveNext(); + } + + public void Reset() + { + _e.Reset(); + } + } + + private readonly IDictionary _dictionary; + + private readonly IDictionary _genericDictionary; + + private object _syncRoot; + + bool IDictionary.IsFixedSize + { + get + { + if (_genericDictionary != null) + { + return false; + } + return _dictionary.IsFixedSize; + } + } + + ICollection IDictionary.Keys + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary.Keys.ToList(); + } + return _dictionary.Keys; + } + } + + ICollection IDictionary.Values + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary.Values.ToList(); + } + return _dictionary.Values; + } + } + + object IDictionary.this[object key] + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary[(TKey)key]; + } + return _dictionary[key]; + } + set + { + if (_genericDictionary != null) + { + _genericDictionary[(TKey)key] = (TValue)value; + } + else + { + _dictionary[key] = value; + } + } + } + + bool ICollection.IsSynchronized + { + get + { + if (_genericDictionary != null) + { + return false; + } + return _dictionary.IsSynchronized; + } + } + + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + { + Interlocked.CompareExchange(ref _syncRoot, new object(), null); + } + return _syncRoot; + } + } + + public ICollection Keys + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary.Keys; + } + return _dictionary.Keys.Cast().ToList(); + } + } + + public ICollection Values + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary.Values; + } + return _dictionary.Values.Cast().ToList(); + } + } + + public TValue this[TKey key] + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary[key]; + } + return (TValue)_dictionary[key]; + } + set + { + if (_genericDictionary != null) + { + _genericDictionary[key] = value; + } + else + { + _dictionary[key] = value; + } + } + } + + public int Count + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary.Count; + } + return _dictionary.Count; + } + } + + public bool IsReadOnly + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary.IsReadOnly; + } + return _dictionary.IsReadOnly; + } + } + + public object UnderlyingDictionary + { + get + { + if (_genericDictionary != null) + { + return _genericDictionary; + } + return _dictionary; + } + } + + public DictionaryWrapper(IDictionary dictionary) + { + ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); + _dictionary = dictionary; + } + + public DictionaryWrapper(IDictionary dictionary) + { + ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); + _genericDictionary = dictionary; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + void IDictionary.Add(object key, object value) + { + if (_genericDictionary != null) + { + _genericDictionary.Add((TKey)key, (TValue)value); + } + else + { + _dictionary.Add(key, value); + } + } + + bool IDictionary.Contains(object key) + { + if (_genericDictionary != null) + { + return _genericDictionary.ContainsKey((TKey)key); + } + return _dictionary.Contains(key); + } + + IDictionaryEnumerator IDictionary.GetEnumerator() + { + if (_genericDictionary != null) + { + return new DictionaryEnumerator(_genericDictionary.GetEnumerator()); + } + return _dictionary.GetEnumerator(); + } + + void ICollection.CopyTo(Array array, int index) + { + if (_genericDictionary != null) + { + _genericDictionary.CopyTo((KeyValuePair[])array, index); + } + else + { + _dictionary.CopyTo(array, index); + } + } + + public void Add(TKey key, TValue value) + { + if (_genericDictionary != null) + { + _genericDictionary.Add(key, value); + } + else + { + _dictionary.Add(key, value); + } + } + + public bool ContainsKey(TKey key) + { + if (_genericDictionary != null) + { + return _genericDictionary.ContainsKey(key); + } + return _dictionary.Contains(key); + } + + public bool Remove(TKey key) + { + if (_genericDictionary != null) + { + return _genericDictionary.Remove(key); + } + if (_dictionary.Contains(key)) + { + _dictionary.Remove(key); + return true; + } + return false; + } + + public bool TryGetValue(TKey key, out TValue value) + { + if (_genericDictionary != null) + { + return _genericDictionary.TryGetValue(key, out value); + } + if (!_dictionary.Contains(key)) + { + value = default(TValue); + return false; + } + value = (TValue)_dictionary[key]; + return true; + } + + public void Add(KeyValuePair item) + { + if (_genericDictionary != null) + { + _genericDictionary.Add(item); + } + else + { + ((IList)_dictionary).Add(item); + } + } + + public void Clear() + { + if (_genericDictionary != null) + { + _genericDictionary.Clear(); + } + else + { + _dictionary.Clear(); + } + } + + public bool Contains(KeyValuePair item) + { + if (_genericDictionary != null) + { + return _genericDictionary.Contains(item); + } + return ((IList)_dictionary).Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (_genericDictionary != null) + { + _genericDictionary.CopyTo(array, arrayIndex); + } + else + { + IDictionaryEnumerator enumerator = _dictionary.GetEnumerator(); + try + { + while (enumerator.MoveNext()) + { + DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current; + array[arrayIndex++] = new KeyValuePair((TKey)dictionaryEntry.Key, (TValue)dictionaryEntry.Value); + } + } + finally + { + (enumerator as IDisposable)?.Dispose(); + } + } + } + + public bool Remove(KeyValuePair item) + { + if (_genericDictionary != null) + { + return _genericDictionary.Remove(item); + } + if (_dictionary.Contains(item.Key)) + { + object objA = _dictionary[item.Key]; + if (object.Equals(objA, item.Value)) + { + _dictionary.Remove(item.Key); + return true; + } + return false; + } + return true; + } + + public IEnumerator> GetEnumerator() + { + if (_genericDictionary != null) + { + return _genericDictionary.GetEnumerator(); + } + return (from DictionaryEntry de in _dictionary + select new KeyValuePair((TKey)de.Key, (TValue)de.Value)).GetEnumerator(); + } + + public void Remove(object key) + { + if (_genericDictionary != null) + { + _genericDictionary.Remove((TKey)key); + } + else + { + _dictionary.Remove(key); + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/DynamicReflectionDelegateFactory.cs b/Newtonsoft.Json.Utilities/DynamicReflectionDelegateFactory.cs new file mode 100644 index 00000000..691b1fa8 --- /dev/null +++ b/Newtonsoft.Json.Utilities/DynamicReflectionDelegateFactory.cs @@ -0,0 +1,198 @@ +using System; +using System.Globalization; +using System.Reflection; +using System.Reflection.Emit; + +namespace Newtonsoft.Json.Utilities +{ + internal class DynamicReflectionDelegateFactory : ReflectionDelegateFactory + { + public static DynamicReflectionDelegateFactory Instance = new DynamicReflectionDelegateFactory(); + + private static DynamicMethod CreateDynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner) + { + return owner.IsInterface ? new DynamicMethod(name, returnType, parameterTypes, owner.Module, skipVisibility: true) : new DynamicMethod(name, returnType, parameterTypes, owner, skipVisibility: true); + } + + public override MethodCall CreateMethodCall(MethodBase method) + { + DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new Type[2] + { + typeof(object), + typeof(object[]) + }, method.DeclaringType); + ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); + GenerateCreateMethodCallIL(method, iLGenerator); + return (MethodCall)dynamicMethod.CreateDelegate(typeof(MethodCall)); + } + + private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator) + { + ParameterInfo[] parameters = method.GetParameters(); + Label label = generator.DefineLabel(); + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Ldlen); + generator.Emit(OpCodes.Ldc_I4, parameters.Length); + generator.Emit(OpCodes.Beq, label); + generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(Type.EmptyTypes)); + generator.Emit(OpCodes.Throw); + generator.MarkLabel(label); + if (!method.IsConstructor && !method.IsStatic) + { + generator.PushInstance(method.DeclaringType); + } + for (int i = 0; i < parameters.Length; i++) + { + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Ldelem_Ref); + generator.UnboxIfNeeded(parameters[i].ParameterType); + } + if (method.IsConstructor) + { + generator.Emit(OpCodes.Newobj, (ConstructorInfo)method); + } + else if (method.IsFinal || !method.IsVirtual) + { + generator.CallMethod((MethodInfo)method); + } + Type type = (!method.IsConstructor) ? ((MethodInfo)method).ReturnType : method.DeclaringType; + if (type != typeof(void)) + { + generator.BoxIfNeeded(type); + } + else + { + generator.Emit(OpCodes.Ldnull); + } + generator.Return(); + } + + public override Func CreateDefaultConstructor(Type type) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Create" + type.FullName, typeof(T), Type.EmptyTypes, type); + dynamicMethod.InitLocals = true; + ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); + GenerateCreateDefaultConstructorIL(type, iLGenerator); + return (Func)dynamicMethod.CreateDelegate(typeof(Func)); + } + + private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator) + { + if (type.IsValueType) + { + generator.DeclareLocal(type); + generator.Emit(OpCodes.Ldloc_0); + generator.Emit(OpCodes.Box, type); + } + else + { + ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); + if (constructor == null) + { + throw new Exception("Could not get constructor for {0}.".FormatWith(CultureInfo.InvariantCulture, type)); + } + generator.Emit(OpCodes.Newobj, constructor); + } + generator.Return(); + } + + public override Func CreateGet(PropertyInfo propertyInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(T), new Type[1] + { + typeof(object) + }, propertyInfo.DeclaringType); + ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); + GenerateCreateGetPropertyIL(propertyInfo, iLGenerator); + return (Func)dynamicMethod.CreateDelegate(typeof(Func)); + } + + private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator) + { + MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true); + if (getMethod == null) + { + throw new Exception("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture, propertyInfo.Name)); + } + if (!getMethod.IsStatic) + { + generator.PushInstance(propertyInfo.DeclaringType); + } + generator.CallMethod(getMethod); + generator.BoxIfNeeded(propertyInfo.PropertyType); + generator.Return(); + } + + public override Func CreateGet(FieldInfo fieldInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new Type[1] + { + typeof(object) + }, fieldInfo.DeclaringType); + ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); + GenerateCreateGetFieldIL(fieldInfo, iLGenerator); + return (Func)dynamicMethod.CreateDelegate(typeof(Func)); + } + + private void GenerateCreateGetFieldIL(FieldInfo fieldInfo, ILGenerator generator) + { + if (!fieldInfo.IsStatic) + { + generator.PushInstance(fieldInfo.DeclaringType); + } + generator.Emit(OpCodes.Ldfld, fieldInfo); + generator.BoxIfNeeded(fieldInfo.FieldType); + generator.Return(); + } + + public override Action CreateSet(FieldInfo fieldInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new Type[2] + { + typeof(T), + typeof(object) + }, fieldInfo.DeclaringType); + ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); + GenerateCreateSetFieldIL(fieldInfo, iLGenerator); + return (Action)dynamicMethod.CreateDelegate(typeof(Action)); + } + + internal static void GenerateCreateSetFieldIL(FieldInfo fieldInfo, ILGenerator generator) + { + if (!fieldInfo.IsStatic) + { + generator.PushInstance(fieldInfo.DeclaringType); + } + generator.Emit(OpCodes.Ldarg_1); + generator.UnboxIfNeeded(fieldInfo.FieldType); + generator.Emit(OpCodes.Stfld, fieldInfo); + generator.Return(); + } + + public override Action CreateSet(PropertyInfo propertyInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new Type[2] + { + typeof(T), + typeof(object) + }, propertyInfo.DeclaringType); + ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); + GenerateCreateSetPropertyIL(propertyInfo, iLGenerator); + return (Action)dynamicMethod.CreateDelegate(typeof(Action)); + } + + internal static void GenerateCreateSetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator) + { + MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true); + if (!setMethod.IsStatic) + { + generator.PushInstance(propertyInfo.DeclaringType); + } + generator.Emit(OpCodes.Ldarg_1); + generator.UnboxIfNeeded(propertyInfo.PropertyType); + generator.CallMethod(setMethod); + generator.Return(); + } + } +} diff --git a/Newtonsoft.Json.Utilities/DynamicWrapper.cs b/Newtonsoft.Json.Utilities/DynamicWrapper.cs new file mode 100644 index 00000000..b78b7d79 --- /dev/null +++ b/Newtonsoft.Json.Utilities/DynamicWrapper.cs @@ -0,0 +1,115 @@ +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Resources; + +namespace Newtonsoft.Json.Utilities +{ + internal static class DynamicWrapper + { + private static readonly object _lock = new object(); + + private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary(); + + private static ModuleBuilder _moduleBuilder; + + private static ModuleBuilder ModuleBuilder + { + get + { + Init(); + return _moduleBuilder; + } + } + + private static void Init() + { + if (_moduleBuilder == null) + { + lock (_lock) + { + if (_moduleBuilder == null) + { + AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic"); + assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey()); + AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + _moduleBuilder = assemblyBuilder.DefineDynamicModule("Newtonsoft.Json.DynamicModule", emitSymbolInfo: false); + } + } + } + } + + private static byte[] GetStrongKey() + { + string text = "Newtonsoft.Json.Dynamic.snk"; + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text)) + { + if (stream == null) + { + throw new MissingManifestResourceException("Should have " + text + " as an embedded resource."); + } + int num = (int)stream.Length; + byte[] array = new byte[num]; + stream.Read(array, 0, num); + return array; + IL_004f: + byte[] result; + return result; + } + } + + public static Type GetWrapper(Type interfaceType, Type realObjectType) + { + Type type = _wrapperDictionary.GetType(interfaceType, realObjectType); + if (type == null) + { + lock (_lock) + { + type = _wrapperDictionary.GetType(interfaceType, realObjectType); + if (type != null) + { + return type; + } + type = GenerateWrapperType(interfaceType, realObjectType); + _wrapperDictionary.SetType(interfaceType, realObjectType, type); + return type; + } + } + return type; + } + + public static object GetUnderlyingObject(object wrapper) + { + DynamicWrapperBase dynamicWrapperBase = wrapper as DynamicWrapperBase; + if (dynamicWrapperBase == null) + { + throw new ArgumentException("Object is not a wrapper.", "wrapper"); + } + return dynamicWrapperBase.UnderlyingObject; + } + + private static Type GenerateWrapperType(Type interfaceType, Type underlyingType) + { + TypeBuilder typeBuilder = ModuleBuilder.DefineType("{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name), TypeAttributes.Sealed, typeof(DynamicWrapperBase), new Type[1] + { + interfaceType + }); + WrapperMethodBuilder wrapperMethodBuilder = new WrapperMethodBuilder(underlyingType, typeBuilder); + foreach (MethodInfo item in interfaceType.AllMethods()) + { + wrapperMethodBuilder.Generate(item); + } + return typeBuilder.CreateType(); + } + + public static T CreateWrapper(object realObject) where T : class + { + Type wrapper = GetWrapper(typeof(T), realObject.GetType()); + DynamicWrapperBase dynamicWrapperBase = (DynamicWrapperBase)Activator.CreateInstance(wrapper); + dynamicWrapperBase.UnderlyingObject = realObject; + return dynamicWrapperBase as T; + } + } +} diff --git a/Newtonsoft.Json.Utilities/DynamicWrapperBase.cs b/Newtonsoft.Json.Utilities/DynamicWrapperBase.cs new file mode 100644 index 00000000..bd67d6a0 --- /dev/null +++ b/Newtonsoft.Json.Utilities/DynamicWrapperBase.cs @@ -0,0 +1,7 @@ +namespace Newtonsoft.Json.Utilities +{ + internal class DynamicWrapperBase + { + protected internal object UnderlyingObject; + } +} diff --git a/Newtonsoft.Json.Utilities/EnumUtils.cs b/Newtonsoft.Json.Utilities/EnumUtils.cs new file mode 100644 index 00000000..7cb543ef --- /dev/null +++ b/Newtonsoft.Json.Utilities/EnumUtils.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; + +namespace Newtonsoft.Json.Utilities +{ + internal static class EnumUtils + { + public static T Parse(string enumMemberName) where T : struct + { + return Parse(enumMemberName, ignoreCase: false); + } + + public static T Parse(string enumMemberName, bool ignoreCase) where T : struct + { + ValidationUtils.ArgumentTypeIsEnum(typeof(T), "T"); + return (T)Enum.Parse(typeof(T), enumMemberName, ignoreCase); + } + + public static bool TryParse(string enumMemberName, bool ignoreCase, out T value) where T : struct + { + ValidationUtils.ArgumentTypeIsEnum(typeof(T), "T"); + return MiscellaneousUtils.TryAction(() => Parse(enumMemberName, ignoreCase), out value); + } + + public static IList GetFlagsValues(T value) where T : struct + { + Type typeFromHandle = typeof(T); + if (!typeFromHandle.IsDefined(typeof(FlagsAttribute), inherit: false)) + { + throw new Exception("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, typeFromHandle)); + } + Type underlyingType = Enum.GetUnderlyingType(value.GetType()); + ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture); + EnumValues namesAndValues = GetNamesAndValues(); + IList list = new List(); + foreach (EnumValue item in namesAndValues) + { + if ((num & item.Value) == item.Value && item.Value != 0L) + { + list.Add((T)Convert.ChangeType(item.Value, underlyingType, CultureInfo.CurrentCulture)); + } + } + if (list.Count == 0 && namesAndValues.SingleOrDefault((EnumValue v) => v.Value == 0) != null) + { + list.Add(default(T)); + } + return list; + } + + public static EnumValues GetNamesAndValues() where T : struct + { + return GetNamesAndValues(typeof(T)); + } + + public static EnumValues GetNamesAndValues() where TEnum : struct where TUnderlyingType : struct + { + return GetNamesAndValues(typeof(TEnum)); + } + + public static EnumValues GetNamesAndValues(Type enumType) where TUnderlyingType : struct + { + if (enumType == null) + { + throw new ArgumentNullException("enumType"); + } + ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType"); + IList values = GetValues(enumType); + IList names = GetNames(enumType); + EnumValues enumValues = new EnumValues(); + for (int i = 0; i < values.Count; i++) + { + try + { + enumValues.Add(new EnumValue(names[i], (TUnderlyingType)Convert.ChangeType(values[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture))); + } + catch (OverflowException innerException) + { + throw new Exception(string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}", Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(values[i], CultureInfo.InvariantCulture)), innerException); + IL_00bc:; + } + } + return enumValues; + } + + public static IList GetValues() + { + return GetValues(typeof(T)).Cast().ToList(); + } + + public static IList GetValues(Type enumType) + { + if (!enumType.IsEnum) + { + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); + } + List list = new List(); + IEnumerable enumerable = from field in enumType.GetFields() + where field.IsLiteral + select field; + foreach (FieldInfo item in enumerable) + { + object value = item.GetValue(enumType); + list.Add(value); + } + return list; + } + + public static IList GetNames() + { + return GetNames(typeof(T)); + } + + public static IList GetNames(Type enumType) + { + if (!enumType.IsEnum) + { + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); + } + List list = new List(); + IEnumerable enumerable = from field in enumType.GetFields() + where field.IsLiteral + select field; + foreach (FieldInfo item in enumerable) + { + list.Add(item.Name); + } + return list; + } + + public static TEnumType GetMaximumValue(Type enumType) where TEnumType : IConvertible, IComparable + { + if (enumType == null) + { + throw new ArgumentNullException("enumType"); + } + Type underlyingType = Enum.GetUnderlyingType(enumType); + if (!typeof(TEnumType).IsAssignableFrom(underlyingType)) + { + throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "TEnumType is not assignable from the enum's underlying type of {0}.", underlyingType.Name)); + } + ulong num = 0uL; + IList values = GetValues(enumType); + if (enumType.IsDefined(typeof(FlagsAttribute), inherit: false)) + { + foreach (TEnumType item in values) + { + num |= item.ToUInt64(CultureInfo.InvariantCulture); + } + } + else + { + foreach (TEnumType item2 in values) + { + ulong num2 = item2.ToUInt64(CultureInfo.InvariantCulture); + if (num.CompareTo(num2) == -1) + { + num = num2; + } + } + } + return (TEnumType)Convert.ChangeType(num, typeof(TEnumType), CultureInfo.InvariantCulture); + } + } +} diff --git a/Newtonsoft.Json.Utilities/EnumValue.cs b/Newtonsoft.Json.Utilities/EnumValue.cs new file mode 100644 index 00000000..0326de27 --- /dev/null +++ b/Newtonsoft.Json.Utilities/EnumValue.cs @@ -0,0 +1,19 @@ +namespace Newtonsoft.Json.Utilities +{ + internal class EnumValue where T : struct + { + private string _name; + + private T _value; + + public string Name => _name; + + public T Value => _value; + + public EnumValue(string name, T value) + { + _name = name; + _value = value; + } + } +} diff --git a/Newtonsoft.Json.Utilities/EnumValues.cs b/Newtonsoft.Json.Utilities/EnumValues.cs new file mode 100644 index 00000000..3dde0323 --- /dev/null +++ b/Newtonsoft.Json.Utilities/EnumValues.cs @@ -0,0 +1,12 @@ +using System.Collections.ObjectModel; + +namespace Newtonsoft.Json.Utilities +{ + internal class EnumValues : KeyedCollection> where T : struct + { + protected override string GetKeyForItem(EnumValue item) + { + return item.Name; + } + } +} diff --git a/Newtonsoft.Json.Utilities/ILGeneratorExtensions.cs b/Newtonsoft.Json.Utilities/ILGeneratorExtensions.cs new file mode 100644 index 00000000..dc02f8f0 --- /dev/null +++ b/Newtonsoft.Json.Utilities/ILGeneratorExtensions.cs @@ -0,0 +1,63 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace Newtonsoft.Json.Utilities +{ + internal static class ILGeneratorExtensions + { + public static void PushInstance(this ILGenerator generator, Type type) + { + generator.Emit(OpCodes.Ldarg_0); + if (type.IsValueType) + { + generator.Emit(OpCodes.Unbox, type); + } + else + { + generator.Emit(OpCodes.Castclass, type); + } + } + + public static void BoxIfNeeded(this ILGenerator generator, Type type) + { + if (type.IsValueType) + { + generator.Emit(OpCodes.Box, type); + } + else + { + generator.Emit(OpCodes.Castclass, type); + } + } + + public static void UnboxIfNeeded(this ILGenerator generator, Type type) + { + if (type.IsValueType) + { + generator.Emit(OpCodes.Unbox_Any, type); + } + else + { + generator.Emit(OpCodes.Castclass, type); + } + } + + public static void CallMethod(this ILGenerator generator, MethodInfo methodInfo) + { + if (methodInfo.IsFinal || !methodInfo.IsVirtual) + { + generator.Emit(OpCodes.Call, methodInfo); + } + else + { + generator.Emit(OpCodes.Callvirt, methodInfo); + } + } + + public static void Return(this ILGenerator generator) + { + generator.Emit(OpCodes.Ret); + } + } +} diff --git a/Newtonsoft.Json.Utilities/IWrappedCollection.cs b/Newtonsoft.Json.Utilities/IWrappedCollection.cs new file mode 100644 index 00000000..61779e72 --- /dev/null +++ b/Newtonsoft.Json.Utilities/IWrappedCollection.cs @@ -0,0 +1,12 @@ +using System.Collections; + +namespace Newtonsoft.Json.Utilities +{ + internal interface IWrappedCollection : IEnumerable, IList, ICollection + { + object UnderlyingCollection + { + get; + } + } +} diff --git a/Newtonsoft.Json.Utilities/IWrappedDictionary.cs b/Newtonsoft.Json.Utilities/IWrappedDictionary.cs new file mode 100644 index 00000000..696be90d --- /dev/null +++ b/Newtonsoft.Json.Utilities/IWrappedDictionary.cs @@ -0,0 +1,12 @@ +using System.Collections; + +namespace Newtonsoft.Json.Utilities +{ + internal interface IWrappedDictionary : IEnumerable, ICollection, IDictionary + { + object UnderlyingDictionary + { + get; + } + } +} diff --git a/Newtonsoft.Json.Utilities/IWrappedList.cs b/Newtonsoft.Json.Utilities/IWrappedList.cs new file mode 100644 index 00000000..74c588f3 --- /dev/null +++ b/Newtonsoft.Json.Utilities/IWrappedList.cs @@ -0,0 +1,12 @@ +using System.Collections; + +namespace Newtonsoft.Json.Utilities +{ + internal interface IWrappedList : IEnumerable, IList, ICollection + { + object UnderlyingList + { + get; + } + } +} diff --git a/Newtonsoft.Json.Utilities/JavaScriptUtils.cs b/Newtonsoft.Json.Utilities/JavaScriptUtils.cs new file mode 100644 index 00000000..52dfa56d --- /dev/null +++ b/Newtonsoft.Json.Utilities/JavaScriptUtils.cs @@ -0,0 +1,116 @@ +using System.IO; + +namespace Newtonsoft.Json.Utilities +{ + internal static class JavaScriptUtils + { + public static void WriteEscapedJavaScriptString(TextWriter writer, string value, char delimiter, bool appendDelimiters) + { + if (appendDelimiters) + { + writer.Write(delimiter); + } + if (value != null) + { + int num = 0; + int num2 = 0; + char[] array = null; + for (int i = 0; i < value.Length; i++) + { + char c = value[i]; + string text; + switch (c) + { + case '\t': + text = "\\t"; + break; + case '\n': + text = "\\n"; + break; + case '\r': + text = "\\r"; + break; + case '\f': + text = "\\f"; + break; + case '\b': + text = "\\b"; + break; + case '\\': + text = "\\\\"; + break; + case '\u0085': + text = "\\u0085"; + break; + case '\u2028': + text = "\\u2028"; + break; + case '\u2029': + text = "\\u2029"; + break; + case '\'': + text = ((delimiter != '\'') ? null : "\\'"); + break; + case '"': + text = ((delimiter != '"') ? null : "\\\""); + break; + default: + text = ((c > '\u001f') ? null : StringUtils.ToCharAsUnicode(c)); + break; + } + if (text != null) + { + if (array == null) + { + array = value.ToCharArray(); + } + if (num2 > 0) + { + writer.Write(array, num, num2); + num2 = 0; + } + writer.Write(text); + num = i + 1; + } + else + { + num2++; + } + } + if (num2 > 0) + { + if (num == 0) + { + writer.Write(value); + } + else + { + writer.Write(array, num, num2); + } + } + } + if (appendDelimiters) + { + writer.Write(delimiter); + } + } + + public static string ToEscapedJavaScriptString(string value) + { + return ToEscapedJavaScriptString(value, '"', appendDelimiters: true); + } + + public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters) + { + int? length = StringUtils.GetLength(value); + using (StringWriter stringWriter = StringUtils.CreateStringWriter((!length.HasValue) ? 16 : length.Value)) + { + WriteEscapedJavaScriptString(stringWriter, value, delimiter, appendDelimiters); + return stringWriter.ToString(); + IL_003c: + string result; + return result; + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/LateBoundReflectionDelegateFactory.cs b/Newtonsoft.Json.Utilities/LateBoundReflectionDelegateFactory.cs new file mode 100644 index 00000000..d39a67b8 --- /dev/null +++ b/Newtonsoft.Json.Utilities/LateBoundReflectionDelegateFactory.cs @@ -0,0 +1,64 @@ +using System; +using System.Reflection; + +namespace Newtonsoft.Json.Utilities +{ + internal class LateBoundReflectionDelegateFactory : ReflectionDelegateFactory + { + private static readonly LateBoundReflectionDelegateFactory _instance = new LateBoundReflectionDelegateFactory(); + + internal static ReflectionDelegateFactory Instance => _instance; + + public override MethodCall CreateMethodCall(MethodBase method) + { + ValidationUtils.ArgumentNotNull(method, "method"); + ConstructorInfo c = method as ConstructorInfo; + if (c != null) + { + return (T o, object[] a) => c.Invoke(a); + } + return (T o, object[] a) => method.Invoke(o, a); + } + + public override Func CreateDefaultConstructor(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + if (type.IsValueType) + { + return () => (T)ReflectionUtils.CreateInstance(type); + } + ConstructorInfo constructorInfo = ReflectionUtils.GetDefaultConstructor(type, nonPublic: true); + return () => (T)constructorInfo.Invoke(null); + } + + public override Func CreateGet(PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + return (T o) => propertyInfo.GetValue(o, null); + } + + public override Func CreateGet(FieldInfo fieldInfo) + { + ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); + return (T o) => fieldInfo.GetValue(o); + } + + public override Action CreateSet(FieldInfo fieldInfo) + { + ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); + return delegate(T o, object v) + { + fieldInfo.SetValue(o, v); + }; + } + + public override Action CreateSet(PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + return delegate(T o, object v) + { + propertyInfo.SetValue(o, v, null); + }; + } + } +} diff --git a/Newtonsoft.Json.Utilities/ListWrapper.cs b/Newtonsoft.Json.Utilities/ListWrapper.cs new file mode 100644 index 00000000..49ced28a --- /dev/null +++ b/Newtonsoft.Json.Utilities/ListWrapper.cs @@ -0,0 +1,187 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Utilities +{ + internal class ListWrapper : CollectionWrapper, IEnumerable, IList, ICollection, IWrappedList, IList, ICollection, IEnumerable + { + private readonly IList _genericList; + + public T this[int index] + { + get + { + if (_genericList != null) + { + return _genericList[index]; + } + return (T)((IList)this)[index]; + } + set + { + if (_genericList != null) + { + _genericList[index] = value; + } + else + { + ((IList)this)[index] = value; + } + } + } + + public override int Count + { + get + { + if (_genericList != null) + { + return _genericList.Count; + } + return base.Count; + } + } + + public override bool IsReadOnly + { + get + { + if (_genericList != null) + { + return _genericList.IsReadOnly; + } + return base.IsReadOnly; + } + } + + public object UnderlyingList + { + get + { + if (_genericList != null) + { + return _genericList; + } + return UnderlyingCollection; + } + } + + public ListWrapper(IList list) + : base(list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + if (list is IList) + { + _genericList = (IList)list; + } + } + + public ListWrapper(IList list) + : base((ICollection)list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + _genericList = list; + } + + public int IndexOf(T item) + { + if (_genericList != null) + { + return _genericList.IndexOf(item); + } + return ((IList)this).IndexOf((object)item); + } + + public void Insert(int index, T item) + { + if (_genericList != null) + { + _genericList.Insert(index, item); + } + else + { + ((IList)this).Insert(index, (object)item); + } + } + + public void RemoveAt(int index) + { + if (_genericList != null) + { + _genericList.RemoveAt(index); + } + else + { + ((IList)this).RemoveAt(index); + } + } + + public override void Add(T item) + { + if (_genericList != null) + { + _genericList.Add(item); + } + else + { + base.Add(item); + } + } + + public override void Clear() + { + if (_genericList != null) + { + _genericList.Clear(); + } + else + { + base.Clear(); + } + } + + public override bool Contains(T item) + { + if (_genericList != null) + { + return _genericList.Contains(item); + } + return base.Contains(item); + } + + public override void CopyTo(T[] array, int arrayIndex) + { + if (_genericList != null) + { + _genericList.CopyTo(array, arrayIndex); + } + else + { + base.CopyTo(array, arrayIndex); + } + } + + public override bool Remove(T item) + { + if (_genericList != null) + { + return _genericList.Remove(item); + } + bool flag = base.Contains(item); + if (flag) + { + base.Remove(item); + } + return flag; + } + + public override IEnumerator GetEnumerator() + { + if (_genericList != null) + { + return _genericList.GetEnumerator(); + } + return base.GetEnumerator(); + } + } +} diff --git a/Newtonsoft.Json.Utilities/MathUtils.cs b/Newtonsoft.Json.Utilities/MathUtils.cs new file mode 100644 index 00000000..ebe3a6f7 --- /dev/null +++ b/Newtonsoft.Json.Utilities/MathUtils.cs @@ -0,0 +1,120 @@ +using System; + +namespace Newtonsoft.Json.Utilities +{ + internal class MathUtils + { + public static int IntLength(int i) + { + if (i < 0) + { + throw new ArgumentOutOfRangeException(); + } + if (i == 0) + { + return 1; + } + return (int)Math.Floor(Math.Log10((double)i)) + 1; + } + + public static int HexToInt(char h) + { + if (h >= '0' && h <= '9') + { + return h - 48; + } + if (h >= 'a' && h <= 'f') + { + return h - 97 + 10; + } + if (h >= 'A' && h <= 'F') + { + return h - 65 + 10; + } + return -1; + } + + public static char IntToHex(int n) + { + if (n <= 9) + { + return (char)(n + 48); + } + return (char)(n - 10 + 97); + } + + public static int GetDecimalPlaces(double value) + { + int num = 10; + double num2 = Math.Pow(0.1, (double)num); + if (value == 0.0) + { + return 0; + } + int num3 = 0; + while (value - Math.Floor(value) > num2 && num3 < num) + { + value *= 10.0; + num3++; + } + return num3; + } + + public static int? Min(int? val1, int? val2) + { + if (!val1.HasValue) + { + return val2; + } + if (!val2.HasValue) + { + return val1; + } + return Math.Min(val1.Value, val2.Value); + } + + public static int? Max(int? val1, int? val2) + { + if (!val1.HasValue) + { + return val2; + } + if (!val2.HasValue) + { + return val1; + } + return Math.Max(val1.Value, val2.Value); + } + + public static double? Min(double? val1, double? val2) + { + if (!val1.HasValue) + { + return val2; + } + if (!val2.HasValue) + { + return val1; + } + return Math.Min(val1.Value, val2.Value); + } + + public static double? Max(double? val1, double? val2) + { + if (!val1.HasValue) + { + return val2; + } + if (!val2.HasValue) + { + return val1; + } + return Math.Max(val1.Value, val2.Value); + } + + public static bool ApproxEquals(double d1, double d2) + { + return Math.Abs(d1 - d2) < Math.Abs(d1) * 1E-06; + } + } +} diff --git a/Newtonsoft.Json.Utilities/MethodCall.cs b/Newtonsoft.Json.Utilities/MethodCall.cs new file mode 100644 index 00000000..a512ede7 --- /dev/null +++ b/Newtonsoft.Json.Utilities/MethodCall.cs @@ -0,0 +1,4 @@ +namespace Newtonsoft.Json.Utilities +{ + internal delegate TResult MethodCall(T target, params object[] args); +} diff --git a/Newtonsoft.Json.Utilities/MiscellaneousUtils.cs b/Newtonsoft.Json.Utilities/MiscellaneousUtils.cs new file mode 100644 index 00000000..17f61992 --- /dev/null +++ b/Newtonsoft.Json.Utilities/MiscellaneousUtils.cs @@ -0,0 +1,157 @@ +using System; +using System.Globalization; + +namespace Newtonsoft.Json.Utilities +{ + internal static class MiscellaneousUtils + { + public static bool ValueEquals(object objA, object objB) + { + if (objA == null && objB == null) + { + return true; + } + if (objA != null && objB == null) + { + return false; + } + if (objA == null && objB != null) + { + return false; + } + if (objA.GetType() != objB.GetType()) + { + if (ConvertUtils.IsInteger(objA) && ConvertUtils.IsInteger(objB)) + { + return Convert.ToDecimal(objA, CultureInfo.CurrentCulture).Equals(Convert.ToDecimal(objB, CultureInfo.CurrentCulture)); + } + if ((objA is double || objA is float || objA is decimal) && (objB is double || objB is float || objB is decimal)) + { + return MathUtils.ApproxEquals(Convert.ToDouble(objA, CultureInfo.CurrentCulture), Convert.ToDouble(objB, CultureInfo.CurrentCulture)); + } + return false; + } + return objA.Equals(objB); + } + + public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string paramName, object actualValue, string message) + { + string message2 = message + Environment.NewLine + "Actual value was {0}.".FormatWith(CultureInfo.InvariantCulture, actualValue); + return new ArgumentOutOfRangeException(paramName, message2); + } + + public static bool TryAction(Creator creator, out T output) + { + ValidationUtils.ArgumentNotNull(creator, "creator"); + try + { + output = creator(); + return true; + IL_001e: + bool result; + return result; + } + catch + { + output = default(T); + return false; + IL_003a: + bool result; + return result; + } + } + + public static string ToString(object value) + { + if (value == null) + { + return "{null}"; + } + return (!(value is string)) ? value.ToString() : ("\"" + value.ToString() + "\""); + } + + public static byte[] HexToBytes(string hex) + { + string text = hex.Replace("-", string.Empty); + byte[] array = new byte[text.Length / 2]; + int num = 4; + int num2 = 0; + string text2 = text; + foreach (char c in text2) + { + int num3 = (c - 48) % 32; + if (num3 > 9) + { + num3 -= 7; + } + array[num2] |= (byte)(num3 << num); + num ^= 4; + if (num != 0) + { + num2++; + } + } + return array; + } + + public static string BytesToHex(byte[] bytes) + { + return BytesToHex(bytes, removeDashes: false); + } + + public static string BytesToHex(byte[] bytes, bool removeDashes) + { + string text = BitConverter.ToString(bytes); + if (removeDashes) + { + text = text.Replace("-", string.Empty); + } + return text; + } + + public static int ByteArrayCompare(byte[] a1, byte[] a2) + { + int num = a1.Length.CompareTo(a2.Length); + if (num != 0) + { + return num; + } + for (int i = 0; i < a1.Length; i++) + { + int num2 = a1[i].CompareTo(a2[i]); + if (num2 != 0) + { + return num2; + } + } + return 0; + } + + public static string GetPrefix(string qualifiedName) + { + GetQualifiedNameParts(qualifiedName, out string prefix, out string _); + return prefix; + } + + public static string GetLocalName(string qualifiedName) + { + GetQualifiedNameParts(qualifiedName, out string _, out string localName); + return localName; + } + + public static void GetQualifiedNameParts(string qualifiedName, out string prefix, out string localName) + { + int num = qualifiedName.IndexOf(':'); + if (num == -1 || num == 0 || qualifiedName.Length - 1 == num) + { + prefix = null; + localName = qualifiedName; + } + else + { + prefix = qualifiedName.Substring(0, num); + localName = qualifiedName.Substring(num + 1); + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/ReflectionDelegateFactory.cs b/Newtonsoft.Json.Utilities/ReflectionDelegateFactory.cs new file mode 100644 index 00000000..668ea8bf --- /dev/null +++ b/Newtonsoft.Json.Utilities/ReflectionDelegateFactory.cs @@ -0,0 +1,51 @@ +using System; +using System.Globalization; +using System.Reflection; + +namespace Newtonsoft.Json.Utilities +{ + internal abstract class ReflectionDelegateFactory + { + public Func CreateGet(MemberInfo memberInfo) + { + PropertyInfo propertyInfo = memberInfo as PropertyInfo; + if (propertyInfo != null) + { + return CreateGet(propertyInfo); + } + FieldInfo fieldInfo = memberInfo as FieldInfo; + if (fieldInfo != null) + { + return CreateGet(fieldInfo); + } + throw new Exception("Could not create getter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo)); + } + + public Action CreateSet(MemberInfo memberInfo) + { + PropertyInfo propertyInfo = memberInfo as PropertyInfo; + if (propertyInfo != null) + { + return CreateSet(propertyInfo); + } + FieldInfo fieldInfo = memberInfo as FieldInfo; + if (fieldInfo != null) + { + return CreateSet(fieldInfo); + } + throw new Exception("Could not create setter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo)); + } + + public abstract MethodCall CreateMethodCall(MethodBase method); + + public abstract Func CreateDefaultConstructor(Type type); + + public abstract Func CreateGet(PropertyInfo propertyInfo); + + public abstract Func CreateGet(FieldInfo fieldInfo); + + public abstract Action CreateSet(FieldInfo fieldInfo); + + public abstract Action CreateSet(PropertyInfo propertyInfo); + } +} diff --git a/Newtonsoft.Json.Utilities/ReflectionUtils.cs b/Newtonsoft.Json.Utilities/ReflectionUtils.cs new file mode 100644 index 00000000..66117b28 --- /dev/null +++ b/Newtonsoft.Json.Utilities/ReflectionUtils.cs @@ -0,0 +1,817 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters; +using System.Text; + +namespace Newtonsoft.Json.Utilities +{ + internal static class ReflectionUtils + { + public static bool IsVirtual(this PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + MethodInfo getMethod = propertyInfo.GetGetMethod(); + if (getMethod != null && getMethod.IsVirtual) + { + return true; + } + getMethod = propertyInfo.GetSetMethod(); + if (getMethod != null && getMethod.IsVirtual) + { + return true; + } + return false; + } + + public static Type GetObjectType(object v) + { + return v?.GetType(); + } + + public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat) + { + return GetTypeName(t, assemblyFormat, null); + } + + public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder) + { + string assemblyQualifiedName = t.AssemblyQualifiedName; + switch (assemblyFormat) + { + case FormatterAssemblyStyle.Simple: + return RemoveAssemblyDetails(assemblyQualifiedName); + case FormatterAssemblyStyle.Full: + return t.AssemblyQualifiedName; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private static string RemoveAssemblyDetails(string fullyQualifiedTypeName) + { + StringBuilder stringBuilder = new StringBuilder(); + bool flag = false; + bool flag2 = false; + foreach (char c in fullyQualifiedTypeName) + { + switch (c) + { + case '[': + flag = false; + flag2 = false; + stringBuilder.Append(c); + break; + case ']': + flag = false; + flag2 = false; + stringBuilder.Append(c); + break; + case ',': + if (!flag) + { + flag = true; + stringBuilder.Append(c); + } + else + { + flag2 = true; + } + break; + default: + if (!flag2) + { + stringBuilder.Append(c); + } + break; + } + } + return stringBuilder.ToString(); + } + + public static bool IsInstantiatableType(Type t) + { + ValidationUtils.ArgumentNotNull(t, "t"); + if (t.IsAbstract || t.IsInterface || t.IsArray || t.IsGenericTypeDefinition || t == typeof(void)) + { + return false; + } + if (!HasDefaultConstructor(t)) + { + return false; + } + return true; + } + + public static bool HasDefaultConstructor(Type t) + { + return HasDefaultConstructor(t, nonPublic: false); + } + + public static bool HasDefaultConstructor(Type t, bool nonPublic) + { + ValidationUtils.ArgumentNotNull(t, "t"); + if (t.IsValueType) + { + return true; + } + return GetDefaultConstructor(t, nonPublic) != null; + } + + public static ConstructorInfo GetDefaultConstructor(Type t) + { + return GetDefaultConstructor(t, nonPublic: false); + } + + public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic) + { + BindingFlags bindingFlags = BindingFlags.Public; + if (nonPublic) + { + bindingFlags |= BindingFlags.NonPublic; + } + return t.GetConstructor(bindingFlags | BindingFlags.Instance, null, new Type[0], null); + } + + public static bool IsNullable(Type t) + { + ValidationUtils.ArgumentNotNull(t, "t"); + if (t.IsValueType) + { + return IsNullableType(t); + } + return true; + } + + public static bool IsNullableType(Type t) + { + ValidationUtils.ArgumentNotNull(t, "t"); + return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static Type EnsureNotNullableType(Type t) + { + return (!IsNullableType(t)) ? t : Nullable.GetUnderlyingType(t); + } + + public static bool IsUnitializedValue(object value) + { + if (value == null) + { + return true; + } + object obj = CreateUnitializedValue(value.GetType()); + return value.Equals(obj); + } + + public static object CreateUnitializedValue(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + if (type.IsGenericTypeDefinition) + { + throw new ArgumentException("Type {0} is a generic type definition and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type"); + } + if (type.IsClass || type.IsInterface || type == typeof(void)) + { + return null; + } + if (type.IsValueType) + { + return Activator.CreateInstance(type); + } + throw new ArgumentException("Type {0} cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type"); + } + + public static bool IsPropertyIndexed(PropertyInfo property) + { + ValidationUtils.ArgumentNotNull(property, "property"); + return !CollectionUtils.IsNullOrEmpty((ICollection)property.GetIndexParameters()); + } + + public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition) + { + Type implementingType; + return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType); + } + + public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition"); + if (!genericInterfaceDefinition.IsInterface || !genericInterfaceDefinition.IsGenericTypeDefinition) + { + throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition)); + } + if (type.IsInterface && type.IsGenericType) + { + Type genericTypeDefinition = type.GetGenericTypeDefinition(); + if (genericInterfaceDefinition == genericTypeDefinition) + { + implementingType = type; + return true; + } + } + Type[] interfaces = type.GetInterfaces(); + foreach (Type type2 in interfaces) + { + if (type2.IsGenericType) + { + Type genericTypeDefinition2 = type2.GetGenericTypeDefinition(); + if (genericInterfaceDefinition == genericTypeDefinition2) + { + implementingType = type2; + return true; + } + } + } + implementingType = null; + return false; + } + + public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match) + { + for (Type type2 = type; type2 != null; type2 = type2.BaseType) + { + if (string.Equals(type2.FullName, fullTypeName, StringComparison.Ordinal)) + { + match = type2; + return true; + } + } + Type[] interfaces = type.GetInterfaces(); + foreach (Type type3 in interfaces) + { + if (string.Equals(type3.Name, fullTypeName, StringComparison.Ordinal)) + { + match = type; + return true; + } + } + match = null; + return false; + } + + public static bool AssignableToTypeName(this Type type, string fullTypeName) + { + Type match; + return type.AssignableToTypeName(fullTypeName, out match); + } + + public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition) + { + Type implementingType; + return InheritsGenericDefinition(type, genericClassDefinition, out implementingType); + } + + public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition"); + if (!genericClassDefinition.IsClass || !genericClassDefinition.IsGenericTypeDefinition) + { + throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition)); + } + return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType); + } + + private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType) + { + if (currentType.IsGenericType) + { + Type genericTypeDefinition = currentType.GetGenericTypeDefinition(); + if (genericClassDefinition == genericTypeDefinition) + { + implementingType = currentType; + return true; + } + } + if (currentType.BaseType == null) + { + implementingType = null; + return false; + } + return InheritsGenericDefinitionInternal(currentType.BaseType, genericClassDefinition, out implementingType); + } + + public static Type GetCollectionItemType(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + if (type.IsArray) + { + return type.GetElementType(); + } + if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out Type implementingType)) + { + if (implementingType.IsGenericTypeDefinition) + { + throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); + } + return implementingType.GetGenericArguments()[0]; + } + if (typeof(IEnumerable).IsAssignableFrom(type)) + { + return null; + } + throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); + } + + public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType) + { + ValidationUtils.ArgumentNotNull(dictionaryType, "type"); + if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<, >), out Type implementingType)) + { + if (implementingType.IsGenericTypeDefinition) + { + throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); + } + Type[] genericArguments = implementingType.GetGenericArguments(); + keyType = genericArguments[0]; + valueType = genericArguments[1]; + } + else + { + if (!typeof(IDictionary).IsAssignableFrom(dictionaryType)) + { + throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); + } + keyType = null; + valueType = null; + } + } + + public static Type GetDictionaryValueType(Type dictionaryType) + { + GetDictionaryKeyValueTypes(dictionaryType, out Type _, out Type valueType); + return valueType; + } + + public static Type GetDictionaryKeyType(Type dictionaryType) + { + GetDictionaryKeyValueTypes(dictionaryType, out Type keyType, out Type _); + return keyType; + } + + public static bool ItemsUnitializedValue(IList list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + Type collectionItemType = GetCollectionItemType(list.GetType()); + if (collectionItemType.IsValueType) + { + object obj = CreateUnitializedValue(collectionItemType); + for (int i = 0; i < list.Count; i++) + { + if (!list[i].Equals(obj)) + { + return false; + } + } + } + else + { + if (!collectionItemType.IsClass) + { + throw new Exception("Type {0} is neither a ValueType or a Class.".FormatWith(CultureInfo.InvariantCulture, collectionItemType)); + } + for (int j = 0; j < list.Count; j++) + { + object obj2 = list[j]; + if (obj2 != null) + { + return false; + } + } + } + return true; + } + + public static Type GetMemberUnderlyingType(MemberInfo member) + { + ValidationUtils.ArgumentNotNull(member, "member"); + switch (member.MemberType) + { + case MemberTypes.Field: + return ((FieldInfo)member).FieldType; + case MemberTypes.Property: + return ((PropertyInfo)member).PropertyType; + case MemberTypes.Event: + return ((EventInfo)member).EventHandlerType; + default: + throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member"); + } + } + + public static bool IsIndexedProperty(MemberInfo member) + { + ValidationUtils.ArgumentNotNull(member, "member"); + PropertyInfo propertyInfo = member as PropertyInfo; + if (propertyInfo != null) + { + return IsIndexedProperty(propertyInfo); + } + return false; + } + + public static bool IsIndexedProperty(PropertyInfo property) + { + ValidationUtils.ArgumentNotNull(property, "property"); + return property.GetIndexParameters().Length > 0; + } + + public static object GetMemberValue(MemberInfo member, object target) + { + ValidationUtils.ArgumentNotNull(member, "member"); + ValidationUtils.ArgumentNotNull(target, "target"); + switch (member.MemberType) + { + case MemberTypes.Field: + return ((FieldInfo)member).GetValue(target); + case MemberTypes.Property: + try + { + return ((PropertyInfo)member).GetValue(target, null); + IL_0051:; + } + catch (TargetParameterCountException innerException) + { + throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), innerException); + IL_007c:; + } + break; + } + throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member"); + } + + public static void SetMemberValue(MemberInfo member, object target, object value) + { + ValidationUtils.ArgumentNotNull(member, "member"); + ValidationUtils.ArgumentNotNull(target, "target"); + switch (member.MemberType) + { + case MemberTypes.Field: + ((FieldInfo)member).SetValue(target, value); + break; + case MemberTypes.Property: + ((PropertyInfo)member).SetValue(target, value, null); + break; + default: + throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member"); + } + } + + public static bool CanReadMemberValue(MemberInfo member, bool nonPublic) + { + switch (member.MemberType) + { + case MemberTypes.Field: + { + FieldInfo fieldInfo = (FieldInfo)member; + if (nonPublic) + { + return true; + } + if (fieldInfo.IsPublic) + { + return true; + } + return false; + } + case MemberTypes.Property: + { + PropertyInfo propertyInfo = (PropertyInfo)member; + if (!propertyInfo.CanRead) + { + return false; + } + if (nonPublic) + { + return true; + } + return propertyInfo.GetGetMethod(nonPublic) != null; + } + default: + return false; + } + } + + public static bool CanSetMemberValue(MemberInfo member, bool nonPublic, bool canSetReadOnly) + { + switch (member.MemberType) + { + case MemberTypes.Field: + { + FieldInfo fieldInfo = (FieldInfo)member; + if (fieldInfo.IsInitOnly && !canSetReadOnly) + { + return false; + } + if (nonPublic) + { + return true; + } + if (fieldInfo.IsPublic) + { + return true; + } + return false; + } + case MemberTypes.Property: + { + PropertyInfo propertyInfo = (PropertyInfo)member; + if (!propertyInfo.CanWrite) + { + return false; + } + if (nonPublic) + { + return true; + } + return propertyInfo.GetSetMethod(nonPublic) != null; + } + default: + return false; + } + } + + public static List GetFieldsAndProperties(BindingFlags bindingAttr) + { + return GetFieldsAndProperties(typeof(T), bindingAttr); + } + + public static List GetFieldsAndProperties(Type type, BindingFlags bindingAttr) + { + List list = new List(); + list.AddRange(GetFields(type, bindingAttr)); + list.AddRange(GetProperties(type, bindingAttr)); + List list2 = new List(list.Count); + var enumerable = from m in list + group m by m.Name into g + select new + { + Count = g.Count(), + Members = g.Cast() + }; + foreach (var item in enumerable) + { + if (item.Count == 1) + { + list2.Add(item.Members.First()); + } + else + { + IEnumerable collection = from m in item.Members + where !IsOverridenGenericMember(m, bindingAttr) || m.Name == "Item" + select m; + list2.AddRange(collection); + } + } + return list2; + } + + private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr) + { + if (memberInfo.MemberType != MemberTypes.Field && memberInfo.MemberType != MemberTypes.Property) + { + throw new ArgumentException("Member must be a field or property."); + } + Type declaringType = memberInfo.DeclaringType; + if (!declaringType.IsGenericType) + { + return false; + } + Type genericTypeDefinition = declaringType.GetGenericTypeDefinition(); + if (genericTypeDefinition == null) + { + return false; + } + MemberInfo[] member = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr); + if (member.Length == 0) + { + return false; + } + Type memberUnderlyingType = GetMemberUnderlyingType(member[0]); + if (!memberUnderlyingType.IsGenericParameter) + { + return false; + } + return true; + } + + public static T GetAttribute(ICustomAttributeProvider attributeProvider) where T : Attribute + { + return GetAttribute(attributeProvider, inherit: true); + } + + public static T GetAttribute(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute + { + T[] attributes = GetAttributes(attributeProvider, inherit); + return CollectionUtils.GetSingleItem(attributes, returnDefaultIfEmpty: true); + } + + public static T[] GetAttributes(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute + { + ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider"); + if (attributeProvider is Type) + { + return (T[])((Type)attributeProvider).GetCustomAttributes(typeof(T), inherit); + } + if (attributeProvider is Assembly) + { + return (T[])Attribute.GetCustomAttributes((Assembly)attributeProvider, typeof(T), inherit); + } + if (attributeProvider is MemberInfo) + { + return (T[])Attribute.GetCustomAttributes((MemberInfo)attributeProvider, typeof(T), inherit); + } + if (attributeProvider is Module) + { + return (T[])Attribute.GetCustomAttributes((Module)attributeProvider, typeof(T), inherit); + } + if (attributeProvider is ParameterInfo) + { + return (T[])Attribute.GetCustomAttributes((ParameterInfo)attributeProvider, typeof(T), inherit); + } + return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit); + } + + public static string GetNameAndAssessmblyName(Type t) + { + ValidationUtils.ArgumentNotNull(t, "t"); + return t.FullName + ", " + t.Assembly.GetName().Name; + } + + public static Type MakeGenericType(Type genericTypeDefinition, params Type[] innerTypes) + { + ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition"); + ValidationUtils.ArgumentNotNullOrEmpty((ICollection)innerTypes, "innerTypes"); + ValidationUtils.ArgumentConditionTrue(genericTypeDefinition.IsGenericTypeDefinition, "genericTypeDefinition", "Type {0} is not a generic type definition.".FormatWith(CultureInfo.InvariantCulture, genericTypeDefinition)); + return genericTypeDefinition.MakeGenericType(innerTypes); + } + + public static object CreateGeneric(Type genericTypeDefinition, Type innerType, params object[] args) + { + return CreateGeneric(genericTypeDefinition, new Type[1] + { + innerType + }, args); + } + + public static object CreateGeneric(Type genericTypeDefinition, IList innerTypes, params object[] args) + { + return CreateGeneric(genericTypeDefinition, innerTypes, (Type t, IList a) => CreateInstance(t, a.ToArray()), args); + } + + public static object CreateGeneric(Type genericTypeDefinition, IList innerTypes, Func, object> instanceCreator, params object[] args) + { + ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition"); + ValidationUtils.ArgumentNotNullOrEmpty(innerTypes, "innerTypes"); + ValidationUtils.ArgumentNotNull(instanceCreator, "createInstance"); + Type arg = MakeGenericType(genericTypeDefinition, innerTypes.ToArray()); + return instanceCreator(arg, args); + } + + public static bool IsCompatibleValue(object value, Type type) + { + if (value == null) + { + return IsNullable(type); + } + if (type.IsAssignableFrom(value.GetType())) + { + return true; + } + return false; + } + + public static object CreateInstance(Type type, params object[] args) + { + ValidationUtils.ArgumentNotNull(type, "type"); + return Activator.CreateInstance(type, args); + } + + public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName) + { + int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName); + if (assemblyDelimiterIndex.HasValue) + { + typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim(); + assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim(); + } + else + { + typeName = fullyQualifiedTypeName; + assemblyName = null; + } + } + + private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName) + { + int num = 0; + for (int i = 0; i < fullyQualifiedTypeName.Length; i++) + { + switch (fullyQualifiedTypeName[i]) + { + case '[': + num++; + break; + case ']': + num--; + break; + case ',': + if (num == 0) + { + return i; + } + break; + } + } + return null; + } + + public static MemberInfo GetMemberInfoFromType(Type targetType, MemberInfo memberInfo) + { + BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + MemberTypes memberType = memberInfo.MemberType; + if (memberType == MemberTypes.Property) + { + PropertyInfo propertyInfo = (PropertyInfo)memberInfo; + Type[] types = (from p in propertyInfo.GetIndexParameters() + select p.ParameterType).ToArray(); + return targetType.GetProperty(propertyInfo.Name, bindingAttr, null, propertyInfo.PropertyType, types, null); + } + return targetType.GetMember(memberInfo.Name, memberInfo.MemberType, bindingAttr).SingleOrDefault(); + } + + public static IEnumerable GetFields(Type targetType, BindingFlags bindingAttr) + { + ValidationUtils.ArgumentNotNull(targetType, "targetType"); + List list = new List(targetType.GetFields(bindingAttr)); + GetChildPrivateFields(list, targetType, bindingAttr); + return list.Cast(); + } + + private static void GetChildPrivateFields(IList initialFields, Type targetType, BindingFlags bindingAttr) + { + if ((bindingAttr & BindingFlags.NonPublic) != 0) + { + BindingFlags bindingAttr2 = bindingAttr.RemoveFlag(BindingFlags.Public); + while ((targetType = targetType.BaseType) != null) + { + IEnumerable collection = (from f in targetType.GetFields(bindingAttr2) + where f.IsPrivate + select f).Cast(); + initialFields.AddRange(collection); + } + } + } + + public static IEnumerable GetProperties(Type targetType, BindingFlags bindingAttr) + { + ValidationUtils.ArgumentNotNull(targetType, "targetType"); + List list = new List(targetType.GetProperties(bindingAttr)); + GetChildPrivateProperties(list, targetType, bindingAttr); + for (int i = 0; i < list.Count; i++) + { + PropertyInfo propertyInfo = list[i]; + if (propertyInfo.DeclaringType != targetType) + { + PropertyInfo propertyInfo3 = list[i] = (PropertyInfo)GetMemberInfoFromType(propertyInfo.DeclaringType, propertyInfo); + } + } + return list; + } + + public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag) + { + return ((bindingAttr & flag) != flag) ? bindingAttr : (bindingAttr ^ flag); + } + + private static void GetChildPrivateProperties(IList initialProperties, Type targetType, BindingFlags bindingAttr) + { + if ((bindingAttr & BindingFlags.NonPublic) != 0) + { + BindingFlags bindingAttr2 = bindingAttr.RemoveFlag(BindingFlags.Public); + while ((targetType = targetType.BaseType) != null) + { + PropertyInfo[] properties = targetType.GetProperties(bindingAttr2); + foreach (PropertyInfo propertyInfo in properties) + { + PropertyInfo nonPublicProperty = propertyInfo; + int num = initialProperties.IndexOf((PropertyInfo p) => p.Name == nonPublicProperty.Name); + if (num == -1) + { + initialProperties.Add(nonPublicProperty); + } + else + { + initialProperties[num] = nonPublicProperty; + } + } + } + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/StringBuffer.cs b/Newtonsoft.Json.Utilities/StringBuffer.cs new file mode 100644 index 00000000..789e4cc5 --- /dev/null +++ b/Newtonsoft.Json.Utilities/StringBuffer.cs @@ -0,0 +1,72 @@ +using System; + +namespace Newtonsoft.Json.Utilities +{ + internal class StringBuffer + { + private char[] _buffer; + + private int _position; + + private static readonly char[] _emptyBuffer = new char[0]; + + public int Position + { + get + { + return _position; + } + set + { + _position = value; + } + } + + public StringBuffer() + { + _buffer = _emptyBuffer; + } + + public StringBuffer(int initalSize) + { + _buffer = new char[initalSize]; + } + + public void Append(char value) + { + if (_position == _buffer.Length) + { + EnsureSize(1); + } + _buffer[_position++] = value; + } + + public void Clear() + { + _buffer = _emptyBuffer; + _position = 0; + } + + private void EnsureSize(int appendLength) + { + char[] array = new char[(_position + appendLength) * 2]; + Array.Copy(_buffer, array, _position); + _buffer = array; + } + + public override string ToString() + { + return ToString(0, _position); + } + + public string ToString(int start, int length) + { + return new string(_buffer, start, length); + } + + public char[] GetInternalBuffer() + { + return _buffer; + } + } +} diff --git a/Newtonsoft.Json.Utilities/StringUtils.cs b/Newtonsoft.Json.Utilities/StringUtils.cs new file mode 100644 index 00000000..889c2d98 --- /dev/null +++ b/Newtonsoft.Json.Utilities/StringUtils.cs @@ -0,0 +1,323 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +namespace Newtonsoft.Json.Utilities +{ + internal static class StringUtils + { + private delegate void ActionLine(TextWriter textWriter, string line); + + public const string CarriageReturnLineFeed = "\r\n"; + + public const string Empty = ""; + + public const char CarriageReturn = '\r'; + + public const char LineFeed = '\n'; + + public const char Tab = '\t'; + + public static string FormatWith(this string format, IFormatProvider provider, params object[] args) + { + ValidationUtils.ArgumentNotNull(format, "format"); + return string.Format(provider, format, args); + } + + public static bool ContainsWhiteSpace(string s) + { + if (s == null) + { + throw new ArgumentNullException("s"); + } + for (int i = 0; i < s.Length; i++) + { + if (char.IsWhiteSpace(s[i])) + { + return true; + } + } + return false; + } + + public static bool IsWhiteSpace(string s) + { + if (s == null) + { + throw new ArgumentNullException("s"); + } + if (s.Length == 0) + { + return false; + } + for (int i = 0; i < s.Length; i++) + { + if (!char.IsWhiteSpace(s[i])) + { + return false; + } + } + return true; + } + + public static string EnsureEndsWith(string target, string value) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + if (value == null) + { + throw new ArgumentNullException("value"); + } + if (target.Length >= value.Length) + { + if (string.Compare(target, target.Length - value.Length, value, 0, value.Length, StringComparison.OrdinalIgnoreCase) == 0) + { + return target; + } + string text = target.TrimEnd(null); + if (string.Compare(text, text.Length - value.Length, value, 0, value.Length, StringComparison.OrdinalIgnoreCase) == 0) + { + return target; + } + } + return target + value; + } + + public static bool IsNullOrEmptyOrWhiteSpace(string s) + { + if (string.IsNullOrEmpty(s)) + { + return true; + } + if (IsWhiteSpace(s)) + { + return true; + } + return false; + } + + public static void IfNotNullOrEmpty(string value, Action action) + { + IfNotNullOrEmpty(value, action, null); + } + + private static void IfNotNullOrEmpty(string value, Action trueAction, Action falseAction) + { + if (!string.IsNullOrEmpty(value)) + { + trueAction?.Invoke(value); + } + else + { + falseAction?.Invoke(value); + } + } + + public static string Indent(string s, int indentation) + { + return Indent(s, indentation, ' '); + } + + public static string Indent(string s, int indentation, char indentChar) + { + if (s == null) + { + throw new ArgumentNullException("s"); + } + if (indentation <= 0) + { + throw new ArgumentException("Must be greater than zero.", "indentation"); + } + StringReader textReader = new StringReader(s); + StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture); + ActionTextReaderLine(textReader, stringWriter, delegate(TextWriter tw, string line) + { + tw.Write(new string(indentChar, indentation)); + tw.Write(line); + }); + return stringWriter.ToString(); + } + + private static void ActionTextReaderLine(TextReader textReader, TextWriter textWriter, ActionLine lineAction) + { + bool flag = true; + string line; + while ((line = textReader.ReadLine()) != null) + { + if (!flag) + { + textWriter.WriteLine(); + } + else + { + flag = false; + } + lineAction(textWriter, line); + } + } + + public static string NumberLines(string s) + { + if (s == null) + { + throw new ArgumentNullException("s"); + } + StringReader textReader = new StringReader(s); + StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture); + int lineNumber = 1; + ActionTextReaderLine(textReader, stringWriter, delegate(TextWriter tw, string line) + { + tw.Write(lineNumber.ToString(CultureInfo.InvariantCulture).PadLeft(4)); + tw.Write(". "); + tw.Write(line); + lineNumber++; + }); + return stringWriter.ToString(); + } + + public static string NullEmptyString(string s) + { + return (!string.IsNullOrEmpty(s)) ? s : null; + } + + public static string ReplaceNewLines(string s, string replacement) + { + StringReader stringReader = new StringReader(s); + StringBuilder stringBuilder = new StringBuilder(); + bool flag = true; + string value; + while ((value = stringReader.ReadLine()) != null) + { + if (flag) + { + flag = false; + } + else + { + stringBuilder.Append(replacement); + } + stringBuilder.Append(value); + } + return stringBuilder.ToString(); + } + + public static string Truncate(string s, int maximumLength) + { + return Truncate(s, maximumLength, "..."); + } + + public static string Truncate(string s, int maximumLength, string suffix) + { + if (suffix == null) + { + throw new ArgumentNullException("suffix"); + } + if (maximumLength <= 0) + { + throw new ArgumentException("Maximum length must be greater than zero.", "maximumLength"); + } + int num = maximumLength - suffix.Length; + if (num <= 0) + { + throw new ArgumentException("Length of suffix string is greater or equal to maximumLength"); + } + if (s != null && s.Length > maximumLength) + { + string text = s.Substring(0, num); + text = text.Trim(); + return text + suffix; + } + return s; + } + + public static StringWriter CreateStringWriter(int capacity) + { + StringBuilder sb = new StringBuilder(capacity); + return new StringWriter(sb, CultureInfo.InvariantCulture); + } + + public static int? GetLength(string value) + { + return value?.Length; + } + + public static string ToCharAsUnicode(char c) + { + char c2 = MathUtils.IntToHex(((int)c >> 12) & 0xF); + char c3 = MathUtils.IntToHex(((int)c >> 8) & 0xF); + char c4 = MathUtils.IntToHex(((int)c >> 4) & 0xF); + char c5 = MathUtils.IntToHex(c & 0xF); + return new string(new char[6] + { + '\\', + 'u', + c2, + c3, + c4, + c5 + }); + } + + public static void WriteCharAsUnicode(TextWriter writer, char c) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + char value = MathUtils.IntToHex(((int)c >> 12) & 0xF); + char value2 = MathUtils.IntToHex(((int)c >> 8) & 0xF); + char value3 = MathUtils.IntToHex(((int)c >> 4) & 0xF); + char value4 = MathUtils.IntToHex(c & 0xF); + writer.Write('\\'); + writer.Write('u'); + writer.Write(value); + writer.Write(value2); + writer.Write(value3); + writer.Write(value4); + } + + public static TSource ForgivingCaseSensitiveFind(this IEnumerable source, Func valueSelector, string testValue) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + if (valueSelector == null) + { + throw new ArgumentNullException("valueSelector"); + } + TSource[] array = (from s in source + where string.Compare(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase) == 0 + select s).ToArray(); + int num = array.Length; + if (num <= 1) + { + return (num != 1) ? default(TSource) : array[0]; + } + IEnumerable source2 = from s in source + where string.Compare(valueSelector(s), testValue, StringComparison.Ordinal) == 0 + select s; + return source2.SingleOrDefault(); + } + + public static string ToCamelCase(string s) + { + if (string.IsNullOrEmpty(s)) + { + return s; + } + if (!char.IsUpper(s[0])) + { + return s; + } + string text = char.ToLower(s[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture); + if (s.Length > 1) + { + text += s.Substring(1); + } + return text; + } + } +} diff --git a/Newtonsoft.Json.Utilities/ThreadSafeStore.cs b/Newtonsoft.Json.Utilities/ThreadSafeStore.cs new file mode 100644 index 00000000..12614857 --- /dev/null +++ b/Newtonsoft.Json.Utilities/ThreadSafeStore.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Utilities +{ + internal class ThreadSafeStore + { + private readonly object _lock = new object(); + + private Dictionary _store; + + private readonly Func _creator; + + public ThreadSafeStore(Func creator) + { + if (creator == null) + { + throw new ArgumentNullException("creator"); + } + _creator = creator; + } + + public TValue Get(TKey key) + { + if (_store == null) + { + return AddValue(key); + } + if (!_store.TryGetValue(key, out TValue value)) + { + return AddValue(key); + } + return value; + } + + private TValue AddValue(TKey key) + { + TValue val = _creator(key); + lock (_lock) + { + if (_store == null) + { + _store = new Dictionary(); + _store[key] = val; + } + else + { + if (_store.TryGetValue(key, out TValue value)) + { + return value; + } + Dictionary dictionary = new Dictionary(_store); + dictionary[key] = val; + _store = dictionary; + } + return val; + IL_0080: + TValue result; + return result; + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/TypeExtensions.cs b/Newtonsoft.Json.Utilities/TypeExtensions.cs new file mode 100644 index 00000000..98ae19c5 --- /dev/null +++ b/Newtonsoft.Json.Utilities/TypeExtensions.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Newtonsoft.Json.Utilities +{ + internal static class TypeExtensions + { + public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes) + { + IEnumerable enumerable = from method in type.GetMethods() + where method.Name == name + select method; + foreach (MethodInfo item in enumerable) + { + if (item.HasParameters(parameterTypes)) + { + return item; + } + } + return null; + } + + public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes) + { + Type[] array = (from parameter in method.GetParameters() + select parameter.ParameterType).ToArray(); + if (array.Length != parameterTypes.Length) + { + return false; + } + for (int i = 0; i < array.Length; i++) + { + if (array[i].ToString() != parameterTypes[i].ToString()) + { + return false; + } + } + return true; + } + + public static IEnumerable AllInterfaces(this Type target) + { + Type[] interfaces = target.GetInterfaces(); + foreach (Type IF in interfaces) + { + yield return IF; + foreach (Type item in IF.AllInterfaces()) + { + yield return item; + } + } + } + + public static IEnumerable AllMethods(this Type target) + { + List list = target.AllInterfaces().ToList(); + list.Add(target); + return from type in list + from method in type.GetMethods() + select method; + } + } +} diff --git a/Newtonsoft.Json.Utilities/ValidationUtils.cs b/Newtonsoft.Json.Utilities/ValidationUtils.cs new file mode 100644 index 00000000..6883829b --- /dev/null +++ b/Newtonsoft.Json.Utilities/ValidationUtils.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; + +namespace Newtonsoft.Json.Utilities +{ + internal static class ValidationUtils + { + public const string EmailAddressRegex = "^([a-zA-Z0-9_'+*$%\\^&!\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9:]{2,4})+$"; + + public const string CurrencyRegex = "(^\\$?(?!0,?\\d)\\d{1,3}(,?\\d{3})*(\\.\\d\\d)?)$"; + + public const string DateRegex = "^(((0?[1-9]|[12]\\d|3[01])[\\.\\-\\/](0?[13578]|1[02])[\\.\\-\\/]((1[6-9]|[2-9]\\d)?\\d{2}|\\d))|((0?[1-9]|[12]\\d|30)[\\.\\-\\/](0?[13456789]|1[012])[\\.\\-\\/]((1[6-9]|[2-9]\\d)?\\d{2}|\\d))|((0?[1-9]|1\\d|2[0-8])[\\.\\-\\/]0?2[\\.\\-\\/]((1[6-9]|[2-9]\\d)?\\d{2}|\\d))|(29[\\.\\-\\/]0?2[\\.\\-\\/]((1[6-9]|[2-9]\\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00|[048])))$"; + + public const string NumericRegex = "\\d*"; + + public static void ArgumentNotNullOrEmpty(string value, string parameterName) + { + if (value == null) + { + throw new ArgumentNullException(parameterName); + } + if (value.Length == 0) + { + throw new ArgumentException("'{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName); + } + } + + public static void ArgumentNotNullOrEmptyOrWhitespace(string value, string parameterName) + { + ArgumentNotNullOrEmpty(value, parameterName); + if (StringUtils.IsWhiteSpace(value)) + { + throw new ArgumentException("'{0}' cannot only be whitespace.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName); + } + } + + public static void ArgumentTypeIsEnum(Type enumType, string parameterName) + { + ArgumentNotNull(enumType, "enumType"); + if (!enumType.IsEnum) + { + throw new ArgumentException("Type {0} is not an Enum.".FormatWith(CultureInfo.InvariantCulture, enumType), parameterName); + } + } + + public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName) + { + ArgumentNotNullOrEmpty(collection, parameterName, "Collection '{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName)); + } + + public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName, string message) + { + if (collection == null) + { + throw new ArgumentNullException(parameterName); + } + if (collection.Count == 0) + { + throw new ArgumentException(message, parameterName); + } + } + + public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName) + { + ArgumentNotNullOrEmpty(collection, parameterName, "Collection '{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName)); + } + + public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName, string message) + { + if (collection == null) + { + throw new ArgumentNullException(parameterName); + } + if (collection.Count == 0) + { + throw new ArgumentException(message, parameterName); + } + } + + public static void ArgumentNotNull(object value, string parameterName) + { + if (value == null) + { + throw new ArgumentNullException(parameterName); + } + } + + public static void ArgumentNotNegative(int value, string parameterName) + { + if (value <= 0) + { + throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Argument cannot be negative."); + } + } + + public static void ArgumentNotNegative(int value, string parameterName, string message) + { + if (value <= 0) + { + throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message); + } + } + + public static void ArgumentNotZero(int value, string parameterName) + { + if (value == 0) + { + throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Argument cannot be zero."); + } + } + + public static void ArgumentNotZero(int value, string parameterName, string message) + { + if (value == 0) + { + throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message); + } + } + + public static void ArgumentIsPositive(T value, string parameterName) where T : struct, IComparable + { + if (value.CompareTo(default(T)) != 1) + { + throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Positive number required."); + } + } + + public static void ArgumentIsPositive(int value, string parameterName, string message) + { + if (value > 0) + { + throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message); + } + } + + public static void ObjectNotDisposed(bool disposed, Type objectType) + { + if (disposed) + { + throw new ObjectDisposedException(objectType.Name); + } + } + + public static void ArgumentConditionTrue(bool condition, string parameterName, string message) + { + if (!condition) + { + throw new ArgumentException(message, parameterName); + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/WrapperDictionary.cs b/Newtonsoft.Json.Utilities/WrapperDictionary.cs new file mode 100644 index 00000000..2a590e1c --- /dev/null +++ b/Newtonsoft.Json.Utilities/WrapperDictionary.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Utilities +{ + internal class WrapperDictionary + { + private readonly Dictionary _wrapperTypes = new Dictionary(); + + private static string GenerateKey(Type interfaceType, Type realObjectType) + { + return interfaceType.Name + "_" + realObjectType.Name; + } + + public Type GetType(Type interfaceType, Type realObjectType) + { + string key = GenerateKey(interfaceType, realObjectType); + if (_wrapperTypes.ContainsKey(key)) + { + return _wrapperTypes[key]; + } + return null; + } + + public void SetType(Type interfaceType, Type realObjectType, Type wrapperType) + { + string key = GenerateKey(interfaceType, realObjectType); + if (_wrapperTypes.ContainsKey(key)) + { + _wrapperTypes[key] = wrapperType; + } + else + { + _wrapperTypes.Add(key, wrapperType); + } + } + } +} diff --git a/Newtonsoft.Json.Utilities/WrapperMethodBuilder.cs b/Newtonsoft.Json.Utilities/WrapperMethodBuilder.cs new file mode 100644 index 00000000..b35c87e2 --- /dev/null +++ b/Newtonsoft.Json.Utilities/WrapperMethodBuilder.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; + +namespace Newtonsoft.Json.Utilities +{ + internal class WrapperMethodBuilder + { + private readonly Type _realObjectType; + + private readonly TypeBuilder _wrapperBuilder; + + public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder) + { + _realObjectType = realObjectType; + _wrapperBuilder = proxyBuilder; + } + + public void Generate(MethodInfo newMethod) + { + if (newMethod.IsGenericMethod) + { + newMethod = newMethod.GetGenericMethodDefinition(); + } + FieldInfo field = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic); + ParameterInfo[] parameters = newMethod.GetParameters(); + Type[] parameterTypes = (from parameter in parameters + select parameter.ParameterType).ToArray(); + MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod(newMethod.Name, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual, newMethod.ReturnType, parameterTypes); + if (newMethod.IsGenericMethod) + { + methodBuilder.DefineGenericParameters((from arg in newMethod.GetGenericArguments() + select arg.Name).ToArray()); + } + ILGenerator iLGenerator = methodBuilder.GetILGenerator(); + LoadUnderlyingObject(iLGenerator, field); + PushParameters(parameters, iLGenerator); + ExecuteMethod(newMethod, parameterTypes, iLGenerator); + Return(iLGenerator); + } + + private static void Return(ILGenerator ilGenerator) + { + ilGenerator.Emit(OpCodes.Ret); + } + + private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator) + { + MethodInfo method = GetMethod(newMethod, parameterTypes); + if (method == null) + { + throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName); + } + ilGenerator.Emit(OpCodes.Call, method); + } + + private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes) + { + if (realMethod.IsGenericMethod) + { + return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes); + } + return _realObjectType.GetMethod(realMethod.Name, parameterTypes); + } + + private static void PushParameters(ICollection parameters, ILGenerator ilGenerator) + { + for (int i = 1; i < parameters.Count + 1; i++) + { + ilGenerator.Emit(OpCodes.Ldarg, i); + } + } + + private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField) + { + ilGenerator.Emit(OpCodes.Ldarg_0); + ilGenerator.Emit(OpCodes.Ldfld, srcField); + } + } +} diff --git a/Newtonsoft.Json/ConstructorHandling.cs b/Newtonsoft.Json/ConstructorHandling.cs new file mode 100644 index 00000000..40a15eb2 --- /dev/null +++ b/Newtonsoft.Json/ConstructorHandling.cs @@ -0,0 +1,8 @@ +namespace Newtonsoft.Json +{ + public enum ConstructorHandling + { + Default, + AllowNonPublicDefaultConstructor + } +} diff --git a/Newtonsoft.Json/DefaultValueHandling.cs b/Newtonsoft.Json/DefaultValueHandling.cs new file mode 100644 index 00000000..2df4c6d5 --- /dev/null +++ b/Newtonsoft.Json/DefaultValueHandling.cs @@ -0,0 +1,13 @@ +using System; + +namespace Newtonsoft.Json +{ + [Flags] + public enum DefaultValueHandling + { + Include = 0x0, + Ignore = 0x1, + Populate = 0x2, + IgnoreAndPopulate = 0x3 + } +} diff --git a/Newtonsoft.Json/Formatting.cs b/Newtonsoft.Json/Formatting.cs new file mode 100644 index 00000000..0a3ebca8 --- /dev/null +++ b/Newtonsoft.Json/Formatting.cs @@ -0,0 +1,8 @@ +namespace Newtonsoft.Json +{ + public enum Formatting + { + None, + Indented + } +} diff --git a/Newtonsoft.Json/IJsonLineInfo.cs b/Newtonsoft.Json/IJsonLineInfo.cs new file mode 100644 index 00000000..a16e7dfe --- /dev/null +++ b/Newtonsoft.Json/IJsonLineInfo.cs @@ -0,0 +1,17 @@ +namespace Newtonsoft.Json +{ + public interface IJsonLineInfo + { + int LineNumber + { + get; + } + + int LinePosition + { + get; + } + + bool HasLineInfo(); + } +} diff --git a/Newtonsoft.Json/JsonArrayAttribute.cs b/Newtonsoft.Json/JsonArrayAttribute.cs new file mode 100644 index 00000000..33d4df98 --- /dev/null +++ b/Newtonsoft.Json/JsonArrayAttribute.cs @@ -0,0 +1,36 @@ +using System; + +namespace Newtonsoft.Json +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] + public sealed class JsonArrayAttribute : JsonContainerAttribute + { + private bool _allowNullItems; + + public bool AllowNullItems + { + get + { + return _allowNullItems; + } + set + { + _allowNullItems = value; + } + } + + public JsonArrayAttribute() + { + } + + public JsonArrayAttribute(bool allowNullItems) + { + _allowNullItems = allowNullItems; + } + + public JsonArrayAttribute(string id) + : base(id) + { + } + } +} diff --git a/Newtonsoft.Json/JsonConstructorAttribute.cs b/Newtonsoft.Json/JsonConstructorAttribute.cs new file mode 100644 index 00000000..1621c745 --- /dev/null +++ b/Newtonsoft.Json/JsonConstructorAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Newtonsoft.Json +{ + [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Property, AllowMultiple = false)] + public sealed class JsonConstructorAttribute : Attribute + { + } +} diff --git a/Newtonsoft.Json/JsonContainerAttribute.cs b/Newtonsoft.Json/JsonContainerAttribute.cs new file mode 100644 index 00000000..177796e8 --- /dev/null +++ b/Newtonsoft.Json/JsonContainerAttribute.cs @@ -0,0 +1,50 @@ +using System; + +namespace Newtonsoft.Json +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] + public abstract class JsonContainerAttribute : Attribute + { + internal bool? _isReference; + + public string Id + { + get; + set; + } + + public string Title + { + get; + set; + } + + public string Description + { + get; + set; + } + + public bool IsReference + { + get + { + bool? isReference = _isReference; + return isReference.HasValue && isReference.Value; + } + set + { + _isReference = value; + } + } + + protected JsonContainerAttribute() + { + } + + protected JsonContainerAttribute(string id) + { + Id = id; + } + } +} diff --git a/Newtonsoft.Json/JsonConvert.cs b/Newtonsoft.Json/JsonConvert.cs new file mode 100644 index 00000000..1b837113 --- /dev/null +++ b/Newtonsoft.Json/JsonConvert.cs @@ -0,0 +1,587 @@ +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; +using System.IO; +using System.Text; +using System.Xml; + +namespace Newtonsoft.Json +{ + public static class JsonConvert + { + public static readonly string True = "true"; + + public static readonly string False = "false"; + + public static readonly string Null = "null"; + + public static readonly string Undefined = "undefined"; + + public static readonly string PositiveInfinity = "Infinity"; + + public static readonly string NegativeInfinity = "-Infinity"; + + public static readonly string NaN = "NaN"; + + internal static readonly long InitialJavaScriptDateTicks = 621355968000000000L; + + public static string ToString(DateTime value) + { + using (StringWriter stringWriter = StringUtils.CreateStringWriter(64)) + { + WriteDateTimeString(stringWriter, value, GetUtcOffset(value), value.Kind); + return stringWriter.ToString(); + IL_0028: + string result; + return result; + } + } + + public static string ToString(DateTimeOffset value) + { + using (StringWriter stringWriter = StringUtils.CreateStringWriter(64)) + { + WriteDateTimeString(stringWriter, value.UtcDateTime, value.Offset, DateTimeKind.Local); + return stringWriter.ToString(); + IL_0029: + string result; + return result; + } + } + + private static TimeSpan GetUtcOffset(DateTime dateTime) + { + return TimeZone.CurrentTimeZone.GetUtcOffset(dateTime); + } + + internal static void WriteDateTimeString(TextWriter writer, DateTime value) + { + WriteDateTimeString(writer, value, GetUtcOffset(value), value.Kind); + } + + internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind) + { + long value2 = ConvertDateTimeToJavaScriptTicks(value, offset); + writer.Write("\"\\/Date("); + writer.Write(value2); + switch (kind) + { + case DateTimeKind.Unspecified: + case DateTimeKind.Local: + { + writer.Write((offset.Ticks < 0) ? "-" : "+"); + int num = Math.Abs(offset.Hours); + if (num < 10) + { + writer.Write(0); + } + writer.Write(num); + int num2 = Math.Abs(offset.Minutes); + if (num2 < 10) + { + writer.Write(0); + } + writer.Write(num2); + break; + } + } + writer.Write(")\\/\""); + } + + private static long ToUniversalTicks(DateTime dateTime) + { + if (dateTime.Kind == DateTimeKind.Utc) + { + return dateTime.Ticks; + } + return ToUniversalTicks(dateTime, GetUtcOffset(dateTime)); + } + + private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset) + { + if (dateTime.Kind == DateTimeKind.Utc) + { + return dateTime.Ticks; + } + long num = dateTime.Ticks - offset.Ticks; + if (num > 3155378975999999999L) + { + return 3155378975999999999L; + } + if (num < 0) + { + return 0L; + } + return num; + } + + internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset) + { + long universialTicks = ToUniversalTicks(dateTime, offset); + return UniversialTicksToJavaScriptTicks(universialTicks); + } + + internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime) + { + return ConvertDateTimeToJavaScriptTicks(dateTime, convertToUtc: true); + } + + internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc) + { + long universialTicks = (!convertToUtc) ? dateTime.Ticks : ToUniversalTicks(dateTime); + return UniversialTicksToJavaScriptTicks(universialTicks); + } + + private static long UniversialTicksToJavaScriptTicks(long universialTicks) + { + return (universialTicks - InitialJavaScriptDateTicks) / 10000; + } + + internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks) + { + return new DateTime(javaScriptTicks * 10000 + InitialJavaScriptDateTicks, DateTimeKind.Utc); + } + + public static string ToString(bool value) + { + return (!value) ? False : True; + } + + public static string ToString(char value) + { + return ToString(char.ToString(value)); + } + + public static string ToString(Enum value) + { + return value.ToString("D"); + } + + public static string ToString(int value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(short value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(ushort value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(uint value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(long value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(ulong value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(float value) + { + return EnsureDecimalPlace((double)value, value.ToString("R", CultureInfo.InvariantCulture)); + } + + public static string ToString(double value) + { + return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); + } + + private static string EnsureDecimalPlace(double value, string text) + { + if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1) + { + return text; + } + return text + ".0"; + } + + private static string EnsureDecimalPlace(string text) + { + if (text.IndexOf('.') != -1) + { + return text; + } + return text + ".0"; + } + + public static string ToString(byte value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(sbyte value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } + + public static string ToString(decimal value) + { + return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture)); + } + + public static string ToString(Guid value) + { + return '"' + value.ToString("D", CultureInfo.InvariantCulture) + '"'; + } + + public static string ToString(TimeSpan value) + { + return '"' + value.ToString() + '"'; + } + + public static string ToString(Uri value) + { + return '"' + value.ToString() + '"'; + } + + public static string ToString(string value) + { + return ToString(value, '"'); + } + + public static string ToString(string value, char delimter) + { + return JavaScriptUtils.ToEscapedJavaScriptString(value, delimter, appendDelimiters: true); + } + + public static string ToString(object value) + { + if (value == null) + { + return Null; + } + IConvertible convertible = value as IConvertible; + if (convertible != null) + { + switch (convertible.GetTypeCode()) + { + case TypeCode.String: + return ToString(convertible.ToString(CultureInfo.InvariantCulture)); + case TypeCode.Char: + return ToString(convertible.ToChar(CultureInfo.InvariantCulture)); + case TypeCode.Boolean: + return ToString(convertible.ToBoolean(CultureInfo.InvariantCulture)); + case TypeCode.SByte: + return ToString(convertible.ToSByte(CultureInfo.InvariantCulture)); + case TypeCode.Int16: + return ToString(convertible.ToInt16(CultureInfo.InvariantCulture)); + case TypeCode.UInt16: + return ToString(convertible.ToUInt16(CultureInfo.InvariantCulture)); + case TypeCode.Int32: + return ToString(convertible.ToInt32(CultureInfo.InvariantCulture)); + case TypeCode.Byte: + return ToString(convertible.ToByte(CultureInfo.InvariantCulture)); + case TypeCode.UInt32: + return ToString(convertible.ToUInt32(CultureInfo.InvariantCulture)); + case TypeCode.Int64: + return ToString(convertible.ToInt64(CultureInfo.InvariantCulture)); + case TypeCode.UInt64: + return ToString(convertible.ToUInt64(CultureInfo.InvariantCulture)); + case TypeCode.Single: + return ToString(convertible.ToSingle(CultureInfo.InvariantCulture)); + case TypeCode.Double: + return ToString(convertible.ToDouble(CultureInfo.InvariantCulture)); + case TypeCode.DateTime: + return ToString(convertible.ToDateTime(CultureInfo.InvariantCulture)); + case TypeCode.Decimal: + return ToString(convertible.ToDecimal(CultureInfo.InvariantCulture)); + case TypeCode.DBNull: + return Null; + } + } + else + { + if (value is DateTimeOffset) + { + return ToString((DateTimeOffset)value); + } + if (value is Guid) + { + return ToString((Guid)value); + } + if (value is Uri) + { + return ToString((Uri)value); + } + if (value is TimeSpan) + { + return ToString((TimeSpan)value); + } + } + throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + } + + private static bool IsJsonPrimitiveTypeCode(TypeCode typeCode) + { + switch (typeCode) + { + case TypeCode.DBNull: + case TypeCode.Boolean: + case TypeCode.Char: + case TypeCode.SByte: + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + case TypeCode.DateTime: + case TypeCode.String: + return true; + default: + return false; + } + } + + internal static bool IsJsonPrimitiveType(Type type) + { + if (ReflectionUtils.IsNullableType(type)) + { + type = Nullable.GetUnderlyingType(type); + } + if (type == typeof(DateTimeOffset)) + { + return true; + } + if (type == typeof(byte[])) + { + return true; + } + if (type == typeof(Uri)) + { + return true; + } + if (type == typeof(TimeSpan)) + { + return true; + } + if (type == typeof(Guid)) + { + return true; + } + return IsJsonPrimitiveTypeCode(Type.GetTypeCode(type)); + } + + internal static bool IsJsonPrimitive(object value) + { + if (value == null) + { + return true; + } + IConvertible convertible = value as IConvertible; + if (convertible != null) + { + return IsJsonPrimitiveTypeCode(convertible.GetTypeCode()); + } + if (value is DateTimeOffset) + { + return true; + } + if (value is byte[]) + { + return true; + } + if (value is Uri) + { + return true; + } + if (value is TimeSpan) + { + return true; + } + if (value is Guid) + { + return true; + } + return false; + } + + public static string SerializeObject(object value) + { + return SerializeObject(value, Formatting.None, (JsonSerializerSettings)null); + } + + public static string SerializeObject(object value, Formatting formatting) + { + return SerializeObject(value, formatting, (JsonSerializerSettings)null); + } + + public static string SerializeObject(object value, params JsonConverter[] converters) + { + return SerializeObject(value, Formatting.None, converters); + } + + public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters) + { + object obj; + if (converters != null && converters.Length > 0) + { + JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings(); + jsonSerializerSettings.Converters = converters; + obj = jsonSerializerSettings; + } + else + { + obj = null; + } + JsonSerializerSettings settings = (JsonSerializerSettings)obj; + return SerializeObject(value, formatting, settings); + } + + public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) + { + JsonSerializer jsonSerializer = JsonSerializer.Create(settings); + StringBuilder sb = new StringBuilder(128); + StringWriter stringWriter = new StringWriter(sb, CultureInfo.InvariantCulture); + using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter)) + { + jsonTextWriter.Formatting = formatting; + jsonSerializer.Serialize(jsonTextWriter, value); + } + return stringWriter.ToString(); + } + + public static object DeserializeObject(string value) + { + return DeserializeObject(value, (Type)null, (JsonSerializerSettings)null); + } + + public static object DeserializeObject(string value, JsonSerializerSettings settings) + { + return DeserializeObject(value, null, settings); + } + + public static object DeserializeObject(string value, Type type) + { + return DeserializeObject(value, type, (JsonSerializerSettings)null); + } + + public static T DeserializeObject(string value) + { + return JsonConvert.DeserializeObject(value, (JsonSerializerSettings)null); + } + + public static T DeserializeAnonymousType(string value, T anonymousTypeObject) + { + return DeserializeObject(value); + } + + public static T DeserializeObject(string value, params JsonConverter[] converters) + { + return (T)DeserializeObject(value, typeof(T), converters); + } + + public static T DeserializeObject(string value, JsonSerializerSettings settings) + { + return (T)DeserializeObject(value, typeof(T), settings); + } + + public static object DeserializeObject(string value, Type type, params JsonConverter[] converters) + { + object obj; + if (converters != null && converters.Length > 0) + { + JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings(); + jsonSerializerSettings.Converters = converters; + obj = jsonSerializerSettings; + } + else + { + obj = null; + } + JsonSerializerSettings settings = (JsonSerializerSettings)obj; + return DeserializeObject(value, type, settings); + } + + public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings) + { + StringReader reader = new StringReader(value); + JsonSerializer jsonSerializer = JsonSerializer.Create(settings); + using (JsonReader jsonReader = new JsonTextReader(reader)) + { + object result = jsonSerializer.Deserialize(jsonReader, type); + if (!jsonReader.Read()) + { + return result; + } + if (jsonReader.TokenType != JsonToken.Comment) + { + throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); + } + return result; + } + } + + public static void PopulateObject(string value, object target) + { + PopulateObject(value, target, null); + } + + public static void PopulateObject(string value, object target, JsonSerializerSettings settings) + { + StringReader reader = new StringReader(value); + JsonSerializer jsonSerializer = JsonSerializer.Create(settings); + using (JsonReader jsonReader = new JsonTextReader(reader)) + { + jsonSerializer.Populate(jsonReader, target); + if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment) + { + throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); + } + } + } + + public static string SerializeXmlNode(XmlNode node) + { + return SerializeXmlNode(node, Formatting.None); + } + + public static string SerializeXmlNode(XmlNode node, Formatting formatting) + { + XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); + return SerializeObject(node, formatting, xmlNodeConverter); + } + + public static string SerializeXmlNode(XmlNode node, Formatting formatting, bool omitRootObject) + { + XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); + xmlNodeConverter.OmitRootObject = omitRootObject; + XmlNodeConverter xmlNodeConverter2 = xmlNodeConverter; + return SerializeObject(node, formatting, xmlNodeConverter2); + } + + public static XmlDocument DeserializeXmlNode(string value) + { + return DeserializeXmlNode(value, null); + } + + public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName) + { + return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false); + } + + public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute) + { + XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); + xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName; + xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute; + return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter); + } + } +} diff --git a/Newtonsoft.Json/JsonConverter.cs b/Newtonsoft.Json/JsonConverter.cs new file mode 100644 index 00000000..40e4b8d2 --- /dev/null +++ b/Newtonsoft.Json/JsonConverter.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json.Schema; +using System; + +namespace Newtonsoft.Json +{ + public abstract class JsonConverter + { + public virtual bool CanRead => true; + + public virtual bool CanWrite => true; + + public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer); + + public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer); + + public abstract bool CanConvert(Type objectType); + + public virtual JsonSchema GetSchema() + { + return null; + } + } +} diff --git a/Newtonsoft.Json/JsonConverterAttribute.cs b/Newtonsoft.Json/JsonConverterAttribute.cs new file mode 100644 index 00000000..a17f9540 --- /dev/null +++ b/Newtonsoft.Json/JsonConverterAttribute.cs @@ -0,0 +1,41 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Globalization; + +namespace Newtonsoft.Json +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)] + public sealed class JsonConverterAttribute : Attribute + { + private readonly Type _converterType; + + public Type ConverterType => _converterType; + + public JsonConverterAttribute(Type converterType) + { + if (converterType == null) + { + throw new ArgumentNullException("converterType"); + } + _converterType = converterType; + } + + internal static JsonConverter CreateJsonConverterInstance(Type converterType) + { + try + { + return (JsonConverter)Activator.CreateInstance(converterType); + IL_0011: + JsonConverter result; + return result; + } + catch (Exception innerException) + { + throw new Exception("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, converterType), innerException); + IL_0037: + JsonConverter result; + return result; + } + } + } +} diff --git a/Newtonsoft.Json/JsonConverterCollection.cs b/Newtonsoft.Json/JsonConverterCollection.cs new file mode 100644 index 00000000..96609812 --- /dev/null +++ b/Newtonsoft.Json/JsonConverterCollection.cs @@ -0,0 +1,8 @@ +using System.Collections.ObjectModel; + +namespace Newtonsoft.Json +{ + public class JsonConverterCollection : Collection + { + } +} diff --git a/Newtonsoft.Json/JsonIgnoreAttribute.cs b/Newtonsoft.Json/JsonIgnoreAttribute.cs new file mode 100644 index 00000000..c43cc12d --- /dev/null +++ b/Newtonsoft.Json/JsonIgnoreAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Newtonsoft.Json +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class JsonIgnoreAttribute : Attribute + { + } +} diff --git a/Newtonsoft.Json/JsonObjectAttribute.cs b/Newtonsoft.Json/JsonObjectAttribute.cs new file mode 100644 index 00000000..ce435d38 --- /dev/null +++ b/Newtonsoft.Json/JsonObjectAttribute.cs @@ -0,0 +1,36 @@ +using System; + +namespace Newtonsoft.Json +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] + public sealed class JsonObjectAttribute : JsonContainerAttribute + { + private MemberSerialization _memberSerialization; + + public MemberSerialization MemberSerialization + { + get + { + return _memberSerialization; + } + set + { + _memberSerialization = value; + } + } + + public JsonObjectAttribute() + { + } + + public JsonObjectAttribute(MemberSerialization memberSerialization) + { + MemberSerialization = memberSerialization; + } + + public JsonObjectAttribute(string id) + : base(id) + { + } + } +} diff --git a/Newtonsoft.Json/JsonPropertyAttribute.cs b/Newtonsoft.Json/JsonPropertyAttribute.cs new file mode 100644 index 00000000..fa04a2c6 --- /dev/null +++ b/Newtonsoft.Json/JsonPropertyAttribute.cs @@ -0,0 +1,134 @@ +using System; + +namespace Newtonsoft.Json +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] + public sealed class JsonPropertyAttribute : Attribute + { + internal NullValueHandling? _nullValueHandling; + + internal DefaultValueHandling? _defaultValueHandling; + + internal ReferenceLoopHandling? _referenceLoopHandling; + + internal ObjectCreationHandling? _objectCreationHandling; + + internal TypeNameHandling? _typeNameHandling; + + internal bool? _isReference; + + internal int? _order; + + public NullValueHandling NullValueHandling + { + get + { + NullValueHandling? nullValueHandling = _nullValueHandling; + return nullValueHandling.HasValue ? nullValueHandling.Value : NullValueHandling.Include; + } + set + { + _nullValueHandling = value; + } + } + + public DefaultValueHandling DefaultValueHandling + { + get + { + DefaultValueHandling? defaultValueHandling = _defaultValueHandling; + return defaultValueHandling.HasValue ? defaultValueHandling.Value : DefaultValueHandling.Include; + } + set + { + _defaultValueHandling = value; + } + } + + public ReferenceLoopHandling ReferenceLoopHandling + { + get + { + ReferenceLoopHandling? referenceLoopHandling = _referenceLoopHandling; + return referenceLoopHandling.HasValue ? referenceLoopHandling.Value : ReferenceLoopHandling.Error; + } + set + { + _referenceLoopHandling = value; + } + } + + public ObjectCreationHandling ObjectCreationHandling + { + get + { + ObjectCreationHandling? objectCreationHandling = _objectCreationHandling; + return objectCreationHandling.HasValue ? objectCreationHandling.Value : ObjectCreationHandling.Auto; + } + set + { + _objectCreationHandling = value; + } + } + + public TypeNameHandling TypeNameHandling + { + get + { + TypeNameHandling? typeNameHandling = _typeNameHandling; + return typeNameHandling.HasValue ? typeNameHandling.Value : TypeNameHandling.None; + } + set + { + _typeNameHandling = value; + } + } + + public bool IsReference + { + get + { + bool? isReference = _isReference; + return isReference.HasValue && isReference.Value; + } + set + { + _isReference = value; + } + } + + public int Order + { + get + { + int? order = _order; + return order.HasValue ? order.Value : 0; + } + set + { + _order = value; + } + } + + public string PropertyName + { + get; + set; + } + + public Required Required + { + get; + set; + } + + public JsonPropertyAttribute() + { + } + + public JsonPropertyAttribute(string propertyName) + { + PropertyName = propertyName; + } + } +} diff --git a/Newtonsoft.Json/JsonReader.cs b/Newtonsoft.Json/JsonReader.cs new file mode 100644 index 00000000..be7fbae7 --- /dev/null +++ b/Newtonsoft.Json/JsonReader.cs @@ -0,0 +1,312 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Newtonsoft.Json +{ + public abstract class JsonReader : IDisposable + { + protected enum State + { + Start, + Complete, + Property, + ObjectStart, + Object, + ArrayStart, + Array, + Closed, + PostValue, + ConstructorStart, + Constructor, + Error, + Finished + } + + private JsonToken _token; + + private object _value; + + private Type _valueType; + + private char _quoteChar; + + private State _currentState; + + private JTokenType _currentTypeContext; + + private int _top; + + private readonly List _stack; + + protected State CurrentState => _currentState; + + public bool CloseInput + { + get; + set; + } + + public virtual char QuoteChar + { + get + { + return _quoteChar; + } + protected internal set + { + _quoteChar = value; + } + } + + public virtual JsonToken TokenType => _token; + + public virtual object Value => _value; + + public virtual Type ValueType => _valueType; + + public virtual int Depth + { + get + { + int num = _top - 1; + if (IsStartToken(TokenType)) + { + return num - 1; + } + return num; + } + } + + protected JsonReader() + { + _currentState = State.Start; + _stack = new List(); + CloseInput = true; + Push(JTokenType.None); + } + + void IDisposable.Dispose() + { + Dispose(disposing: true); + } + + private void Push(JTokenType value) + { + _stack.Add(value); + _top++; + _currentTypeContext = value; + } + + private JTokenType Pop() + { + JTokenType result = Peek(); + _stack.RemoveAt(_stack.Count - 1); + _top--; + _currentTypeContext = _stack[_top - 1]; + return result; + } + + private JTokenType Peek() + { + return _currentTypeContext; + } + + public abstract bool Read(); + + public abstract byte[] ReadAsBytes(); + + public abstract decimal? ReadAsDecimal(); + + public abstract DateTimeOffset? ReadAsDateTimeOffset(); + + public void Skip() + { + if (IsStartToken(TokenType)) + { + int depth = Depth; + while (Read() && depth < Depth) + { + } + } + } + + protected void SetToken(JsonToken newToken) + { + SetToken(newToken, null); + } + + protected virtual void SetToken(JsonToken newToken, object value) + { + _token = newToken; + switch (newToken) + { + case JsonToken.StartObject: + _currentState = State.ObjectStart; + Push(JTokenType.Object); + break; + case JsonToken.StartArray: + _currentState = State.ArrayStart; + Push(JTokenType.Array); + break; + case JsonToken.StartConstructor: + _currentState = State.ConstructorStart; + Push(JTokenType.Constructor); + break; + case JsonToken.EndObject: + ValidateEnd(JsonToken.EndObject); + _currentState = State.PostValue; + break; + case JsonToken.EndArray: + ValidateEnd(JsonToken.EndArray); + _currentState = State.PostValue; + break; + case JsonToken.EndConstructor: + ValidateEnd(JsonToken.EndConstructor); + _currentState = State.PostValue; + break; + case JsonToken.PropertyName: + _currentState = State.Property; + Push(JTokenType.Property); + break; + case JsonToken.Raw: + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Null: + case JsonToken.Undefined: + case JsonToken.Date: + case JsonToken.Bytes: + _currentState = State.PostValue; + break; + } + JTokenType jTokenType = Peek(); + if (jTokenType == JTokenType.Property && _currentState == State.PostValue) + { + Pop(); + } + if (value != null) + { + _value = value; + _valueType = value.GetType(); + } + else + { + _value = null; + _valueType = null; + } + } + + private void ValidateEnd(JsonToken endToken) + { + JTokenType jTokenType = Pop(); + if (GetTypeForCloseToken(endToken) != jTokenType) + { + throw new JsonReaderException("JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jTokenType)); + } + } + + protected void SetStateBasedOnCurrent() + { + JTokenType jTokenType = Peek(); + switch (jTokenType) + { + case JTokenType.Object: + _currentState = State.Object; + break; + case JTokenType.Array: + _currentState = State.Array; + break; + case JTokenType.Constructor: + _currentState = State.Constructor; + break; + case JTokenType.None: + _currentState = State.Finished; + break; + default: + throw new JsonReaderException("While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jTokenType)); + } + } + + internal static bool IsPrimitiveToken(JsonToken token) + { + switch (token) + { + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Null: + case JsonToken.Undefined: + case JsonToken.Date: + case JsonToken.Bytes: + return true; + default: + return false; + } + } + + internal static bool IsStartToken(JsonToken token) + { + switch (token) + { + case JsonToken.StartObject: + case JsonToken.StartArray: + case JsonToken.StartConstructor: + case JsonToken.PropertyName: + return true; + case JsonToken.None: + case JsonToken.Comment: + case JsonToken.Raw: + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Null: + case JsonToken.Undefined: + case JsonToken.EndObject: + case JsonToken.EndArray: + case JsonToken.EndConstructor: + case JsonToken.Date: + case JsonToken.Bytes: + return false; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("token", token, "Unexpected JsonToken value."); + } + } + + private JTokenType GetTypeForCloseToken(JsonToken token) + { + switch (token) + { + case JsonToken.EndObject: + return JTokenType.Object; + case JsonToken.EndArray: + return JTokenType.Array; + case JsonToken.EndConstructor: + return JTokenType.Constructor; + default: + throw new JsonReaderException("Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)); + } + } + + protected virtual void Dispose(bool disposing) + { + if (_currentState != State.Closed && disposing) + { + Close(); + } + } + + public virtual void Close() + { + _currentState = State.Closed; + _token = JsonToken.None; + _value = null; + _valueType = null; + } + } +} diff --git a/Newtonsoft.Json/JsonReaderException.cs b/Newtonsoft.Json/JsonReaderException.cs new file mode 100644 index 00000000..082fa599 --- /dev/null +++ b/Newtonsoft.Json/JsonReaderException.cs @@ -0,0 +1,47 @@ +using System; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json +{ + [Serializable] + public class JsonReaderException : Exception + { + public int LineNumber + { + get; + private set; + } + + public int LinePosition + { + get; + private set; + } + + public JsonReaderException() + { + } + + public JsonReaderException(string message) + : base(message) + { + } + + public JsonReaderException(string message, Exception innerException) + : base(message, innerException) + { + } + + public JsonReaderException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + internal JsonReaderException(string message, Exception innerException, int lineNumber, int linePosition) + : base(message, innerException) + { + LineNumber = lineNumber; + LinePosition = linePosition; + } + } +} diff --git a/Newtonsoft.Json/JsonSerializationException.cs b/Newtonsoft.Json/JsonSerializationException.cs new file mode 100644 index 00000000..8cd3a841 --- /dev/null +++ b/Newtonsoft.Json/JsonSerializationException.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json +{ + [Serializable] + public class JsonSerializationException : Exception + { + public JsonSerializationException() + { + } + + public JsonSerializationException(string message) + : base(message) + { + } + + public JsonSerializationException(string message, Exception innerException) + : base(message, innerException) + { + } + + public JsonSerializationException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/Newtonsoft.Json/JsonSerializer.cs b/Newtonsoft.Json/JsonSerializer.cs new file mode 100644 index 00000000..596d3133 --- /dev/null +++ b/Newtonsoft.Json/JsonSerializer.cs @@ -0,0 +1,406 @@ +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters; + +namespace Newtonsoft.Json +{ + public class JsonSerializer + { + private TypeNameHandling _typeNameHandling; + + private FormatterAssemblyStyle _typeNameAssemblyFormat; + + private PreserveReferencesHandling _preserveReferencesHandling; + + private ReferenceLoopHandling _referenceLoopHandling; + + private MissingMemberHandling _missingMemberHandling; + + private ObjectCreationHandling _objectCreationHandling; + + private NullValueHandling _nullValueHandling; + + private DefaultValueHandling _defaultValueHandling; + + private ConstructorHandling _constructorHandling; + + private JsonConverterCollection _converters; + + private IContractResolver _contractResolver; + + private IReferenceResolver _referenceResolver; + + private SerializationBinder _binder; + + private StreamingContext _context; + + public virtual IReferenceResolver ReferenceResolver + { + get + { + if (_referenceResolver == null) + { + _referenceResolver = new DefaultReferenceResolver(); + } + return _referenceResolver; + } + set + { + if (value == null) + { + throw new ArgumentNullException("value", "Reference resolver cannot be null."); + } + _referenceResolver = value; + } + } + + public virtual SerializationBinder Binder + { + get + { + return _binder; + } + set + { + if (value == null) + { + throw new ArgumentNullException("value", "Serialization binder cannot be null."); + } + _binder = value; + } + } + + public virtual TypeNameHandling TypeNameHandling + { + get + { + return _typeNameHandling; + } + set + { + if (value < TypeNameHandling.None || value > TypeNameHandling.Auto) + { + throw new ArgumentOutOfRangeException("value"); + } + _typeNameHandling = value; + } + } + + public virtual FormatterAssemblyStyle TypeNameAssemblyFormat + { + get + { + return _typeNameAssemblyFormat; + } + set + { + if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) + { + throw new ArgumentOutOfRangeException("value"); + } + _typeNameAssemblyFormat = value; + } + } + + public virtual PreserveReferencesHandling PreserveReferencesHandling + { + get + { + return _preserveReferencesHandling; + } + set + { + if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All) + { + throw new ArgumentOutOfRangeException("value"); + } + _preserveReferencesHandling = value; + } + } + + public virtual ReferenceLoopHandling ReferenceLoopHandling + { + get + { + return _referenceLoopHandling; + } + set + { + if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize) + { + throw new ArgumentOutOfRangeException("value"); + } + _referenceLoopHandling = value; + } + } + + public virtual MissingMemberHandling MissingMemberHandling + { + get + { + return _missingMemberHandling; + } + set + { + if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error) + { + throw new ArgumentOutOfRangeException("value"); + } + _missingMemberHandling = value; + } + } + + public virtual NullValueHandling NullValueHandling + { + get + { + return _nullValueHandling; + } + set + { + if (value < NullValueHandling.Include || value > NullValueHandling.Ignore) + { + throw new ArgumentOutOfRangeException("value"); + } + _nullValueHandling = value; + } + } + + public virtual DefaultValueHandling DefaultValueHandling + { + get + { + return _defaultValueHandling; + } + set + { + if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate) + { + throw new ArgumentOutOfRangeException("value"); + } + _defaultValueHandling = value; + } + } + + public virtual ObjectCreationHandling ObjectCreationHandling + { + get + { + return _objectCreationHandling; + } + set + { + if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace) + { + throw new ArgumentOutOfRangeException("value"); + } + _objectCreationHandling = value; + } + } + + public virtual ConstructorHandling ConstructorHandling + { + get + { + return _constructorHandling; + } + set + { + if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor) + { + throw new ArgumentOutOfRangeException("value"); + } + _constructorHandling = value; + } + } + + public virtual JsonConverterCollection Converters + { + get + { + if (_converters == null) + { + _converters = new JsonConverterCollection(); + } + return _converters; + } + } + + public virtual IContractResolver ContractResolver + { + get + { + if (_contractResolver == null) + { + _contractResolver = DefaultContractResolver.Instance; + } + return _contractResolver; + } + set + { + _contractResolver = value; + } + } + + public virtual StreamingContext Context + { + get + { + return _context; + } + set + { + _context = value; + } + } + + public virtual event EventHandler Error; + + public JsonSerializer() + { + _referenceLoopHandling = ReferenceLoopHandling.Error; + _missingMemberHandling = MissingMemberHandling.Ignore; + _nullValueHandling = NullValueHandling.Include; + _defaultValueHandling = DefaultValueHandling.Include; + _objectCreationHandling = ObjectCreationHandling.Auto; + _preserveReferencesHandling = PreserveReferencesHandling.None; + _constructorHandling = ConstructorHandling.Default; + _typeNameHandling = TypeNameHandling.None; + _context = JsonSerializerSettings.DefaultContext; + _binder = DefaultSerializationBinder.Instance; + } + + public static JsonSerializer Create(JsonSerializerSettings settings) + { + JsonSerializer jsonSerializer = new JsonSerializer(); + if (settings != null) + { + if (!CollectionUtils.IsNullOrEmpty(settings.Converters)) + { + jsonSerializer.Converters.AddRange(settings.Converters); + } + jsonSerializer.TypeNameHandling = settings.TypeNameHandling; + jsonSerializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat; + jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; + jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; + jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling; + jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling; + jsonSerializer.NullValueHandling = settings.NullValueHandling; + jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling; + jsonSerializer.ConstructorHandling = settings.ConstructorHandling; + jsonSerializer.Context = settings.Context; + if (settings.Error != null) + { + JsonSerializer jsonSerializer2 = jsonSerializer; + jsonSerializer2.Error = (EventHandler)Delegate.Combine(jsonSerializer2.Error, settings.Error); + } + if (settings.ContractResolver != null) + { + jsonSerializer.ContractResolver = settings.ContractResolver; + } + if (settings.ReferenceResolver != null) + { + jsonSerializer.ReferenceResolver = settings.ReferenceResolver; + } + if (settings.Binder != null) + { + jsonSerializer.Binder = settings.Binder; + } + } + return jsonSerializer; + } + + public void Populate(TextReader reader, object target) + { + Populate(new JsonTextReader(reader), target); + } + + public void Populate(JsonReader reader, object target) + { + PopulateInternal(reader, target); + } + + internal virtual void PopulateInternal(JsonReader reader, object target) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + ValidationUtils.ArgumentNotNull(target, "target"); + JsonSerializerInternalReader jsonSerializerInternalReader = new JsonSerializerInternalReader(this); + jsonSerializerInternalReader.Populate(reader, target); + } + + public object Deserialize(JsonReader reader) + { + return Deserialize(reader, null); + } + + public object Deserialize(TextReader reader, Type objectType) + { + return Deserialize(new JsonTextReader(reader), objectType); + } + + public T Deserialize(JsonReader reader) + { + return (T)Deserialize(reader, typeof(T)); + } + + public object Deserialize(JsonReader reader, Type objectType) + { + return DeserializeInternal(reader, objectType); + } + + internal virtual object DeserializeInternal(JsonReader reader, Type objectType) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + JsonSerializerInternalReader jsonSerializerInternalReader = new JsonSerializerInternalReader(this); + return jsonSerializerInternalReader.Deserialize(reader, objectType); + } + + public void Serialize(TextWriter textWriter, object value) + { + Serialize(new JsonTextWriter(textWriter), value); + } + + public void Serialize(JsonWriter jsonWriter, object value) + { + SerializeInternal(jsonWriter, value); + } + + internal virtual void SerializeInternal(JsonWriter jsonWriter, object value) + { + ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); + JsonSerializerInternalWriter jsonSerializerInternalWriter = new JsonSerializerInternalWriter(this); + jsonSerializerInternalWriter.Serialize(jsonWriter, value); + } + + internal JsonConverter GetMatchingConverter(Type type) + { + return GetMatchingConverter(_converters, type); + } + + internal static JsonConverter GetMatchingConverter(IList converters, Type objectType) + { + ValidationUtils.ArgumentNotNull(objectType, "objectType"); + if (converters != null) + { + for (int i = 0; i < converters.Count; i++) + { + JsonConverter jsonConverter = converters[i]; + if (jsonConverter.CanConvert(objectType)) + { + return jsonConverter; + } + } + } + return null; + } + + internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e) + { + this.Error?.Invoke(this, e); + } + } +} diff --git a/Newtonsoft.Json/JsonSerializerSettings.cs b/Newtonsoft.Json/JsonSerializerSettings.cs new file mode 100644 index 00000000..cdc20d06 --- /dev/null +++ b/Newtonsoft.Json/JsonSerializerSettings.cs @@ -0,0 +1,135 @@ +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters; + +namespace Newtonsoft.Json +{ + public class JsonSerializerSettings + { + internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error; + + internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore; + + internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include; + + internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include; + + internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto; + + internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None; + + internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default; + + internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None; + + internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple; + + internal static readonly StreamingContext DefaultContext = default(StreamingContext); + + public ReferenceLoopHandling ReferenceLoopHandling + { + get; + set; + } + + public MissingMemberHandling MissingMemberHandling + { + get; + set; + } + + public ObjectCreationHandling ObjectCreationHandling + { + get; + set; + } + + public NullValueHandling NullValueHandling + { + get; + set; + } + + public DefaultValueHandling DefaultValueHandling + { + get; + set; + } + + public IList Converters + { + get; + set; + } + + public PreserveReferencesHandling PreserveReferencesHandling + { + get; + set; + } + + public TypeNameHandling TypeNameHandling + { + get; + set; + } + + public FormatterAssemblyStyle TypeNameAssemblyFormat + { + get; + set; + } + + public ConstructorHandling ConstructorHandling + { + get; + set; + } + + public IContractResolver ContractResolver + { + get; + set; + } + + public IReferenceResolver ReferenceResolver + { + get; + set; + } + + public SerializationBinder Binder + { + get; + set; + } + + public EventHandler Error + { + get; + set; + } + + public StreamingContext Context + { + get; + set; + } + + public JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Error; + MissingMemberHandling = MissingMemberHandling.Ignore; + ObjectCreationHandling = ObjectCreationHandling.Auto; + NullValueHandling = NullValueHandling.Include; + DefaultValueHandling = DefaultValueHandling.Include; + PreserveReferencesHandling = PreserveReferencesHandling.None; + TypeNameHandling = TypeNameHandling.None; + TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple; + Context = DefaultContext; + Converters = new List(); + } + } +} diff --git a/Newtonsoft.Json/JsonTextReader.cs b/Newtonsoft.Json/JsonTextReader.cs new file mode 100644 index 00000000..8752be3e --- /dev/null +++ b/Newtonsoft.Json/JsonTextReader.cs @@ -0,0 +1,929 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; + +namespace Newtonsoft.Json +{ + public class JsonTextReader : JsonReader, IJsonLineInfo + { + private enum ReadType + { + Read, + ReadAsBytes, + ReadAsDecimal, + ReadAsDateTimeOffset + } + + private const int LineFeedValue = 10; + + private const int CarriageReturnValue = 13; + + private readonly TextReader _reader; + + private readonly StringBuffer _buffer; + + private char? _lastChar; + + private int _currentLinePosition; + + private int _currentLineNumber; + + private bool _end; + + private ReadType _readType; + + private CultureInfo _culture; + + public CultureInfo Culture + { + get + { + return _culture ?? CultureInfo.CurrentCulture; + } + set + { + _culture = value; + } + } + + public int LineNumber + { + get + { + if (base.CurrentState == State.Start) + { + return 0; + } + return _currentLineNumber; + } + } + + public int LinePosition => _currentLinePosition; + + public JsonTextReader(TextReader reader) + { + if (reader == null) + { + throw new ArgumentNullException("reader"); + } + _reader = reader; + _buffer = new StringBuffer(4096); + _currentLineNumber = 1; + } + + private void ParseString(char quote) + { + ReadStringIntoBuffer(quote); + if (_readType == ReadType.ReadAsBytes) + { + byte[] value; + if (_buffer.Position == 0) + { + value = new byte[0]; + } + else + { + value = Convert.FromBase64CharArray(_buffer.GetInternalBuffer(), 0, _buffer.Position); + _buffer.Position = 0; + } + SetToken(JsonToken.Bytes, value); + } + else + { + string text = _buffer.ToString(); + _buffer.Position = 0; + if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal)) + { + ParseDate(text); + } + else + { + SetToken(JsonToken.String, text); + QuoteChar = quote; + } + } + } + + private void ReadStringIntoBuffer(char quote) + { + while (true) + { + char c = MoveNext(); + switch (c) + { + case '\0': + if (_end) + { + throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition); + } + _buffer.Append('\0'); + break; + case '\\': + if ((c = MoveNext()) == '\0' && _end) + { + throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition); + } + switch (c) + { + case 'b': + _buffer.Append('\b'); + break; + case 't': + _buffer.Append('\t'); + break; + case 'n': + _buffer.Append('\n'); + break; + case 'f': + _buffer.Append('\f'); + break; + case 'r': + _buffer.Append('\r'); + break; + case '\\': + _buffer.Append('\\'); + break; + case '"': + case '\'': + case '/': + _buffer.Append(c); + break; + case 'u': + { + char[] array = new char[4]; + for (int i = 0; i < array.Length; i++) + { + if ((c = MoveNext()) == '\0' && _end) + { + throw CreateJsonReaderException("Unexpected end while parsing unicode character. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + array[i] = c; + } + char value = Convert.ToChar(int.Parse(new string(array), NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo)); + _buffer.Append(value); + break; + } + default: + throw CreateJsonReaderException("Bad JSON escape sequence: {0}. Line {1}, position {2}.", "\\" + c, _currentLineNumber, _currentLinePosition); + } + break; + case '"': + case '\'': + if (c == quote) + { + return; + } + _buffer.Append(c); + break; + default: + _buffer.Append(c); + break; + } + } + } + + private JsonReaderException CreateJsonReaderException(string format, params object[] args) + { + string message = format.FormatWith(CultureInfo.InvariantCulture, args); + return new JsonReaderException(message, null, _currentLineNumber, _currentLinePosition); + } + + private TimeSpan ReadOffset(string offsetText) + { + bool flag = offsetText[0] == '-'; + int num = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture); + int num2 = 0; + if (offsetText.Length >= 5) + { + num2 = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture); + } + TimeSpan result = TimeSpan.FromHours((double)num) + TimeSpan.FromMinutes((double)num2); + if (flag) + { + result = result.Negate(); + } + return result; + } + + private void ParseDate(string text) + { + string text2 = text.Substring(6, text.Length - 8); + DateTimeKind dateTimeKind = DateTimeKind.Utc; + int num = text2.IndexOf('+', 1); + if (num == -1) + { + num = text2.IndexOf('-', 1); + } + TimeSpan timeSpan = TimeSpan.Zero; + if (num != -1) + { + dateTimeKind = DateTimeKind.Local; + timeSpan = ReadOffset(text2.Substring(num)); + text2 = text2.Substring(0, num); + } + long javaScriptTicks = long.Parse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture); + DateTime dateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks); + if (_readType == ReadType.ReadAsDateTimeOffset) + { + SetToken(JsonToken.Date, new DateTimeOffset(dateTime.Add(timeSpan).Ticks, timeSpan)); + } + else + { + DateTime dateTime2; + switch (dateTimeKind) + { + case DateTimeKind.Unspecified: + dateTime2 = DateTime.SpecifyKind(dateTime.ToLocalTime(), DateTimeKind.Unspecified); + break; + case DateTimeKind.Local: + dateTime2 = dateTime.ToLocalTime(); + break; + default: + dateTime2 = dateTime; + break; + } + SetToken(JsonToken.Date, dateTime2); + } + } + + private char MoveNext() + { + int num = _reader.Read(); + switch (num) + { + case -1: + _end = true; + return '\0'; + case 13: + if (_reader.Peek() == 10) + { + _reader.Read(); + } + _currentLineNumber++; + _currentLinePosition = 0; + break; + case 10: + _currentLineNumber++; + _currentLinePosition = 0; + break; + default: + _currentLinePosition++; + break; + } + return (char)num; + } + + private bool HasNext() + { + return _reader.Peek() != -1; + } + + private int PeekNext() + { + return _reader.Peek(); + } + + public override bool Read() + { + _readType = ReadType.Read; + return ReadInternal(); + } + + public override byte[] ReadAsBytes() + { + _readType = ReadType.ReadAsBytes; + do + { + if (!ReadInternal()) + { + throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + } + while (TokenType == JsonToken.Comment); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Bytes) + { + return (byte[])Value; + } + if (TokenType == JsonToken.StartArray) + { + List list = new List(); + while (ReadInternal()) + { + switch (TokenType) + { + case JsonToken.Integer: + list.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.EndArray: + { + byte[] array = list.ToArray(); + SetToken(JsonToken.Bytes, array); + return array; + } + default: + throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition); + case JsonToken.Comment: + break; + } + } + throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition); + } + + public override decimal? ReadAsDecimal() + { + _readType = ReadType.ReadAsDecimal; + do + { + if (!ReadInternal()) + { + throw CreateJsonReaderException("Unexpected end when reading decimal: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + } + while (TokenType == JsonToken.Comment); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Float) + { + return (decimal?)Value; + } + if (TokenType == JsonToken.String && decimal.TryParse((string)Value, NumberStyles.Number, Culture, out decimal result)) + { + SetToken(JsonToken.Float, result); + return result; + } + throw CreateJsonReaderException("Unexpected token when reading decimal: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition); + } + + public override DateTimeOffset? ReadAsDateTimeOffset() + { + _readType = ReadType.ReadAsDateTimeOffset; + do + { + if (!ReadInternal()) + { + throw CreateJsonReaderException("Unexpected end when reading date: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + } + while (TokenType == JsonToken.Comment); + if (TokenType == JsonToken.Null) + { + return null; + } + if (TokenType == JsonToken.Date) + { + return (DateTimeOffset)Value; + } + if (TokenType == JsonToken.String && DateTimeOffset.TryParse((string)Value, Culture, DateTimeStyles.None, out DateTimeOffset result)) + { + SetToken(JsonToken.Date, result); + return result; + } + throw CreateJsonReaderException("Unexpected token when reading date: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition); + } + + private bool ReadInternal() + { + while (true) + { + char? lastChar = _lastChar; + char c; + if (lastChar.HasValue) + { + c = _lastChar.Value; + _lastChar = null; + } + else + { + c = MoveNext(); + } + if (c == '\0' && _end) + { + break; + } + switch (base.CurrentState) + { + case State.Complete: + case State.Closed: + case State.Error: + break; + case State.Start: + case State.Property: + case State.ArrayStart: + case State.Array: + case State.ConstructorStart: + case State.Constructor: + return ParseValue(c); + case State.ObjectStart: + case State.Object: + return ParseObject(c); + case State.PostValue: + if (ParsePostValue(c)) + { + return true; + } + break; + default: + throw CreateJsonReaderException("Unexpected state: {0}. Line {1}, position {2}.", base.CurrentState, _currentLineNumber, _currentLinePosition); + } + } + return false; + } + + private bool ParsePostValue(char currentChar) + { + do + { + switch (currentChar) + { + case '}': + SetToken(JsonToken.EndObject); + return true; + case ']': + SetToken(JsonToken.EndArray); + return true; + case ')': + SetToken(JsonToken.EndConstructor); + return true; + case '/': + ParseComment(); + return true; + case ',': + SetStateBasedOnCurrent(); + return false; + default: + if (!char.IsWhiteSpace(currentChar)) + { + throw CreateJsonReaderException("After parsing a value an unexpected character was encountered: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition); + } + break; + case '\t': + case '\n': + case '\r': + case ' ': + break; + } + } + while ((currentChar = MoveNext()) != 0 || !_end); + return false; + } + + private bool ParseObject(char currentChar) + { + do + { + switch (currentChar) + { + case '}': + SetToken(JsonToken.EndObject); + return true; + case '/': + ParseComment(); + return true; + default: + if (!char.IsWhiteSpace(currentChar)) + { + return ParseProperty(currentChar); + } + break; + case '\t': + case '\n': + case '\r': + case ' ': + break; + } + } + while ((currentChar = MoveNext()) != 0 || !_end); + return false; + } + + private bool ParseProperty(char firstChar) + { + char c = firstChar; + char c2; + if (ValidIdentifierChar(c)) + { + c2 = '\0'; + c = ParseUnquotedProperty(c); + } + else + { + if (c != '"' && c != '\'') + { + throw CreateJsonReaderException("Invalid property identifier character: {0}. Line {1}, position {2}.", c, _currentLineNumber, _currentLinePosition); + } + c2 = c; + ReadStringIntoBuffer(c2); + c = MoveNext(); + } + if (c != ':') + { + c = MoveNext(); + EatWhitespace(c, /*oneOrMore:*/ false, out c); + if (c != ':') + { + throw CreateJsonReaderException("Invalid character after parsing property name. Expected ':' but got: {0}. Line {1}, position {2}.", c, _currentLineNumber, _currentLinePosition); + } + } + SetToken(JsonToken.PropertyName, _buffer.ToString()); + QuoteChar = c2; + _buffer.Position = 0; + return true; + } + + private bool ValidIdentifierChar(char value) + { + return char.IsLetterOrDigit(value) || value == '_' || value == '$'; + } + + private char ParseUnquotedProperty(char firstChar) + { + _buffer.Append(firstChar); + char c; + while ((c = MoveNext()) != 0 || !_end) + { + if (char.IsWhiteSpace(c) || c == ':') + { + return c; + } + if (!ValidIdentifierChar(c)) + { + throw CreateJsonReaderException("Invalid JavaScript property identifier character: {0}. Line {1}, position {2}.", c, _currentLineNumber, _currentLinePosition); + } + _buffer.Append(c); + } + throw CreateJsonReaderException("Unexpected end when parsing unquoted property name. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + + private bool ParseValue(char currentChar) + { + do + { + switch (currentChar) + { + case '"': + case '\'': + ParseString(currentChar); + return true; + case 't': + ParseTrue(); + return true; + case 'f': + ParseFalse(); + return true; + case 'n': + if (!HasNext()) + { + throw CreateJsonReaderException("Unexpected end. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + switch ((ushort)PeekNext()) + { + case 117: + ParseNull(); + break; + case 101: + ParseConstructor(); + break; + default: + throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition); + } + return true; + case 'N': + ParseNumberNaN(); + return true; + case 'I': + ParseNumberPositiveInfinity(); + return true; + case '-': + if (PeekNext() == 73) + { + ParseNumberNegativeInfinity(); + } + else + { + ParseNumber(currentChar); + } + return true; + case '/': + ParseComment(); + return true; + case 'u': + ParseUndefined(); + return true; + case '{': + SetToken(JsonToken.StartObject); + return true; + case '[': + SetToken(JsonToken.StartArray); + return true; + case '}': + SetToken(JsonToken.EndObject); + return true; + case ']': + SetToken(JsonToken.EndArray); + return true; + case ',': + SetToken(JsonToken.Undefined); + return true; + case ')': + SetToken(JsonToken.EndConstructor); + return true; + default: + if (!char.IsWhiteSpace(currentChar)) + { + if (char.IsNumber(currentChar) || currentChar == '-' || currentChar == '.') + { + ParseNumber(currentChar); + return true; + } + throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition); + } + break; + case '\t': + case '\n': + case '\r': + case ' ': + break; + } + } + while ((currentChar = MoveNext()) != 0 || !_end); + return false; + } + + private bool EatWhitespace(char initialChar, bool oneOrMore, out char finalChar) + { + bool flag = false; + char c = initialChar; + while (c == ' ' || char.IsWhiteSpace(c)) + { + flag = true; + c = MoveNext(); + } + finalChar = c; + return !oneOrMore || flag; + } + + private void ParseConstructor() + { + if (MatchValue('n', "new", noTrailingNonSeperatorCharacters: true)) + { + char finalChar = MoveNext(); + if (EatWhitespace(finalChar, /*oneOrMore:*/ true, out finalChar)) + { + while (char.IsLetter(finalChar)) + { + _buffer.Append(finalChar); + finalChar = MoveNext(); + } + EatWhitespace(finalChar, /*oneOrMore:*/ false, out finalChar); + if (finalChar != '(') + { + throw CreateJsonReaderException("Unexpected character while parsing constructor: {0}. Line {1}, position {2}.", finalChar, _currentLineNumber, _currentLinePosition); + } + string value = _buffer.ToString(); + _buffer.Position = 0; + SetToken(JsonToken.StartConstructor, value); + } + } + } + + private void ParseNumber(char firstChar) + { + char c = firstChar; + bool flag = false; + do + { + if (IsSeperator(c)) + { + flag = true; + _lastChar = c; + } + else + { + _buffer.Append(c); + } + } + while (!flag && ((c = MoveNext()) != 0 || !_end)); + string text = _buffer.ToString(); + bool flag2 = firstChar == '0' && !text.StartsWith("0.", StringComparison.OrdinalIgnoreCase); + object value2; + JsonToken newToken; + if (_readType == ReadType.ReadAsDecimal) + { + if (flag2) + { + long value = (!text.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) ? Convert.ToInt64(text, 8) : Convert.ToInt64(text, 16); + value2 = Convert.ToDecimal(value); + } + else + { + value2 = decimal.Parse(text, NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowLeadingSign | NumberStyles.AllowTrailingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); + } + newToken = JsonToken.Float; + } + else if (flag2) + { + value2 = ((!text.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) ? Convert.ToInt64(text, 8) : Convert.ToInt64(text, 16)); + newToken = JsonToken.Integer; + } + else if (text.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || text.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) + { + value2 = Convert.ToDouble(text, CultureInfo.InvariantCulture); + newToken = JsonToken.Float; + } + else + { + try + { + value2 = Convert.ToInt64(text, CultureInfo.InvariantCulture); + } + catch (OverflowException innerException) + { + throw new JsonReaderException("JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, text), innerException); + IL_018f:; + } + newToken = JsonToken.Integer; + } + _buffer.Position = 0; + SetToken(newToken, value2); + } + + private void ParseComment() + { + char c = MoveNext(); + if (c != '*') + { + throw CreateJsonReaderException("Error parsing comment. Expected: *. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + while ((c = MoveNext()) != 0 || !_end) + { + if (c == '*') + { + if ((c = MoveNext()) != 0 || !_end) + { + if (c == '/') + { + break; + } + _buffer.Append('*'); + _buffer.Append(c); + } + } + else + { + _buffer.Append(c); + } + } + SetToken(JsonToken.Comment, _buffer.ToString()); + _buffer.Position = 0; + } + + private bool MatchValue(char firstChar, string value) + { + char c = firstChar; + int num = 0; + while (c == value[num]) + { + num++; + if (num >= value.Length || ((c = MoveNext()) == '\0' && _end)) + { + break; + } + } + return num == value.Length; + } + + private bool MatchValue(char firstChar, string value, bool noTrailingNonSeperatorCharacters) + { + bool flag = MatchValue(firstChar, value); + if (!noTrailingNonSeperatorCharacters) + { + return flag; + } + int num = PeekNext(); + char c = (num != -1) ? ((char)num) : '\0'; + return flag && (c == '\0' || IsSeperator(c)); + } + + private bool IsSeperator(char c) + { + switch (c) + { + case ',': + case ']': + case '}': + return true; + case '/': + return HasNext() && PeekNext() == 42; + case ')': + if (base.CurrentState == State.Constructor || base.CurrentState == State.ConstructorStart) + { + return true; + } + break; + case '\t': + case '\n': + case '\r': + case ' ': + return true; + default: + if (char.IsWhiteSpace(c)) + { + return true; + } + break; + } + return false; + } + + private void ParseTrue() + { + if (!MatchValue('t', JsonConvert.True, noTrailingNonSeperatorCharacters: true)) + { + throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + SetToken(JsonToken.Boolean, true); + } + + private void ParseNull() + { + if (!MatchValue('n', JsonConvert.Null, noTrailingNonSeperatorCharacters: true)) + { + throw CreateJsonReaderException("Error parsing null value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + SetToken(JsonToken.Null); + } + + private void ParseUndefined() + { + if (!MatchValue('u', JsonConvert.Undefined, noTrailingNonSeperatorCharacters: true)) + { + throw CreateJsonReaderException("Error parsing undefined value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + SetToken(JsonToken.Undefined); + } + + private void ParseFalse() + { + if (!MatchValue('f', JsonConvert.False, noTrailingNonSeperatorCharacters: true)) + { + throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + SetToken(JsonToken.Boolean, false); + } + + private void ParseNumberNegativeInfinity() + { + if (!MatchValue('-', JsonConvert.NegativeInfinity, noTrailingNonSeperatorCharacters: true)) + { + throw CreateJsonReaderException("Error parsing negative infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + SetToken(JsonToken.Float, double.NegativeInfinity); + } + + private void ParseNumberPositiveInfinity() + { + if (!MatchValue('I', JsonConvert.PositiveInfinity, noTrailingNonSeperatorCharacters: true)) + { + throw CreateJsonReaderException("Error parsing positive infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + SetToken(JsonToken.Float, double.PositiveInfinity); + } + + private void ParseNumberNaN() + { + if (!MatchValue('N', JsonConvert.NaN, noTrailingNonSeperatorCharacters: true)) + { + throw CreateJsonReaderException("Error parsing NaN value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition); + } + SetToken(JsonToken.Float, double.NaN); + } + + public override void Close() + { + base.Close(); + if (base.CloseInput && _reader != null) + { + _reader.Close(); + } + if (_buffer != null) + { + _buffer.Clear(); + } + } + + public bool HasLineInfo() + { + return true; + } + } +} diff --git a/Newtonsoft.Json/JsonTextWriter.cs b/Newtonsoft.Json/JsonTextWriter.cs new file mode 100644 index 00000000..723ff96a --- /dev/null +++ b/Newtonsoft.Json/JsonTextWriter.cs @@ -0,0 +1,354 @@ +using Newtonsoft.Json.Utilities; +using System; +using System.IO; + +namespace Newtonsoft.Json +{ + public class JsonTextWriter : JsonWriter + { + private readonly TextWriter _writer; + + private Base64Encoder _base64Encoder; + + private char _indentChar; + + private int _indentation; + + private char _quoteChar; + + private bool _quoteName; + + private Base64Encoder Base64Encoder + { + get + { + if (_base64Encoder == null) + { + _base64Encoder = new Base64Encoder(_writer); + } + return _base64Encoder; + } + } + + public int Indentation + { + get + { + return _indentation; + } + set + { + if (value < 0) + { + throw new ArgumentException("Indentation value must be greater than 0."); + } + _indentation = value; + } + } + + public char QuoteChar + { + get + { + return _quoteChar; + } + set + { + if (value != '"' && value != '\'') + { + throw new ArgumentException("Invalid JavaScript string quote character. Valid quote characters are ' and \"."); + } + _quoteChar = value; + } + } + + public char IndentChar + { + get + { + return _indentChar; + } + set + { + _indentChar = value; + } + } + + public bool QuoteName + { + get + { + return _quoteName; + } + set + { + _quoteName = value; + } + } + + public JsonTextWriter(TextWriter textWriter) + { + if (textWriter == null) + { + throw new ArgumentNullException("textWriter"); + } + _writer = textWriter; + _quoteChar = '"'; + _quoteName = true; + _indentChar = ' '; + _indentation = 2; + } + + public override void Flush() + { + _writer.Flush(); + } + + public override void Close() + { + base.Close(); + if (base.CloseOutput && _writer != null) + { + _writer.Close(); + } + } + + public override void WriteStartObject() + { + base.WriteStartObject(); + _writer.Write("{"); + } + + public override void WriteStartArray() + { + base.WriteStartArray(); + _writer.Write("["); + } + + public override void WriteStartConstructor(string name) + { + base.WriteStartConstructor(name); + _writer.Write("new "); + _writer.Write(name); + _writer.Write("("); + } + + protected override void WriteEnd(JsonToken token) + { + switch (token) + { + case JsonToken.EndObject: + _writer.Write("}"); + break; + case JsonToken.EndArray: + _writer.Write("]"); + break; + case JsonToken.EndConstructor: + _writer.Write(")"); + break; + default: + throw new JsonWriterException("Invalid JsonToken: " + token); + } + } + + public override void WritePropertyName(string name) + { + base.WritePropertyName(name); + JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName); + _writer.Write(':'); + } + + protected override void WriteIndent() + { + if (base.Formatting == Formatting.Indented) + { + _writer.Write(Environment.NewLine); + int num = base.Top * _indentation; + for (int i = 0; i < num; i++) + { + _writer.Write(_indentChar); + } + } + } + + protected override void WriteValueDelimiter() + { + _writer.Write(','); + } + + protected override void WriteIndentSpace() + { + _writer.Write(' '); + } + + private void WriteValueInternal(string value, JsonToken token) + { + _writer.Write(value); + } + + public override void WriteNull() + { + base.WriteNull(); + WriteValueInternal(JsonConvert.Null, JsonToken.Null); + } + + public override void WriteUndefined() + { + base.WriteUndefined(); + WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined); + } + + public override void WriteRaw(string json) + { + base.WriteRaw(json); + _writer.Write(json); + } + + public override void WriteValue(string value) + { + base.WriteValue(value); + if (value == null) + { + WriteValueInternal(JsonConvert.Null, JsonToken.Null); + } + else + { + JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, appendDelimiters: true); + } + } + + public override void WriteValue(int value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(uint value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(long value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(ulong value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(float value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); + } + + public override void WriteValue(double value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); + } + + public override void WriteValue(bool value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean); + } + + public override void WriteValue(short value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(ushort value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(char value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(byte value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(sbyte value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); + } + + public override void WriteValue(decimal value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); + } + + public override void WriteValue(DateTime value) + { + base.WriteValue(value); + JsonConvert.WriteDateTimeString(_writer, value); + } + + public override void WriteValue(byte[] value) + { + base.WriteValue(value); + if (value != null) + { + _writer.Write(_quoteChar); + Base64Encoder.Encode(value, 0, value.Length); + Base64Encoder.Flush(); + _writer.Write(_quoteChar); + } + } + + public override void WriteValue(DateTimeOffset value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date); + } + + public override void WriteValue(Guid value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.String); + } + + public override void WriteValue(TimeSpan value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date); + } + + public override void WriteValue(Uri value) + { + base.WriteValue(value); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date); + } + + public override void WriteComment(string text) + { + base.WriteComment(text); + _writer.Write("/*"); + _writer.Write(text); + _writer.Write("*/"); + } + + public override void WriteWhitespace(string ws) + { + base.WriteWhitespace(ws); + _writer.Write(ws); + } + } +} diff --git a/Newtonsoft.Json/JsonToken.cs b/Newtonsoft.Json/JsonToken.cs new file mode 100644 index 00000000..49fa0377 --- /dev/null +++ b/Newtonsoft.Json/JsonToken.cs @@ -0,0 +1,24 @@ +namespace Newtonsoft.Json +{ + public enum JsonToken + { + None, + StartObject, + StartArray, + StartConstructor, + PropertyName, + Comment, + Raw, + Integer, + Float, + String, + Boolean, + Null, + Undefined, + EndObject, + EndArray, + EndConstructor, + Date, + Bytes + } +} diff --git a/Newtonsoft.Json/JsonValidatingReader.cs b/Newtonsoft.Json/JsonValidatingReader.cs new file mode 100644 index 00000000..c3cb681d --- /dev/null +++ b/Newtonsoft.Json/JsonValidatingReader.cs @@ -0,0 +1,680 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Schema; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Newtonsoft.Json +{ + public class JsonValidatingReader : JsonReader, IJsonLineInfo + { + private class SchemaScope + { + private readonly JTokenType _tokenType; + + private readonly IList _schemas; + + private readonly Dictionary _requiredProperties; + + public string CurrentPropertyName + { + get; + set; + } + + public int ArrayItemCount + { + get; + set; + } + + public IList Schemas => _schemas; + + public Dictionary RequiredProperties => _requiredProperties; + + public JTokenType TokenType => _tokenType; + + public SchemaScope(JTokenType tokenType, IList schemas) + { + _tokenType = tokenType; + _schemas = schemas; + _requiredProperties = schemas.SelectMany(GetRequiredProperties).Distinct().ToDictionary((string p) => p, (string p) => false); + } + + private IEnumerable GetRequiredProperties(JsonSchemaModel schema) + { + if (schema == null || schema.Properties == null) + { + return Enumerable.Empty(); + } + return from p in schema.Properties + where p.Value.Required + select p.Key; + } + } + + private readonly JsonReader _reader; + + private readonly Stack _stack; + + private JsonSchema _schema; + + private JsonSchemaModel _model; + + private SchemaScope _currentScope; + + int IJsonLineInfo.LineNumber + { + get + { + return (_reader as IJsonLineInfo)?.LineNumber ?? 0; + } + } + + int IJsonLineInfo.LinePosition + { + get + { + return (_reader as IJsonLineInfo)?.LinePosition ?? 0; + } + } + + public override object Value => _reader.Value; + + public override int Depth => _reader.Depth; + + public override char QuoteChar + { + get + { + return _reader.QuoteChar; + } + protected internal set + { + } + } + + public override JsonToken TokenType => _reader.TokenType; + + public override Type ValueType => _reader.ValueType; + + private IEnumerable CurrentSchemas => _currentScope.Schemas; + + private IEnumerable CurrentMemberSchemas + { + get + { + if (_currentScope == null) + { + return new List(new JsonSchemaModel[1] + { + _model + }); + } + if (_currentScope.Schemas != null && _currentScope.Schemas.Count != 0) + { + switch (_currentScope.TokenType) + { + case JTokenType.None: + return _currentScope.Schemas; + case JTokenType.Object: + { + if (_currentScope.CurrentPropertyName == null) + { + throw new Exception("CurrentPropertyName has not been set on scope."); + } + IList list2 = new List(); + { + foreach (JsonSchemaModel currentSchema in CurrentSchemas) + { + if (currentSchema.Properties != null && currentSchema.Properties.TryGetValue(_currentScope.CurrentPropertyName, out JsonSchemaModel value)) + { + list2.Add(value); + } + if (currentSchema.PatternProperties != null) + { + foreach (KeyValuePair patternProperty in currentSchema.PatternProperties) + { + if (Regex.IsMatch(_currentScope.CurrentPropertyName, patternProperty.Key)) + { + list2.Add(patternProperty.Value); + } + } + } + if (list2.Count == 0 && currentSchema.AllowAdditionalProperties && currentSchema.AdditionalProperties != null) + { + list2.Add(currentSchema.AdditionalProperties); + } + } + return list2; + } + } + case JTokenType.Array: + { + IList list = new List(); + { + foreach (JsonSchemaModel currentSchema2 in CurrentSchemas) + { + if (!CollectionUtils.IsNullOrEmpty(currentSchema2.Items)) + { + if (currentSchema2.Items.Count == 1) + { + list.Add(currentSchema2.Items[0]); + } + if (currentSchema2.Items.Count > _currentScope.ArrayItemCount - 1) + { + list.Add(currentSchema2.Items[_currentScope.ArrayItemCount - 1]); + } + } + if (currentSchema2.AllowAdditionalProperties && currentSchema2.AdditionalProperties != null) + { + list.Add(currentSchema2.AdditionalProperties); + } + } + return list; + } + } + case JTokenType.Constructor: + return Enumerable.Empty(); + default: + throw new ArgumentOutOfRangeException("TokenType", "Unexpected token type: {0}".FormatWith(CultureInfo.InvariantCulture, _currentScope.TokenType)); + } + } + return Enumerable.Empty(); + } + } + + public JsonSchema Schema + { + get + { + return _schema; + } + set + { + if (TokenType != 0) + { + throw new Exception("Cannot change schema while validating JSON."); + } + _schema = value; + _model = null; + } + } + + public JsonReader Reader => _reader; + + public event ValidationEventHandler ValidationEventHandler; + + public JsonValidatingReader(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + _reader = reader; + _stack = new Stack(); + } + + bool IJsonLineInfo.HasLineInfo() + { + return (_reader as IJsonLineInfo)?.HasLineInfo() ?? false; + } + + private void Push(SchemaScope scope) + { + _stack.Push(scope); + _currentScope = scope; + } + + private SchemaScope Pop() + { + SchemaScope result = _stack.Pop(); + _currentScope = ((_stack.Count == 0) ? null : _stack.Peek()); + return result; + } + + private void RaiseError(string message, JsonSchemaModel schema) + { + string message2 = (!((IJsonLineInfo)this).HasLineInfo()) ? message : (message + " Line {0}, position {1}.".FormatWith(CultureInfo.InvariantCulture, ((IJsonLineInfo)this).LineNumber, ((IJsonLineInfo)this).LinePosition)); + OnValidationEvent(new JsonSchemaException(message2, null, ((IJsonLineInfo)this).LineNumber, ((IJsonLineInfo)this).LinePosition)); + } + + private void OnValidationEvent(JsonSchemaException exception) + { + ValidationEventHandler validationEventHandler = this.ValidationEventHandler; + if (validationEventHandler == null) + { + throw exception; + } + validationEventHandler(this, new ValidationEventArgs(exception)); + } + + private void ValidateInEnumAndNotDisallowed(JsonSchemaModel schema) + { + if (schema != null) + { + JToken jToken = new JValue(_reader.Value); + if (schema.Enum != null) + { + StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture); + jToken.WriteTo(new JsonTextWriter(stringWriter)); + if (!schema.Enum.ContainsValue(jToken, new JTokenEqualityComparer())) + { + RaiseError("Value {0} is not defined in enum.".FormatWith(CultureInfo.InvariantCulture, stringWriter.ToString()), schema); + } + } + JsonSchemaType? currentNodeSchemaType = GetCurrentNodeSchemaType(); + if (currentNodeSchemaType.HasValue && JsonSchemaGenerator.HasFlag(schema.Disallow, currentNodeSchemaType.Value)) + { + RaiseError("Type {0} is disallowed.".FormatWith(CultureInfo.InvariantCulture, currentNodeSchemaType), schema); + } + } + } + + private JsonSchemaType? GetCurrentNodeSchemaType() + { + switch (_reader.TokenType) + { + case JsonToken.StartObject: + return JsonSchemaType.Object; + case JsonToken.StartArray: + return JsonSchemaType.Array; + case JsonToken.Integer: + return JsonSchemaType.Integer; + case JsonToken.Float: + return JsonSchemaType.Float; + case JsonToken.String: + return JsonSchemaType.String; + case JsonToken.Boolean: + return JsonSchemaType.Boolean; + case JsonToken.Null: + return JsonSchemaType.Null; + default: + return null; + } + } + + public override byte[] ReadAsBytes() + { + byte[] result = _reader.ReadAsBytes(); + ValidateCurrentToken(); + return result; + } + + public override decimal? ReadAsDecimal() + { + decimal? result = _reader.ReadAsDecimal(); + ValidateCurrentToken(); + return result; + } + + public override DateTimeOffset? ReadAsDateTimeOffset() + { + DateTimeOffset? result = _reader.ReadAsDateTimeOffset(); + ValidateCurrentToken(); + return result; + } + + public override bool Read() + { + if (!_reader.Read()) + { + return false; + } + if (_reader.TokenType == JsonToken.Comment) + { + return true; + } + ValidateCurrentToken(); + return true; + } + + private void ValidateCurrentToken() + { + if (_model == null) + { + JsonSchemaModelBuilder jsonSchemaModelBuilder = new JsonSchemaModelBuilder(); + _model = jsonSchemaModelBuilder.Build(_schema); + } + switch (_reader.TokenType) + { + case JsonToken.Raw: + break; + case JsonToken.Undefined: + break; + case JsonToken.Date: + break; + case JsonToken.StartObject: + { + ProcessValue(); + IList schemas2 = CurrentMemberSchemas.Where(ValidateObject).ToList(); + Push(new SchemaScope(JTokenType.Object, schemas2)); + break; + } + case JsonToken.StartArray: + { + ProcessValue(); + IList schemas = CurrentMemberSchemas.Where(ValidateArray).ToList(); + Push(new SchemaScope(JTokenType.Array, schemas)); + break; + } + case JsonToken.StartConstructor: + Push(new SchemaScope(JTokenType.Constructor, null)); + break; + case JsonToken.PropertyName: + foreach (JsonSchemaModel currentSchema in CurrentSchemas) + { + ValidatePropertyName(currentSchema); + } + break; + case JsonToken.Integer: + ProcessValue(); + foreach (JsonSchemaModel currentMemberSchema in CurrentMemberSchemas) + { + ValidateInteger(currentMemberSchema); + } + break; + case JsonToken.Float: + ProcessValue(); + foreach (JsonSchemaModel currentMemberSchema2 in CurrentMemberSchemas) + { + ValidateFloat(currentMemberSchema2); + } + break; + case JsonToken.String: + ProcessValue(); + foreach (JsonSchemaModel currentMemberSchema3 in CurrentMemberSchemas) + { + ValidateString(currentMemberSchema3); + } + break; + case JsonToken.Boolean: + ProcessValue(); + foreach (JsonSchemaModel currentMemberSchema4 in CurrentMemberSchemas) + { + ValidateBoolean(currentMemberSchema4); + } + break; + case JsonToken.Null: + ProcessValue(); + foreach (JsonSchemaModel currentMemberSchema5 in CurrentMemberSchemas) + { + ValidateNull(currentMemberSchema5); + } + break; + case JsonToken.EndObject: + foreach (JsonSchemaModel currentSchema2 in CurrentSchemas) + { + ValidateEndObject(currentSchema2); + } + Pop(); + break; + case JsonToken.EndArray: + foreach (JsonSchemaModel currentSchema3 in CurrentSchemas) + { + ValidateEndArray(currentSchema3); + } + Pop(); + break; + case JsonToken.EndConstructor: + Pop(); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private void ValidateEndObject(JsonSchemaModel schema) + { + if (schema != null) + { + Dictionary requiredProperties = _currentScope.RequiredProperties; + if (requiredProperties != null) + { + List list = (from kv in requiredProperties + where !kv.Value + select kv.Key).ToList(); + if (list.Count > 0) + { + RaiseError("Required properties are missing from object: {0}.".FormatWith(CultureInfo.InvariantCulture, string.Join(", ", list.ToArray())), schema); + } + } + } + } + + private void ValidateEndArray(JsonSchemaModel schema) + { + if (schema != null) + { + int arrayItemCount = _currentScope.ArrayItemCount; + if (schema.MaximumItems.HasValue) + { + int? maximumItems = schema.MaximumItems; + if (maximumItems.HasValue && arrayItemCount > maximumItems.Value) + { + RaiseError("Array item count {0} exceeds maximum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MaximumItems), schema); + } + } + if (schema.MinimumItems.HasValue) + { + int? minimumItems = schema.MinimumItems; + if (minimumItems.HasValue && arrayItemCount < minimumItems.Value) + { + RaiseError("Array item count {0} is less than minimum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MinimumItems), schema); + } + } + } + } + + private void ValidateNull(JsonSchemaModel schema) + { + if (schema != null && TestType(schema, JsonSchemaType.Null)) + { + ValidateInEnumAndNotDisallowed(schema); + } + } + + private void ValidateBoolean(JsonSchemaModel schema) + { + if (schema != null && TestType(schema, JsonSchemaType.Boolean)) + { + ValidateInEnumAndNotDisallowed(schema); + } + } + + private void ValidateString(JsonSchemaModel schema) + { + if (schema != null && TestType(schema, JsonSchemaType.String)) + { + ValidateInEnumAndNotDisallowed(schema); + string text = _reader.Value.ToString(); + if (schema.MaximumLength.HasValue) + { + int? maximumLength = schema.MaximumLength; + if (maximumLength.HasValue && text.Length > maximumLength.Value) + { + RaiseError("String '{0}' exceeds maximum length of {1}.".FormatWith(CultureInfo.InvariantCulture, text, schema.MaximumLength), schema); + } + } + if (schema.MinimumLength.HasValue) + { + int? minimumLength = schema.MinimumLength; + if (minimumLength.HasValue && text.Length < minimumLength.Value) + { + RaiseError("String '{0}' is less than minimum length of {1}.".FormatWith(CultureInfo.InvariantCulture, text, schema.MinimumLength), schema); + } + } + if (schema.Patterns != null) + { + foreach (string pattern in schema.Patterns) + { + if (!Regex.IsMatch(text, pattern)) + { + RaiseError("String '{0}' does not match regex pattern '{1}'.".FormatWith(CultureInfo.InvariantCulture, text, pattern), schema); + } + } + } + } + } + + private void ValidateInteger(JsonSchemaModel schema) + { + if (schema != null && TestType(schema, JsonSchemaType.Integer)) + { + ValidateInEnumAndNotDisallowed(schema); + long num = Convert.ToInt64(_reader.Value, CultureInfo.InvariantCulture); + if (schema.Maximum.HasValue) + { + double? maximum = schema.Maximum; + if (maximum.HasValue && (double)num > maximum.Value) + { + RaiseError("Integer {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, num, schema.Maximum), schema); + } + if (schema.ExclusiveMaximum && (double)num == schema.Maximum) + { + RaiseError("Integer {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, num, schema.Maximum), schema); + } + } + if (schema.Minimum.HasValue) + { + double? minimum = schema.Minimum; + if (minimum.HasValue && (double)num < minimum.Value) + { + RaiseError("Integer {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, num, schema.Minimum), schema); + } + if (schema.ExclusiveMinimum && (double)num == schema.Minimum) + { + RaiseError("Integer {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, num, schema.Minimum), schema); + } + } + if (schema.DivisibleBy.HasValue && !IsZero((double)num % schema.DivisibleBy.Value)) + { + RaiseError("Integer {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(num), schema.DivisibleBy), schema); + } + } + } + + private void ProcessValue() + { + if (_currentScope != null && _currentScope.TokenType == JTokenType.Array) + { + _currentScope.ArrayItemCount++; + foreach (JsonSchemaModel currentSchema in CurrentSchemas) + { + if (currentSchema != null && currentSchema.Items != null && currentSchema.Items.Count > 1 && _currentScope.ArrayItemCount >= currentSchema.Items.Count) + { + RaiseError("Index {0} has not been defined and the schema does not allow additional items.".FormatWith(CultureInfo.InvariantCulture, _currentScope.ArrayItemCount), currentSchema); + } + } + } + } + + private void ValidateFloat(JsonSchemaModel schema) + { + if (schema != null && TestType(schema, JsonSchemaType.Float)) + { + ValidateInEnumAndNotDisallowed(schema); + double num = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture); + if (schema.Maximum.HasValue) + { + double? maximum = schema.Maximum; + if (maximum.HasValue && num > maximum.Value) + { + RaiseError("Float {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(num), schema.Maximum), schema); + } + if (schema.ExclusiveMaximum && num == schema.Maximum) + { + RaiseError("Float {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(num), schema.Maximum), schema); + } + } + if (schema.Minimum.HasValue) + { + double? minimum = schema.Minimum; + if (minimum.HasValue && num < minimum.Value) + { + RaiseError("Float {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(num), schema.Minimum), schema); + } + if (schema.ExclusiveMinimum && num == schema.Minimum) + { + RaiseError("Float {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(num), schema.Minimum), schema); + } + } + if (schema.DivisibleBy.HasValue && !IsZero(num % schema.DivisibleBy.Value)) + { + RaiseError("Float {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(num), schema.DivisibleBy), schema); + } + } + } + + private static bool IsZero(double value) + { + double num = 2.2204460492503131E-16; + return Math.Abs(value) < 10.0 * num; + } + + private void ValidatePropertyName(JsonSchemaModel schema) + { + if (schema != null) + { + string text = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); + if (_currentScope.RequiredProperties.ContainsKey(text)) + { + _currentScope.RequiredProperties[text] = true; + } + if (!schema.AllowAdditionalProperties && !IsPropertyDefinied(schema, text)) + { + RaiseError("Property '{0}' has not been defined and the schema does not allow additional properties.".FormatWith(CultureInfo.InvariantCulture, text), schema); + } + _currentScope.CurrentPropertyName = text; + } + } + + private bool IsPropertyDefinied(JsonSchemaModel schema, string propertyName) + { + if (schema.Properties != null && schema.Properties.ContainsKey(propertyName)) + { + return true; + } + if (schema.PatternProperties != null) + { + foreach (string key in schema.PatternProperties.Keys) + { + if (Regex.IsMatch(propertyName, key)) + { + return true; + } + } + } + return false; + } + + private bool ValidateArray(JsonSchemaModel schema) + { + if (schema == null) + { + return true; + } + return TestType(schema, JsonSchemaType.Array); + } + + private bool ValidateObject(JsonSchemaModel schema) + { + if (schema == null) + { + return true; + } + return TestType(schema, JsonSchemaType.Object); + } + + private bool TestType(JsonSchemaModel currentSchema, JsonSchemaType currentType) + { + if (!JsonSchemaGenerator.HasFlag(currentSchema.Type, currentType)) + { + RaiseError("Invalid type. Expected {0} but got {1}.".FormatWith(CultureInfo.InvariantCulture, currentSchema.Type, currentType), currentSchema); + return false; + } + return true; + } + } +} diff --git a/Newtonsoft.Json/JsonWriter.cs b/Newtonsoft.Json/JsonWriter.cs new file mode 100644 index 00000000..afbd2443 --- /dev/null +++ b/Newtonsoft.Json/JsonWriter.cs @@ -0,0 +1,1021 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Utilities; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Newtonsoft.Json +{ + public abstract class JsonWriter : IDisposable + { + private enum State + { + Start, + Property, + ObjectStart, + Object, + ArrayStart, + Array, + ConstructorStart, + Constructor, + Bytes, + Closed, + Error + } + + private static readonly State[][] stateArray = new State[8][] + { + new State[10] + { + State.Error, + State.Error, + State.Error, + State.Error, + State.Error, + State.Error, + State.Error, + State.Error, + State.Error, + State.Error + }, + new State[10] + { + State.ObjectStart, + State.ObjectStart, + State.Error, + State.Error, + State.ObjectStart, + State.ObjectStart, + State.ObjectStart, + State.ObjectStart, + State.Error, + State.Error + }, + new State[10] + { + State.ArrayStart, + State.ArrayStart, + State.Error, + State.Error, + State.ArrayStart, + State.ArrayStart, + State.ArrayStart, + State.ArrayStart, + State.Error, + State.Error + }, + new State[10] + { + State.ConstructorStart, + State.ConstructorStart, + State.Error, + State.Error, + State.ConstructorStart, + State.ConstructorStart, + State.ConstructorStart, + State.ConstructorStart, + State.Error, + State.Error + }, + new State[10] + { + State.Property, + State.Error, + State.Property, + State.Property, + State.Error, + State.Error, + State.Error, + State.Error, + State.Error, + State.Error + }, + new State[10] + { + State.Start, + State.Property, + State.ObjectStart, + State.Object, + State.ArrayStart, + State.Array, + State.Constructor, + State.Constructor, + State.Error, + State.Error + }, + new State[10] + { + State.Start, + State.Property, + State.ObjectStart, + State.Object, + State.ArrayStart, + State.Array, + State.Constructor, + State.Constructor, + State.Error, + State.Error + }, + new State[10] + { + State.Start, + State.Object, + State.Error, + State.Error, + State.Array, + State.Array, + State.Constructor, + State.Constructor, + State.Error, + State.Error + } + }; + + private int _top; + + private readonly List _stack; + + private State _currentState; + + private Formatting _formatting; + + public bool CloseOutput + { + get; + set; + } + + protected internal int Top => _top; + + public WriteState WriteState + { + get + { + switch (_currentState) + { + case State.Error: + return WriteState.Error; + case State.Closed: + return WriteState.Closed; + case State.ObjectStart: + case State.Object: + return WriteState.Object; + case State.ArrayStart: + case State.Array: + return WriteState.Array; + case State.ConstructorStart: + case State.Constructor: + return WriteState.Constructor; + case State.Property: + return WriteState.Property; + case State.Start: + return WriteState.Start; + default: + throw new JsonWriterException("Invalid state: " + _currentState); + } + } + } + + public Formatting Formatting + { + get + { + return _formatting; + } + set + { + _formatting = value; + } + } + + protected JsonWriter() + { + _stack = new List(8); + _stack.Add(JTokenType.None); + _currentState = State.Start; + _formatting = Formatting.None; + CloseOutput = true; + } + + void IDisposable.Dispose() + { + Dispose(disposing: true); + } + + private void Push(JTokenType value) + { + _top++; + if (_stack.Count <= _top) + { + _stack.Add(value); + } + else + { + _stack[_top] = value; + } + } + + private JTokenType Pop() + { + JTokenType result = Peek(); + _top--; + return result; + } + + private JTokenType Peek() + { + return _stack[_top]; + } + + public abstract void Flush(); + + public virtual void Close() + { + AutoCompleteAll(); + } + + public virtual void WriteStartObject() + { + AutoComplete(JsonToken.StartObject); + Push(JTokenType.Object); + } + + public virtual void WriteEndObject() + { + AutoCompleteClose(JsonToken.EndObject); + } + + public virtual void WriteStartArray() + { + AutoComplete(JsonToken.StartArray); + Push(JTokenType.Array); + } + + public virtual void WriteEndArray() + { + AutoCompleteClose(JsonToken.EndArray); + } + + public virtual void WriteStartConstructor(string name) + { + AutoComplete(JsonToken.StartConstructor); + Push(JTokenType.Constructor); + } + + public virtual void WriteEndConstructor() + { + AutoCompleteClose(JsonToken.EndConstructor); + } + + public virtual void WritePropertyName(string name) + { + AutoComplete(JsonToken.PropertyName); + } + + public virtual void WriteEnd() + { + WriteEnd(Peek()); + } + + public void WriteToken(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + int initialDepth = (reader.TokenType == JsonToken.None) ? (-1) : (IsStartToken(reader.TokenType) ? reader.Depth : (reader.Depth + 1)); + WriteToken(reader, initialDepth); + } + + internal void WriteToken(JsonReader reader, int initialDepth) + { + do + { + switch (reader.TokenType) + { + case JsonToken.StartObject: + WriteStartObject(); + break; + case JsonToken.StartArray: + WriteStartArray(); + break; + case JsonToken.StartConstructor: + { + string strA = reader.Value.ToString(); + if (string.Compare(strA, "Date", StringComparison.Ordinal) == 0) + { + WriteConstructorDate(reader); + } + else + { + WriteStartConstructor(reader.Value.ToString()); + } + break; + } + case JsonToken.PropertyName: + WritePropertyName(reader.Value.ToString()); + break; + case JsonToken.Comment: + WriteComment(reader.Value.ToString()); + break; + case JsonToken.Integer: + WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.Float: + WriteValue(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.String: + WriteValue(reader.Value.ToString()); + break; + case JsonToken.Boolean: + WriteValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.Null: + WriteNull(); + break; + case JsonToken.Undefined: + WriteUndefined(); + break; + case JsonToken.EndObject: + WriteEndObject(); + break; + case JsonToken.EndArray: + WriteEndArray(); + break; + case JsonToken.EndConstructor: + WriteEndConstructor(); + break; + case JsonToken.Date: + WriteValue((DateTime)reader.Value); + break; + case JsonToken.Raw: + WriteRawValue((string)reader.Value); + break; + case JsonToken.Bytes: + WriteValue((byte[])reader.Value); + break; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type."); + case JsonToken.None: + break; + } + } + while (initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0) && reader.Read()); + } + + private void WriteConstructorDate(JsonReader reader) + { + if (!reader.Read()) + { + throw new Exception("Unexpected end while reading date constructor."); + } + if (reader.TokenType != JsonToken.Integer) + { + throw new Exception("Unexpected token while reading date constructor. Expected Integer, got " + reader.TokenType); + } + long javaScriptTicks = (long)reader.Value; + DateTime value = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks); + if (!reader.Read()) + { + throw new Exception("Unexpected end while reading date constructor."); + } + if (reader.TokenType != JsonToken.EndConstructor) + { + throw new Exception("Unexpected token while reading date constructor. Expected EndConstructor, got " + reader.TokenType); + } + WriteValue(value); + } + + private bool IsEndToken(JsonToken token) + { + switch (token) + { + case JsonToken.EndObject: + case JsonToken.EndArray: + case JsonToken.EndConstructor: + return true; + default: + return false; + } + } + + private bool IsStartToken(JsonToken token) + { + switch (token) + { + case JsonToken.StartObject: + case JsonToken.StartArray: + case JsonToken.StartConstructor: + return true; + default: + return false; + } + } + + private void WriteEnd(JTokenType type) + { + switch (type) + { + case JTokenType.Object: + WriteEndObject(); + break; + case JTokenType.Array: + WriteEndArray(); + break; + case JTokenType.Constructor: + WriteEndConstructor(); + break; + default: + throw new JsonWriterException("Unexpected type when writing end: " + type); + } + } + + private void AutoCompleteAll() + { + while (_top > 0) + { + WriteEnd(); + } + } + + private JTokenType GetTypeForCloseToken(JsonToken token) + { + switch (token) + { + case JsonToken.EndObject: + return JTokenType.Object; + case JsonToken.EndArray: + return JTokenType.Array; + case JsonToken.EndConstructor: + return JTokenType.Constructor; + default: + throw new JsonWriterException("No type for token: " + token); + } + } + + private JsonToken GetCloseTokenForType(JTokenType type) + { + switch (type) + { + case JTokenType.Object: + return JsonToken.EndObject; + case JTokenType.Array: + return JsonToken.EndArray; + case JTokenType.Constructor: + return JsonToken.EndConstructor; + default: + throw new JsonWriterException("No close token for type: " + type); + } + } + + private void AutoCompleteClose(JsonToken tokenBeingClosed) + { + int num = 0; + for (int i = 0; i < _top; i++) + { + int index = _top - i; + if (_stack[index] == GetTypeForCloseToken(tokenBeingClosed)) + { + num = i + 1; + break; + } + } + if (num == 0) + { + throw new JsonWriterException("No token to close."); + } + for (int j = 0; j < num; j++) + { + JsonToken closeTokenForType = GetCloseTokenForType(Pop()); + if (_currentState != State.ObjectStart && _currentState != State.ArrayStart) + { + WriteIndent(); + } + WriteEnd(closeTokenForType); + } + JTokenType jTokenType = Peek(); + switch (jTokenType) + { + case JTokenType.Object: + _currentState = State.Object; + break; + case JTokenType.Array: + _currentState = State.Array; + break; + case JTokenType.Constructor: + _currentState = State.Array; + break; + case JTokenType.None: + _currentState = State.Start; + break; + default: + throw new JsonWriterException("Unknown JsonType: " + jTokenType); + } + } + + protected virtual void WriteEnd(JsonToken token) + { + } + + protected virtual void WriteIndent() + { + } + + protected virtual void WriteValueDelimiter() + { + } + + protected virtual void WriteIndentSpace() + { + } + + internal void AutoComplete(JsonToken tokenBeingWritten) + { + int num; + switch (tokenBeingWritten) + { + default: + num = (int)tokenBeingWritten; + break; + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Null: + case JsonToken.Undefined: + case JsonToken.Date: + case JsonToken.Bytes: + num = 7; + break; + } + State state = stateArray[num][(int)_currentState]; + if (state == State.Error) + { + throw new JsonWriterException("Token {0} in state {1} would result in an invalid JavaScript object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString())); + } + if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment) + { + WriteValueDelimiter(); + } + else if (_currentState == State.Property && _formatting == Formatting.Indented) + { + WriteIndentSpace(); + } + WriteState writeState = WriteState; + if ((tokenBeingWritten == JsonToken.PropertyName && writeState != WriteState.Start) || writeState == WriteState.Array || writeState == WriteState.Constructor) + { + WriteIndent(); + } + _currentState = state; + } + + public virtual void WriteNull() + { + AutoComplete(JsonToken.Null); + } + + public virtual void WriteUndefined() + { + AutoComplete(JsonToken.Undefined); + } + + public virtual void WriteRaw(string json) + { + } + + public virtual void WriteRawValue(string json) + { + AutoComplete(JsonToken.Undefined); + WriteRaw(json); + } + + public virtual void WriteValue(string value) + { + AutoComplete(JsonToken.String); + } + + public virtual void WriteValue(int value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(uint value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(long value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(ulong value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(float value) + { + AutoComplete(JsonToken.Float); + } + + public virtual void WriteValue(double value) + { + AutoComplete(JsonToken.Float); + } + + public virtual void WriteValue(bool value) + { + AutoComplete(JsonToken.Boolean); + } + + public virtual void WriteValue(short value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(ushort value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(char value) + { + AutoComplete(JsonToken.String); + } + + public virtual void WriteValue(byte value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(sbyte value) + { + AutoComplete(JsonToken.Integer); + } + + public virtual void WriteValue(decimal value) + { + AutoComplete(JsonToken.Float); + } + + public virtual void WriteValue(DateTime value) + { + AutoComplete(JsonToken.Date); + } + + public virtual void WriteValue(DateTimeOffset value) + { + AutoComplete(JsonToken.Date); + } + + public virtual void WriteValue(Guid value) + { + AutoComplete(JsonToken.String); + } + + public virtual void WriteValue(TimeSpan value) + { + AutoComplete(JsonToken.String); + } + + public virtual void WriteValue(int? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(uint? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(long? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(ulong? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(float? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(double? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(bool? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(short? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(ushort? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(char? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(byte? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(sbyte? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(decimal? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(DateTime? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(DateTimeOffset? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(Guid? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(TimeSpan? value) + { + if (!value.HasValue) + { + WriteNull(); + } + else + { + WriteValue(value.Value); + } + } + + public virtual void WriteValue(byte[] value) + { + if (value == null) + { + WriteNull(); + } + else + { + AutoComplete(JsonToken.Bytes); + } + } + + public virtual void WriteValue(Uri value) + { + if (value == null) + { + WriteNull(); + } + else + { + AutoComplete(JsonToken.String); + } + } + + public virtual void WriteValue(object value) + { + if (value == null) + { + WriteNull(); + return; + } + if (value is IConvertible) + { + IConvertible convertible = value as IConvertible; + switch (convertible.GetTypeCode()) + { + case TypeCode.String: + WriteValue(convertible.ToString(CultureInfo.InvariantCulture)); + return; + case TypeCode.Char: + WriteValue(convertible.ToChar(CultureInfo.InvariantCulture)); + return; + case TypeCode.Boolean: + WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture)); + return; + case TypeCode.SByte: + WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture)); + return; + case TypeCode.Int16: + WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture)); + return; + case TypeCode.UInt16: + WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture)); + return; + case TypeCode.Int32: + WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture)); + return; + case TypeCode.Byte: + WriteValue(convertible.ToByte(CultureInfo.InvariantCulture)); + return; + case TypeCode.UInt32: + WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture)); + return; + case TypeCode.Int64: + WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture)); + return; + case TypeCode.UInt64: + WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture)); + return; + case TypeCode.Single: + WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture)); + return; + case TypeCode.Double: + WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture)); + return; + case TypeCode.DateTime: + WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture)); + return; + case TypeCode.Decimal: + WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture)); + return; + case TypeCode.DBNull: + WriteNull(); + return; + } + } + else + { + if (value is DateTimeOffset) + { + WriteValue((DateTimeOffset)value); + return; + } + if (value is byte[]) + { + WriteValue((byte[])value); + return; + } + if (value is Guid) + { + WriteValue((Guid)value); + return; + } + if (value is Uri) + { + WriteValue((Uri)value); + return; + } + if (value is TimeSpan) + { + WriteValue((TimeSpan)value); + return; + } + } + throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + } + + public virtual void WriteComment(string text) + { + AutoComplete(JsonToken.Comment); + } + + public virtual void WriteWhitespace(string ws) + { + if (ws != null && !StringUtils.IsWhiteSpace(ws)) + { + throw new JsonWriterException("Only white space characters should be used."); + } + } + + private void Dispose(bool disposing) + { + if (WriteState != WriteState.Closed) + { + Close(); + } + } + } +} diff --git a/Newtonsoft.Json/JsonWriterException.cs b/Newtonsoft.Json/JsonWriterException.cs new file mode 100644 index 00000000..7ab33dbc --- /dev/null +++ b/Newtonsoft.Json/JsonWriterException.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json +{ + [Serializable] + public class JsonWriterException : Exception + { + public JsonWriterException() + { + } + + public JsonWriterException(string message) + : base(message) + { + } + + public JsonWriterException(string message, Exception innerException) + : base(message, innerException) + { + } + + public JsonWriterException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/Newtonsoft.Json/MemberSerialization.cs b/Newtonsoft.Json/MemberSerialization.cs new file mode 100644 index 00000000..b3653112 --- /dev/null +++ b/Newtonsoft.Json/MemberSerialization.cs @@ -0,0 +1,8 @@ +namespace Newtonsoft.Json +{ + public enum MemberSerialization + { + OptOut, + OptIn + } +} diff --git a/Newtonsoft.Json/MissingMemberHandling.cs b/Newtonsoft.Json/MissingMemberHandling.cs new file mode 100644 index 00000000..58cda3cb --- /dev/null +++ b/Newtonsoft.Json/MissingMemberHandling.cs @@ -0,0 +1,8 @@ +namespace Newtonsoft.Json +{ + public enum MissingMemberHandling + { + Ignore, + Error + } +} diff --git a/Newtonsoft.Json/NullValueHandling.cs b/Newtonsoft.Json/NullValueHandling.cs new file mode 100644 index 00000000..26f51c67 --- /dev/null +++ b/Newtonsoft.Json/NullValueHandling.cs @@ -0,0 +1,8 @@ +namespace Newtonsoft.Json +{ + public enum NullValueHandling + { + Include, + Ignore + } +} diff --git a/Newtonsoft.Json/ObjectCreationHandling.cs b/Newtonsoft.Json/ObjectCreationHandling.cs new file mode 100644 index 00000000..7d394406 --- /dev/null +++ b/Newtonsoft.Json/ObjectCreationHandling.cs @@ -0,0 +1,9 @@ +namespace Newtonsoft.Json +{ + public enum ObjectCreationHandling + { + Auto, + Reuse, + Replace + } +} diff --git a/Newtonsoft.Json/PreserveReferencesHandling.cs b/Newtonsoft.Json/PreserveReferencesHandling.cs new file mode 100644 index 00000000..e8a7d9c4 --- /dev/null +++ b/Newtonsoft.Json/PreserveReferencesHandling.cs @@ -0,0 +1,13 @@ +using System; + +namespace Newtonsoft.Json +{ + [Flags] + public enum PreserveReferencesHandling + { + None = 0x0, + Objects = 0x1, + Arrays = 0x2, + All = 0x3 + } +} diff --git a/Newtonsoft.Json/ReferenceLoopHandling.cs b/Newtonsoft.Json/ReferenceLoopHandling.cs new file mode 100644 index 00000000..860dd6d6 --- /dev/null +++ b/Newtonsoft.Json/ReferenceLoopHandling.cs @@ -0,0 +1,9 @@ +namespace Newtonsoft.Json +{ + public enum ReferenceLoopHandling + { + Error, + Ignore, + Serialize + } +} diff --git a/Newtonsoft.Json/Required.cs b/Newtonsoft.Json/Required.cs new file mode 100644 index 00000000..434c767b --- /dev/null +++ b/Newtonsoft.Json/Required.cs @@ -0,0 +1,9 @@ +namespace Newtonsoft.Json +{ + public enum Required + { + Default, + AllowNull, + Always + } +} diff --git a/Newtonsoft.Json/TypeNameHandling.cs b/Newtonsoft.Json/TypeNameHandling.cs new file mode 100644 index 00000000..176b2cc3 --- /dev/null +++ b/Newtonsoft.Json/TypeNameHandling.cs @@ -0,0 +1,14 @@ +using System; + +namespace Newtonsoft.Json +{ + [Flags] + public enum TypeNameHandling + { + None = 0x0, + Objects = 0x1, + Arrays = 0x2, + Auto = 0x4, + All = 0x3 + } +} diff --git a/Newtonsoft.Json/WriteState.cs b/Newtonsoft.Json/WriteState.cs new file mode 100644 index 00000000..06e601ad --- /dev/null +++ b/Newtonsoft.Json/WriteState.cs @@ -0,0 +1,13 @@ +namespace Newtonsoft.Json +{ + public enum WriteState + { + Error, + Closed, + Object, + Array, + Constructor, + Property, + Start + } +} diff --git a/Polygon.cs b/Polygon.cs new file mode 100644 index 00000000..c185074d --- /dev/null +++ b/Polygon.cs @@ -0,0 +1,258 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("Mesh/Polygon")] +[RequireComponent(typeof(MeshCollider))] +[RequireComponent(typeof(MeshFilter))] +[RequireComponent(typeof(MeshRenderer))] +public class Polygon : MonoBehaviour +{ + [Serializable] + public class ShapeData + { + public bool GenerateFront = true; + + public bool GenerateBack = true; + + public bool GenerateSides = true; + + public float Extrude = 1f; + + public float Elevation = 0.5f; + + public bool Enabled = true; + } + + public List Points = new List(); + + public HashSet Selected = new HashSet(); + + public float SmoothAngle = 35f; + + public Vector2 FrontUVScale = new Vector2(0.25f, 0.25f); + + public Vector2 BackUVScale = new Vector2(0.25f, 0.25f); + + public Vector2 SideUVScale = new Vector2(0.25f, 0.25f); + + public ShapeData PolygonMesh = new ShapeData(); + + public ShapeData PolygonCollider = new ShapeData(); + + public int InsertBefore; + + private void Start() + { + UpdateComponents(); + } + + public void UpdateComponents() + { + if (Application.isPlaying) + { + GetComponent().sharedMesh = GenerateMesh(PolygonCollider.GenerateFront, PolygonCollider.GenerateBack, PolygonCollider.GenerateSides, PolygonCollider.Extrude, PolygonCollider.Elevation, /*useNormals:*/ true, /*useUVS:*/ true, Vector2.one, Vector2.one, Vector2.one); + } + Mesh mesh = GenerateMesh(PolygonMesh.GenerateFront, PolygonMesh.GenerateBack, PolygonMesh.GenerateSides, PolygonMesh.Extrude, PolygonMesh.Elevation, /*useNormals:*/ true, /*useUVS:*/ true, FrontUVScale, BackUVScale, SideUVScale); + GetComponent().mesh = mesh; + } + + private Mesh GenerateMesh(bool front, bool back, bool sides, float extrude, float elevate, bool useNormals, bool useUVS, Vector2 frontUVScale, Vector2 backUVScale, Vector2 sideUVScale) + { + Mesh mesh = new Mesh(); + if (Points.Count == 0) + { + return mesh; + } + int num = 0; + int num2 = 0; + Vector3 b = Vector3.back * elevate; + List list = new List(); + if (front) + { + foreach (Vector2 point in Points) + { + Vector3 a = point; + list.Add(a + b); + } + } + num = list.Count; + if (back) + { + foreach (Vector2 point2 in Points) + { + Vector3 a2 = point2; + list.Add(a2 + Vector3.forward * extrude + b); + } + } + num2 = list.Count; + if (sides) + { + foreach (Vector2 point3 in Points) + { + Vector3 a3 = point3; + list.Add(a3 + b); + list.Add(a3 + b); + } + foreach (Vector2 point4 in Points) + { + Vector3 a4 = point4; + list.Add(a4 + Vector3.forward * extrude + b); + list.Add(a4 + Vector3.forward * extrude + b); + } + } + mesh.vertices = list.ToArray(); + if (useUVS) + { + List list2 = new List(); + float num3 = 0f; + Vector2 b2 = Points[Points.Count - 1]; + foreach (Vector2 point5 in Points) + { + num3 += (point5 - b2).magnitude; + b2 = point5; + } + if (front) + { + for (int i = 0; i < Points.Count; i++) + { + Vector2 vector = Points[i]; + list2.Add(new Vector2(vector.x * frontUVScale.x, vector.y * frontUVScale.y)); + } + } + if (back) + { + for (int j = 0; j < Points.Count; j++) + { + Vector2 vector2 = Points[j]; + list2.Add(new Vector2(vector2.x * backUVScale.x, vector2.y * backUVScale.y)); + } + } + if (sides) + { + for (int k = 0; k < 2; k++) + { + Vector2 b3 = Points[0]; + float num4 = 0f; + for (int l = 0; l < Points.Count; l++) + { + Vector2 vector3 = Points[l]; + num4 += (vector3 - b3).magnitude; + list2.Add(new Vector2((float)k * extrude * sideUVScale.x, ((l != 0) ? num4 : num3) * sideUVScale.y)); + list2.Add(new Vector2((float)k * extrude * sideUVScale.x, num4 * sideUVScale.y)); + b3 = vector3; + } + num4 += (Points[0] - b3).magnitude; + } + } + mesh.uv = list2.ToArray(); + } + List contour = new List(); + foreach (Vector2 point6 in Points) + { + Vector3 v = point6; + contour.Add(v); + } + List result = new List(); + Triangulate.Process(ref contour, ref result, out bool counterClockwise); + List list3 = new List(); + if (front) + { + list3.AddRange(result); + } + if (back) + { + for (int m = 0; m < result.Count; m += 3) + { + list3.Add(result[m + 2] + num); + list3.Add(result[m + 1] + num); + list3.Add(result[m] + num); + } + } + if (sides) + { + int item = num2 + Points.Count * 0 + Points.Count * 2 - 1; + int item2 = num2 + Points.Count * 2 + Points.Count * 2 - 1; + for (int n = 0; n < Points.Count; n++) + { + int num5 = num2 + Points.Count * 0 + n * 2; + int num6 = num2 + Points.Count * 2 + n * 2; + if (counterClockwise) + { + list3.Add(item); + list3.Add(num5); + list3.Add(item2); + list3.Add(num5); + list3.Add(num6); + list3.Add(item2); + } + else + { + list3.Add(item); + list3.Add(item2); + list3.Add(num5); + list3.Add(num5); + list3.Add(item2); + list3.Add(num6); + } + item = num5 + 1; + item2 = num6 + 1; + } + } + mesh.triangles = list3.ToArray(); + if (useNormals) + { + List list4 = new List(); + if (front) + { + for (int num7 = 0; num7 < Points.Count; num7++) + { + list4.Add(Vector3.back); + } + } + if (back) + { + for (int num8 = 0; num8 < Points.Count; num8++) + { + list4.Add(Vector3.forward); + } + } + if (sides) + { + for (int num9 = 0; num9 < 2; num9++) + { + for (int num10 = 0; num10 < Points.Count; num10++) + { + Vector2 a5 = Points[(num10 + Points.Count - 1) % Points.Count]; + Vector2 vector4 = Points[num10]; + Vector2 b4 = Points[(num10 + 1) % Points.Count]; + Vector2 normalized = (a5 - vector4).normalized; + Vector2 normalized2 = (vector4 - b4).normalized; + Vector2 vector5 = new Vector3(normalized.y, 0f - normalized.x, 0f).normalized; + Vector2 vector6 = new Vector3(normalized2.y, 0f - normalized2.x, 0f).normalized; + Vector2 vector7 = (vector5 + vector6).normalized; + if (counterClockwise) + { + vector7 *= -1f; + vector5 *= -1f; + vector6 *= -1f; + } + if (Vector2.Dot(vector5, vector6) > Mathf.Cos(0.0174532924f * SmoothAngle)) + { + list4.Add(vector7); + list4.Add(vector7); + } + else + { + list4.Add(vector5); + list4.Add(vector6); + } + } + } + } + mesh.normals = list4.ToArray(); + } + mesh.RecalculateBounds(); + return mesh; + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..2afd7bd5 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,5 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: AssemblyVersion("0.0.0.0")] diff --git a/PropertyBinding.cs b/PropertyBinding.cs new file mode 100644 index 00000000..d458a3fe --- /dev/null +++ b/PropertyBinding.cs @@ -0,0 +1,112 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Internal/Property Binding")] +[ExecuteInEditMode] +public class PropertyBinding : MonoBehaviour +{ + public enum UpdateCondition + { + OnStart, + OnUpdate, + OnLateUpdate, + OnFixedUpdate + } + + public enum Direction + { + SourceUpdatesTarget, + TargetUpdatesSource, + BiDirectional + } + + public PropertyReference source; + + public PropertyReference target; + + public Direction direction; + + public UpdateCondition update = UpdateCondition.OnUpdate; + + public bool editMode = true; + + private object mLastValue; + + private void Start() + { + UpdateTarget(); + if (update == UpdateCondition.OnStart) + { + base.enabled = false; + } + } + + private void Update() + { + if (update == UpdateCondition.OnUpdate) + { + UpdateTarget(); + } + } + + private void LateUpdate() + { + if (update == UpdateCondition.OnLateUpdate) + { + UpdateTarget(); + } + } + + private void FixedUpdate() + { + if (update == UpdateCondition.OnFixedUpdate) + { + UpdateTarget(); + } + } + + private void OnValidate() + { + if (source != null) + { + source.Reset(); + } + if (target != null) + { + target.Reset(); + } + } + + [ContextMenu("Update Now")] + public void UpdateTarget() + { + if (source != null && target != null && source.isValid && target.isValid) + { + if (direction == Direction.SourceUpdatesTarget) + { + target.Set(source.Get()); + } + else if (direction == Direction.TargetUpdatesSource) + { + source.Set(target.Get()); + } + else if (source.GetPropertyType() == target.GetPropertyType()) + { + object obj = source.Get(); + if (mLastValue == null || !mLastValue.Equals(obj)) + { + mLastValue = obj; + target.Set(obj); + } + else + { + obj = target.Get(); + if (!mLastValue.Equals(obj)) + { + mLastValue = obj; + source.Set(obj); + } + } + } + } + } +} diff --git a/PropertyReference.cs b/PropertyReference.cs new file mode 100644 index 00000000..75728450 --- /dev/null +++ b/PropertyReference.cs @@ -0,0 +1,326 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using UnityEngine; + +[Serializable] +public class PropertyReference +{ + [SerializeField] + private Component mTarget; + + [SerializeField] + private string mName; + + private FieldInfo mField; + + private PropertyInfo mProperty; + + private static int s_Hash = "PropertyBinding".GetHashCode(); + + public Component target + { + get + { + return mTarget; + } + set + { + mTarget = value; + mProperty = null; + mField = null; + } + } + + public string name + { + get + { + return mName; + } + set + { + mName = value; + mProperty = null; + mField = null; + } + } + + public bool isValid => mTarget != null && !string.IsNullOrEmpty(mName); + + public bool isEnabled + { + get + { + if (mTarget == null) + { + return false; + } + MonoBehaviour monoBehaviour = mTarget as MonoBehaviour; + return monoBehaviour == null || monoBehaviour.enabled; + } + } + + public PropertyReference() + { + } + + public PropertyReference(Component target, string fieldName) + { + mTarget = target; + mName = fieldName; + } + + public Type GetPropertyType() + { + if (mProperty == null && mField == null && isValid) + { + Cache(); + } + if (mProperty != null) + { + return mProperty.PropertyType; + } + if (mField != null) + { + return mField.FieldType; + } + return typeof(void); + } + + public override bool Equals(object obj) + { + if (obj == null) + { + return !isValid; + } + if (obj is PropertyReference) + { + PropertyReference propertyReference = obj as PropertyReference; + return mTarget == propertyReference.mTarget && string.Equals(mName, propertyReference.mName); + } + return false; + } + + public override int GetHashCode() + { + return s_Hash; + } + + public void Set(Component target, string methodName) + { + mTarget = target; + mName = methodName; + } + + public void Clear() + { + mTarget = null; + mName = null; + } + + public void Reset() + { + mField = null; + mProperty = null; + } + + public override string ToString() + { + return ToString(mTarget, name); + } + + public static string ToString(Component comp, string property) + { + if (comp != null) + { + string text = comp.GetType().ToString(); + int num = text.LastIndexOf('.'); + if (num > 0) + { + text = text.Substring(num + 1); + } + if (!string.IsNullOrEmpty(property)) + { + return text + "." + property; + } + return text + ".[property]"; + } + return null; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public object Get() + { + if (mProperty == null && mField == null && isValid) + { + Cache(); + } + if (mProperty != null) + { + if (mProperty.CanRead) + { + return mProperty.GetValue(mTarget, null); + } + } + else if (mField != null) + { + return mField.GetValue(mTarget); + } + return null; + } + + [DebuggerHidden] + [DebuggerStepThrough] + public bool Set(object value) + { + if (mProperty == null && mField == null && isValid) + { + Cache(); + } + if (mProperty == null && mField == null) + { + return false; + } + if (value == null) + { + try + { + if (mProperty == null) + { + mField.SetValue(mTarget, null); + return true; + } + if (mProperty.CanWrite) + { + mProperty.SetValue(mTarget, null, null); + return true; + } + } + catch (Exception) + { + return false; + IL_00a6:; + } + } + if (!Convert(ref value)) + { + if (Application.isPlaying) + { + UnityEngine.Debug.LogError("Unable to convert " + value.GetType() + " to " + GetPropertyType()); + } + } + else + { + if (mField != null) + { + mField.SetValue(mTarget, value); + return true; + } + if (mProperty.CanWrite) + { + mProperty.SetValue(mTarget, value, null); + return true; + } + } + return false; + } + + [DebuggerHidden] + [DebuggerStepThrough] + private bool Cache() + { + if (mTarget != null && !string.IsNullOrEmpty(mName)) + { + Type type = mTarget.GetType(); + mField = type.GetField(mName); + mProperty = type.GetProperty(mName); + } + else + { + mField = null; + mProperty = null; + } + return mField != null || mProperty != null; + } + + private bool Convert(ref object value) + { + if (mTarget == null) + { + return false; + } + Type propertyType = GetPropertyType(); + Type from; + if (value == null) + { + if (!propertyType.IsClass) + { + return false; + } + from = propertyType; + } + else + { + from = value.GetType(); + } + return Convert(ref value, from, propertyType); + } + + public static bool Convert(Type from, Type to) + { + object value = null; + return Convert(ref value, from, to); + } + + public static bool Convert(object value, Type to) + { + if (value == null) + { + value = null; + return Convert(ref value, to, to); + } + return Convert(ref value, value.GetType(), to); + } + + public static bool Convert(ref object value, Type from, Type to) + { + if (to.IsAssignableFrom(from)) + { + return true; + } + if (to == typeof(string)) + { + value = ((value == null) ? "null" : value.ToString()); + return true; + } + if (value == null) + { + return false; + } + float result2; + if (to == typeof(int)) + { + if (from == typeof(string)) + { + if (int.TryParse((string)value, out int result)) + { + value = result; + return true; + } + } + else if (from == typeof(float)) + { + value = Mathf.RoundToInt((float)value); + return true; + } + } + else if (to == typeof(float) && from == typeof(string) && float.TryParse((string)value, out result2)) + { + value = result2; + return true; + } + return false; + } +} diff --git a/Quad.cs b/Quad.cs new file mode 100644 index 00000000..b412460d --- /dev/null +++ b/Quad.cs @@ -0,0 +1,21 @@ +internal class Quad : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return c * (t /= d) * t + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return (0.0 - c) * (t /= d) * (t - 2.0) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * t * t + b; + } + return (0.0 - c) / 2.0 * ((t -= 1.0) * (t - 2.0) - 1.0) + b; + } +} diff --git a/Quart.cs b/Quart.cs new file mode 100644 index 00000000..d22f1822 --- /dev/null +++ b/Quart.cs @@ -0,0 +1,21 @@ +internal class Quart : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return c * (t /= d) * t * t * t + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return (0.0 - c) * ((t = t / d - 1.0) * t * t * t - 1.0) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * t * t * t * t + b; + } + return (0.0 - c) / 2.0 * ((t -= 2.0) * t * t * t - 2.0) + b; + } +} diff --git a/Quint.cs b/Quint.cs new file mode 100644 index 00000000..cc29cb5b --- /dev/null +++ b/Quint.cs @@ -0,0 +1,21 @@ +internal class Quint : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return c * (t /= d) * t * t * t * t + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return c * ((t = t / d - 1.0) * t * t * t * t + 1.0) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * t * t * t * t * t + b; + } + return c / 2.0 * ((t -= 2.0) * t * t * t * t + 2.0) + b; + } +} diff --git a/RealTime.cs b/RealTime.cs new file mode 100644 index 00000000..5f45e8de --- /dev/null +++ b/RealTime.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +public class RealTime : MonoBehaviour +{ + public static float time => Time.unscaledTime; + + public static float deltaTime => Time.unscaledDeltaTime; +} diff --git a/Rotator.cs b/Rotator.cs new file mode 100644 index 00000000..038a85fd --- /dev/null +++ b/Rotator.cs @@ -0,0 +1,45 @@ +using UnityEngine; + +public class Rotator : MonoBehaviour +{ + public float StartPos; + + public float EndPos = 360f; + + public float Duration = 1f; + + private float starttime; + + public bool EaseType; + + public void Reverse() + { + float startPos = StartPos; + StartPos = EndPos; + StartPos = startPos; + } + + public void Restart() + { + starttime = Time.time; + } + + private void Start() + { + starttime = Time.time; + } + + private void Update() + { + if (Time.time - starttime <= Duration) + { + float num = 0f; + num = (EaseType ? ((float)Quad.EaseOut((double)(Time.time - starttime), 0.0, 1.0, (double)Duration) * (EndPos - StartPos) + StartPos) : ((float)Quad.EaseInOut((double)(Time.time - starttime), 0.0, 1.0, (double)Duration) * (EndPos - StartPos) + StartPos)); + base.transform.localEulerAngles = new Vector3(0f, 0f, num); + } + else + { + base.transform.localEulerAngles = new Vector3(0f, 0f, EndPos); + } + } +} diff --git a/Sine.cs b/Sine.cs new file mode 100644 index 00000000..4cdd5e22 --- /dev/null +++ b/Sine.cs @@ -0,0 +1,19 @@ +using System; + +internal class Sine : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return (0.0 - c) * Math.Cos(t / d * 1.5707963267948966) + c + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return c * Math.Sin(t / d * 1.5707963267948966) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + return (0.0 - c) / 2.0 * (Math.Cos(3.1415926535897931 * t / d) - 1.0) + b; + } +} diff --git a/SpringPanel.cs b/SpringPanel.cs new file mode 100644 index 00000000..90bf7f84 --- /dev/null +++ b/SpringPanel.cs @@ -0,0 +1,78 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Internal/Spring Panel")] +[RequireComponent(typeof(UIPanel))] +public class SpringPanel : MonoBehaviour +{ + public delegate void OnFinished(); + + public static SpringPanel current; + + public Vector3 target = Vector3.zero; + + public float strength = 10f; + + public OnFinished onFinished; + + private UIPanel mPanel; + + private Transform mTrans; + + private UIScrollView mDrag; + + private void Start() + { + mPanel = GetComponent(); + mDrag = GetComponent(); + mTrans = base.transform; + } + + private void Update() + { + AdvanceTowardsPosition(); + } + + protected virtual void AdvanceTowardsPosition() + { + float deltaTime = RealTime.deltaTime; + bool flag = false; + Vector3 localPosition = mTrans.localPosition; + Vector3 vector = NGUIMath.SpringLerp(mTrans.localPosition, target, strength, deltaTime); + if ((vector - target).sqrMagnitude < 0.01f) + { + vector = target; + base.enabled = false; + flag = true; + } + mTrans.localPosition = vector; + Vector3 vector2 = vector - localPosition; + Vector2 clipOffset = mPanel.clipOffset; + clipOffset.x -= vector2.x; + clipOffset.y -= vector2.y; + mPanel.clipOffset = clipOffset; + if (mDrag != null) + { + mDrag.UpdateScrollbars(recalculateBounds: false); + } + if (flag && onFinished != null) + { + current = this; + onFinished(); + current = null; + } + } + + public static SpringPanel Begin(GameObject go, Vector3 pos, float strength) + { + SpringPanel springPanel = go.GetComponent(); + if (springPanel == null) + { + springPanel = go.AddComponent(); + } + springPanel.target = pos; + springPanel.strength = strength; + springPanel.onFinished = null; + springPanel.enabled = true; + return springPanel; + } +} diff --git a/SpringPosition.cs b/SpringPosition.cs new file mode 100644 index 00000000..ea74474e --- /dev/null +++ b/SpringPosition.cs @@ -0,0 +1,113 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Spring Position")] +public class SpringPosition : MonoBehaviour +{ + public delegate void OnFinished(); + + public static SpringPosition current; + + public Vector3 target = Vector3.zero; + + public float strength = 10f; + + public bool worldSpace; + + public bool ignoreTimeScale; + + public bool updateScrollView; + + public OnFinished onFinished; + + [HideInInspector] + [SerializeField] + private GameObject eventReceiver; + + [HideInInspector] + [SerializeField] + public string callWhenFinished; + + private Transform mTrans; + + private float mThreshold; + + private UIScrollView mSv; + + private void Start() + { + mTrans = base.transform; + if (updateScrollView) + { + mSv = NGUITools.FindInParents(base.gameObject); + } + } + + private void Update() + { + float deltaTime = (!ignoreTimeScale) ? Time.deltaTime : RealTime.deltaTime; + if (worldSpace) + { + if (mThreshold == 0f) + { + mThreshold = (target - mTrans.position).sqrMagnitude * 0.001f; + } + mTrans.position = NGUIMath.SpringLerp(mTrans.position, target, strength, deltaTime); + if (mThreshold >= (target - mTrans.position).sqrMagnitude) + { + mTrans.position = target; + NotifyListeners(); + base.enabled = false; + } + } + else + { + if (mThreshold == 0f) + { + mThreshold = (target - mTrans.localPosition).sqrMagnitude * 1E-05f; + } + mTrans.localPosition = NGUIMath.SpringLerp(mTrans.localPosition, target, strength, deltaTime); + if (mThreshold >= (target - mTrans.localPosition).sqrMagnitude) + { + mTrans.localPosition = target; + NotifyListeners(); + base.enabled = false; + } + } + if (mSv != null) + { + mSv.UpdateScrollbars(recalculateBounds: true); + } + } + + private void NotifyListeners() + { + current = this; + if (onFinished != null) + { + onFinished(); + } + if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished)) + { + eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver); + } + current = null; + } + + public static SpringPosition Begin(GameObject go, Vector3 pos, float strength) + { + SpringPosition springPosition = go.GetComponent(); + if (springPosition == null) + { + springPosition = go.AddComponent(); + } + springPosition.target = pos; + springPosition.strength = strength; + springPosition.onFinished = null; + if (!springPosition.enabled) + { + springPosition.mThreshold = 0f; + springPosition.enabled = true; + } + return springPosition; + } +} diff --git a/SpriteOptionButton.cs b/SpriteOptionButton.cs new file mode 100644 index 00000000..f8915f0c --- /dev/null +++ b/SpriteOptionButton.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class SpriteOptionButton : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/SteamManager.cs b/SteamManager.cs new file mode 100644 index 00000000..336da3cc --- /dev/null +++ b/SteamManager.cs @@ -0,0 +1,107 @@ +using Steamworks; +using System; +using System.Text; +using UnityEngine; + +[DisallowMultipleComponent] +internal class SteamManager : MonoBehaviour +{ + private static SteamManager s_instance; + + private static bool s_EverInialized; + + private bool m_bInitialized; + + private SteamAPIWarningMessageHook_t m_SteamAPIWarningMessageHook; + + private static SteamManager Instance => s_instance ?? new GameObject("SteamManager").AddComponent(); + + public static bool Initialized => Instance.m_bInitialized; + + private static void SteamAPIDebugTextHook(int nSeverity, StringBuilder pchDebugText) + { + Debug.LogWarning(pchDebugText); + } + + private void Awake() + { + if (s_instance != null) + { + UnityEngine.Object.Destroy(base.gameObject); + } + else + { + s_instance = this; + if (s_EverInialized) + { + throw new Exception("Tried to Initialize the SteamAPI twice in one session!"); + } + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + if (!Packsize.Test()) + { + Debug.LogError("[Steamworks.NET] Packsize Test returned false, the wrong version of Steamworks.NET is being run in this platform.", this); + } + if (!DllCheck.Test()) + { + Debug.LogError("[Steamworks.NET] DllCheck Test returned false, One or more of the Steamworks binaries seems to be the wrong version.", this); + } + try + { + if (SteamAPI.RestartAppIfNecessary(AppId_t.Invalid)) + { + Application.Quit(); + return; + } + } + catch (DllNotFoundException arg) + { + Debug.LogError("[Steamworks.NET] Could not load [lib]steam_api.dll/so/dylib. It's likely not in the correct location. Refer to the README for more details.\n" + arg, this); + Application.Quit(); + return; + IL_00a6:; + } + m_bInitialized = SteamAPI.Init(); + if (!m_bInitialized) + { + Debug.LogError("[Steamworks.NET] SteamAPI_Init() failed. Refer to Valve's documentation or the comment above this line for more information.", this); + } + else + { + s_EverInialized = true; + } + } + } + + private void OnEnable() + { + if (s_instance == null) + { + s_instance = this; + } + if (m_bInitialized && m_SteamAPIWarningMessageHook == null) + { + m_SteamAPIWarningMessageHook = SteamAPIDebugTextHook; + SteamClient.SetWarningMessageHook(m_SteamAPIWarningMessageHook); + } + } + + private void OnDestroy() + { + if (!(s_instance != this)) + { + s_instance = null; + if (m_bInitialized) + { + SteamAPI.Shutdown(); + } + } + } + + private void Update() + { + if (m_bInitialized) + { + SteamAPI.RunCallbacks(); + } + } +} diff --git a/Strong.cs b/Strong.cs new file mode 100644 index 00000000..81fa29e6 --- /dev/null +++ b/Strong.cs @@ -0,0 +1,21 @@ +internal class Strong : Ease +{ + public static double EaseIn(double t, double b, double c, double d) + { + return c * (t /= d) * t * t * t * t + b; + } + + public static double EaseOut(double t, double b, double c, double d) + { + return c * ((t = t / d - 1.0) * t * t * t * t + 1.0) + b; + } + + public static double EaseInOut(double t, double b, double c, double d) + { + if ((t /= d / 2.0) < 1.0) + { + return c / 2.0 * t * t * t * t * t + b; + } + return c / 2.0 * ((t -= 2.0) * t * t * t * t + 2.0) + b; + } +} diff --git a/System.Runtime.Serialization/DataContractAttribute.cs b/System.Runtime.Serialization/DataContractAttribute.cs new file mode 100644 index 00000000..874b8b19 --- /dev/null +++ b/System.Runtime.Serialization/DataContractAttribute.cs @@ -0,0 +1,40 @@ +namespace System.Runtime.Serialization +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)] + public sealed class DataContractAttribute : Attribute + { + private string name; + + private string ns; + + public string Name + { + get + { + return name; + } + set + { + name = value; + } + } + + public string Namespace + { + get + { + return ns; + } + set + { + ns = value; + } + } + + public bool IsReference + { + get; + set; + } + } +} diff --git a/System.Runtime.Serialization/DataMemberAttribute.cs b/System.Runtime.Serialization/DataMemberAttribute.cs new file mode 100644 index 00000000..1e43c9a9 --- /dev/null +++ b/System.Runtime.Serialization/DataMemberAttribute.cs @@ -0,0 +1,62 @@ +namespace System.Runtime.Serialization +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class DataMemberAttribute : Attribute + { + private bool is_required; + + private bool emit_default = true; + + private string name; + + private int order = -1; + + public bool EmitDefaultValue + { + get + { + return emit_default; + } + set + { + emit_default = value; + } + } + + public bool IsRequired + { + get + { + return is_required; + } + set + { + is_required = value; + } + } + + public string Name + { + get + { + return name; + } + set + { + name = value; + } + } + + public int Order + { + get + { + return order; + } + set + { + order = value; + } + } + } +} diff --git a/System.Runtime.Serialization/EnumMemberAttribute.cs b/System.Runtime.Serialization/EnumMemberAttribute.cs new file mode 100644 index 00000000..ab10bbc5 --- /dev/null +++ b/System.Runtime.Serialization/EnumMemberAttribute.cs @@ -0,0 +1,20 @@ +namespace System.Runtime.Serialization +{ + [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class EnumMemberAttribute : Attribute + { + private string value; + + public string Value + { + get + { + return value; + } + set + { + this.value = value; + } + } + } +} diff --git a/TMPro/Compute_DT_EventArgs.cs b/TMPro/Compute_DT_EventArgs.cs new file mode 100644 index 00000000..2513ef7f --- /dev/null +++ b/TMPro/Compute_DT_EventArgs.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +namespace TMPro +{ + public class Compute_DT_EventArgs + { + public Compute_DistanceTransform_EventTypes EventType; + + public float ProgressPercentage; + + public Color[] Colors; + + public Compute_DT_EventArgs(Compute_DistanceTransform_EventTypes type, float progress) + { + EventType = type; + ProgressPercentage = progress; + } + + public Compute_DT_EventArgs(Compute_DistanceTransform_EventTypes type, Color[] colors) + { + EventType = type; + Colors = colors; + } + } +} diff --git a/TMPro/Compute_DistanceTransform_EventTypes.cs b/TMPro/Compute_DistanceTransform_EventTypes.cs new file mode 100644 index 00000000..dceb3f7b --- /dev/null +++ b/TMPro/Compute_DistanceTransform_EventTypes.cs @@ -0,0 +1,8 @@ +namespace TMPro +{ + public enum Compute_DistanceTransform_EventTypes + { + Processing, + Completed + } +} diff --git a/TMPro/Extents.cs b/TMPro/Extents.cs new file mode 100644 index 00000000..e7f6b058 --- /dev/null +++ b/TMPro/Extents.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +namespace TMPro +{ + public struct Extents + { + public Vector2 min; + + public Vector2 max; + + public Extents(Vector2 min, Vector2 max) + { + this.min = min; + this.max = max; + } + + public override string ToString() + { + return "Min (" + min.x.ToString("f2") + ", " + min.y.ToString("f2") + ") Max (" + max.x.ToString("f2") + ", " + max.y.ToString("f2") + ")"; + } + } +} diff --git a/TMPro/FaceInfo.cs b/TMPro/FaceInfo.cs new file mode 100644 index 00000000..8020d43f --- /dev/null +++ b/TMPro/FaceInfo.cs @@ -0,0 +1,42 @@ +using System; + +namespace TMPro +{ + [Serializable] + public class FaceInfo + { + public string Name; + + public float PointSize; + + public float Padding; + + public float LineHeight; + + public float Baseline; + + public float Ascender; + + public float Descender; + + public float CenterLine; + + public float SuperscriptOffset; + + public float SubscriptOffset; + + public float SubSize; + + public float Underline; + + public float UnderlineThickness; + + public float TabWidth; + + public int CharacterCount; + + public float AtlasWidth; + + public float AtlasHeight; + } +} diff --git a/TMPro/FontCreationSetting.cs b/TMPro/FontCreationSetting.cs new file mode 100644 index 00000000..7fbba310 --- /dev/null +++ b/TMPro/FontCreationSetting.cs @@ -0,0 +1,32 @@ +using System; + +namespace TMPro +{ + [Serializable] + public struct FontCreationSetting + { + public string fontSourcePath; + + public int fontSizingMode; + + public int fontSize; + + public int fontPadding; + + public int fontPackingMode; + + public int fontAtlasWidth; + + public int fontAtlasHeight; + + public int fontCharacterSet; + + public int fontStyle; + + public float fontStlyeModifier; + + public int fontRenderMode; + + public bool fontKerning; + } +} diff --git a/TMPro/FontStyles.cs b/TMPro/FontStyles.cs new file mode 100644 index 00000000..19d06571 --- /dev/null +++ b/TMPro/FontStyles.cs @@ -0,0 +1,35 @@ +namespace TMPro +{ + public enum FontStyles + { + Normal = 0, + Bold = 1, + Italic = 2, + Underline = 4, + LowerCase = 8, + UpperCase = 0x10, + SmallCaps = 0x20, + BoldItalic = 3, + BoldUnderline = 5, + BoldItalicUnderline = 7, + ItalicUnderline = 6, + LowerCaseBold = 9, + LowerCaseItalic = 10, + LowerCaseUnderline = 12, + LowerCaseBoldItalic = 11, + LowerCaseBoldUnderline = 13, + LowerCaseBoldItalicUnderline = 0xF, + UpperCaseBold = 17, + UpperCaseItalic = 18, + UpperCaseUnderline = 20, + UpperCaseBoldItalic = 19, + UpperCaseBoldUnderline = 21, + UpperCaseBoltItalicUnderline = 23, + SmallCapsBold = 33, + SmallCapsItalic = 34, + SmallCapsUnderline = 36, + SmallCapsBoldItalic = 35, + SmallCapsBoldUnderline = 37, + SmallCapsBoldItalicUnderline = 39 + } +} diff --git a/TMPro/Glyph2D.cs b/TMPro/Glyph2D.cs new file mode 100644 index 00000000..e61ca8be --- /dev/null +++ b/TMPro/Glyph2D.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +namespace TMPro +{ + [Serializable] + public class Glyph2D + { + public Vector3 bottomLeft; + + public Vector3 topLeft; + + public Vector3 bottomRight; + + public Vector3 topRight; + + public Vector2 uv0; + + public Vector2 uv1; + + public Vector2 uv2; + + public Vector2 uv3; + } +} diff --git a/TMPro/GlyphInfo.cs b/TMPro/GlyphInfo.cs new file mode 100644 index 00000000..c4faa1bf --- /dev/null +++ b/TMPro/GlyphInfo.cs @@ -0,0 +1,24 @@ +using System; + +namespace TMPro +{ + [Serializable] + public class GlyphInfo + { + public int id; + + public float x; + + public float y; + + public float width; + + public float height; + + public float xOffset; + + public float yOffset; + + public float xAdvance; + } +} diff --git a/TMPro/KerningPair.cs b/TMPro/KerningPair.cs new file mode 100644 index 00000000..185a7462 --- /dev/null +++ b/TMPro/KerningPair.cs @@ -0,0 +1,21 @@ +using System; + +namespace TMPro +{ + [Serializable] + public class KerningPair + { + public int AscII_Left; + + public int AscII_Right; + + public float XadvanceOffset; + + public KerningPair(int left, int right, float offset) + { + AscII_Left = left; + AscII_Right = right; + XadvanceOffset = offset; + } + } +} diff --git a/TMPro/KerningPairKey.cs b/TMPro/KerningPairKey.cs new file mode 100644 index 00000000..da34b490 --- /dev/null +++ b/TMPro/KerningPairKey.cs @@ -0,0 +1,18 @@ +namespace TMPro +{ + public struct KerningPairKey + { + public int ascii_Left; + + public int ascii_Right; + + public int key; + + public KerningPairKey(int ascii_left, int ascii_right) + { + ascii_Left = ascii_left; + ascii_Right = ascii_right; + key = (ascii_right << 16) + ascii_left; + } + } +} diff --git a/TMPro/KerningTable.cs b/TMPro/KerningTable.cs new file mode 100644 index 00000000..20c73e90 --- /dev/null +++ b/TMPro/KerningTable.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TMPro +{ + [Serializable] + public class KerningTable + { + public List kerningPairs; + + public KerningTable() + { + kerningPairs = new List(); + } + + public void AddKerningPair() + { + if (kerningPairs.Count == 0) + { + kerningPairs.Add(new KerningPair(0, 0, 0f)); + } + else + { + int ascII_Left = kerningPairs.Last().AscII_Left; + int ascII_Right = kerningPairs.Last().AscII_Right; + float xadvanceOffset = kerningPairs.Last().XadvanceOffset; + kerningPairs.Add(new KerningPair(ascII_Left, ascII_Right, xadvanceOffset)); + } + } + + public int AddKerningPair(int left, int right, float offset) + { + int num = kerningPairs.FindIndex((KerningPair item) => item.AscII_Left == left && item.AscII_Right == right); + if (num == -1) + { + kerningPairs.Add(new KerningPair(left, right, offset)); + return 0; + } + return -1; + } + + public void RemoveKerningPair(int left, int right) + { + int num = kerningPairs.FindIndex((KerningPair item) => item.AscII_Left == left && item.AscII_Right == right); + if (num != -1) + { + kerningPairs.RemoveAt(num); + } + } + + public void RemoveKerningPair(int index) + { + kerningPairs.RemoveAt(index); + } + + public void SortKerningPairs() + { + if (kerningPairs.Count > 0) + { + kerningPairs = (from s in kerningPairs + orderby s.AscII_Left, s.AscII_Right + select s).ToList(); + } + } + } +} diff --git a/TMPro/LineBreakingTable.cs b/TMPro/LineBreakingTable.cs new file mode 100644 index 00000000..15702756 --- /dev/null +++ b/TMPro/LineBreakingTable.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace TMPro +{ + [Serializable] + public class LineBreakingTable + { + public Dictionary leadingCharacters; + + public Dictionary followingCharacters; + + public LineBreakingTable() + { + leadingCharacters = new Dictionary(); + followingCharacters = new Dictionary(); + } + } +} diff --git a/TMPro/LineWrapState.cs b/TMPro/LineWrapState.cs new file mode 100644 index 00000000..6dfefe9a --- /dev/null +++ b/TMPro/LineWrapState.cs @@ -0,0 +1,43 @@ +using UnityEngine; + +namespace TMPro +{ + public struct LineWrapState + { + public int previous_LineBreak; + + public int total_CharacterCount; + + public int visible_CharacterCount; + + public int visible_SpriteCount; + + public float maxAscender; + + public float maxDescender; + + public float maxFontScale; + + public int wordCount; + + public FontStyles fontStyle; + + public float fontScale; + + public float xAdvance; + + public float currentFontSize; + + public float baselineOffset; + + public float lineOffset; + + public TMP_TextInfo textInfo; + + public TMP_LineInfo lineInfo; + + public Color32 vertexColor; + + public Extents meshExtents; + } +} diff --git a/TMPro/MaskingOffsetMode.cs b/TMPro/MaskingOffsetMode.cs new file mode 100644 index 00000000..8c649aae --- /dev/null +++ b/TMPro/MaskingOffsetMode.cs @@ -0,0 +1,8 @@ +namespace TMPro +{ + public enum MaskingOffsetMode + { + Percentage, + Pixel + } +} diff --git a/TMPro/MaskingTypes.cs b/TMPro/MaskingTypes.cs new file mode 100644 index 00000000..565a03e3 --- /dev/null +++ b/TMPro/MaskingTypes.cs @@ -0,0 +1,9 @@ +namespace TMPro +{ + public enum MaskingTypes + { + MaskOff, + MaskHard, + MaskSoft + } +} diff --git a/TMPro/Mesh_Extents.cs b/TMPro/Mesh_Extents.cs new file mode 100644 index 00000000..72eee189 --- /dev/null +++ b/TMPro/Mesh_Extents.cs @@ -0,0 +1,24 @@ +using System; +using UnityEngine; + +namespace TMPro +{ + [Serializable] + public struct Mesh_Extents + { + public Vector2 min; + + public Vector2 max; + + public Mesh_Extents(Vector2 min, Vector2 max) + { + this.min = min; + this.max = max; + } + + public override string ToString() + { + return "Min (" + min.x.ToString("f2") + ", " + min.y.ToString("f2") + ") Max (" + max.x.ToString("f2") + ", " + max.y.ToString("f2") + ")"; + } + } +} diff --git a/TMPro/ShaderUtilities.cs b/TMPro/ShaderUtilities.cs new file mode 100644 index 00000000..2554de44 --- /dev/null +++ b/TMPro/ShaderUtilities.cs @@ -0,0 +1,398 @@ +using System.Linq; +using UnityEngine; + +namespace TMPro +{ + public static class ShaderUtilities + { + public static int ID_MainTex; + + public static int ID_FaceColor; + + public static int ID_FaceDilate; + + public static int ID_Shininess; + + public static int ID_UnderlayOffsetX; + + public static int ID_UnderlayOffsetY; + + public static int ID_UnderlayDilate; + + public static int ID_UnderlaySoftness; + + public static int ID_WeightNormal; + + public static int ID_WeightBold; + + public static int ID_OutlineWidth; + + public static int ID_OutlineSoftness; + + public static int ID_OutlineColor; + + public static int ID_GradientScale; + + public static int ID_ScaleX; + + public static int ID_ScaleY; + + public static int ID_PerspectiveFilter; + + public static int ID_TextureWidth; + + public static int ID_TextureHeight; + + public static int ID_BevelAmount; + + public static int ID_GlowColor; + + public static int ID_GlowOffset; + + public static int ID_GlowPower; + + public static int ID_GlowOuter; + + public static int ID_LightAngle; + + public static int ID_EnvMap; + + public static int ID_EnvMatrix; + + public static int ID_EnvMatrixRotation; + + public static int ID_MaskID; + + public static int ID_MaskCoord; + + public static int ID_MaskSoftnessX; + + public static int ID_MaskSoftnessY; + + public static int ID_VertexOffsetX; + + public static int ID_VertexOffsetY; + + public static int ID_StencilID; + + public static int ID_StencilComp; + + public static int ID_ShaderFlags; + + public static int ID_ScaleRatio_A; + + public static int ID_ScaleRatio_B; + + public static int ID_ScaleRatio_C; + + public static string Keyword_Bevel = "BEVEL_ON"; + + public static string Keyword_Glow = "GLOW_ON"; + + public static string Keyword_Underlay = "UNDERLAY_ON"; + + public static string Keyword_Ratios = "RATIOS_OFF"; + + public static string Keyword_MaskSoft = "MASK_SOFT"; + + public static string Keyword_MaskHard = "MASK_HARD"; + + private static float m_clamp = 1f; + + public static bool isInitialized; + + public static void GetShaderPropertyIDs() + { + if (!isInitialized) + { + isInitialized = true; + ID_MainTex = Shader.PropertyToID("_MainTex"); + ID_FaceColor = Shader.PropertyToID("_FaceColor"); + ID_FaceDilate = Shader.PropertyToID("_FaceDilate"); + ID_Shininess = Shader.PropertyToID("_FaceShininess"); + ID_UnderlayOffsetX = Shader.PropertyToID("_UnderlayOffsetX"); + ID_UnderlayOffsetY = Shader.PropertyToID("_UnderlayOffsetY"); + ID_UnderlayDilate = Shader.PropertyToID("_UnderlayDilate"); + ID_UnderlaySoftness = Shader.PropertyToID("_UnderlaySoftness"); + ID_WeightNormal = Shader.PropertyToID("_WeightNormal"); + ID_WeightBold = Shader.PropertyToID("_WeightBold"); + ID_OutlineWidth = Shader.PropertyToID("_OutlineWidth"); + ID_OutlineSoftness = Shader.PropertyToID("_OutlineSoftness"); + ID_OutlineColor = Shader.PropertyToID("_OutlineColor"); + ID_GradientScale = Shader.PropertyToID("_GradientScale"); + ID_ScaleX = Shader.PropertyToID("_ScaleX"); + ID_ScaleY = Shader.PropertyToID("_ScaleY"); + ID_PerspectiveFilter = Shader.PropertyToID("_PerspectiveFilter"); + ID_TextureWidth = Shader.PropertyToID("_TextureWidth"); + ID_TextureHeight = Shader.PropertyToID("_TextureHeight"); + ID_BevelAmount = Shader.PropertyToID("_Bevel"); + ID_LightAngle = Shader.PropertyToID("_LightAngle"); + ID_EnvMap = Shader.PropertyToID("_Cube"); + ID_EnvMatrix = Shader.PropertyToID("_EnvMatrix"); + ID_EnvMatrixRotation = Shader.PropertyToID("_EnvMatrixRotation"); + ID_GlowColor = Shader.PropertyToID("_GlowColor"); + ID_GlowOffset = Shader.PropertyToID("_GlowOffset"); + ID_GlowPower = Shader.PropertyToID("_GlowPower"); + ID_GlowOuter = Shader.PropertyToID("_GlowOuter"); + ID_MaskID = Shader.PropertyToID("_MaskID"); + ID_MaskCoord = Shader.PropertyToID("_MaskCoord"); + ID_MaskSoftnessX = Shader.PropertyToID("_MaskSoftnessX"); + ID_MaskSoftnessY = Shader.PropertyToID("_MaskSoftnessY"); + ID_VertexOffsetX = Shader.PropertyToID("_VertexOffsetX"); + ID_VertexOffsetY = Shader.PropertyToID("_VertexOffsetY"); + ID_StencilID = Shader.PropertyToID("_Stencil"); + ID_StencilComp = Shader.PropertyToID("_StencilComp"); + ID_ShaderFlags = Shader.PropertyToID("_ShaderFlags"); + ID_ScaleRatio_A = Shader.PropertyToID("_ScaleRatioA"); + ID_ScaleRatio_B = Shader.PropertyToID("_ScaleRatioB"); + ID_ScaleRatio_C = Shader.PropertyToID("_ScaleRatioC"); + } + } + + public static void UpdateShaderRatios(Material mat, bool isBold) + { + float num = 1f; + float num2 = 1f; + float num3 = 1f; + bool flag = !mat.shaderKeywords.Contains(Keyword_Ratios); + float @float = mat.GetFloat(ID_GradientScale); + float float2 = mat.GetFloat(ID_FaceDilate); + float float3 = mat.GetFloat(ID_OutlineWidth); + float float4 = mat.GetFloat(ID_OutlineSoftness); + float num4 = isBold ? (mat.GetFloat(ID_WeightBold) * 2f / @float) : (mat.GetFloat(ID_WeightNormal) * 2f / @float); + float num5 = Mathf.Max(1f, num4 + float2 + float3 + float4); + num = ((!flag) ? 1f : ((@float - m_clamp) / (@float * num5))); + mat.SetFloat(ID_ScaleRatio_A, num); + if (mat.HasProperty(ID_GlowOffset)) + { + float float5 = mat.GetFloat(ID_GlowOffset); + float float6 = mat.GetFloat(ID_GlowOuter); + float num6 = (num4 + float2) * (@float - m_clamp); + num5 = Mathf.Max(1f, float5 + float6); + num2 = ((!flag) ? 1f : (Mathf.Max(0f, @float - m_clamp - num6) / (@float * num5))); + mat.SetFloat(ID_ScaleRatio_B, num2); + } + if (mat.HasProperty(ID_UnderlayOffsetX)) + { + float float7 = mat.GetFloat(ID_UnderlayOffsetX); + float float8 = mat.GetFloat(ID_UnderlayOffsetY); + float float9 = mat.GetFloat(ID_UnderlayDilate); + float float10 = mat.GetFloat(ID_UnderlaySoftness); + float num7 = (num4 + float2) * (@float - m_clamp); + num5 = Mathf.Max(1f, Mathf.Max(Mathf.Abs(float7), Mathf.Abs(float8)) + float9 + float10); + num3 = ((!flag) ? 1f : (Mathf.Max(0f, @float - m_clamp - num7) / (@float * num5))); + mat.SetFloat(ID_ScaleRatio_C, num3); + } + } + + public static Vector4 GetFontExtent(Material material) + { + if (!material.HasProperty(ID_GradientScale)) + { + return Vector4.zero; + } + float @float = material.GetFloat(ID_ScaleRatio_A); + float num = material.GetFloat(ID_FaceDilate) * @float; + float num2 = material.GetFloat(ID_OutlineWidth) * @float; + float num3 = Mathf.Min(1f, num + num2); + num3 *= material.GetFloat(ID_GradientScale); + return new Vector4(num3, num3, num3, num3); + } + + public static bool IsMaskingEnabled(Material material) + { + if (!material.HasProperty(ID_MaskCoord)) + { + return false; + } + if (material.shaderKeywords.Contains(Keyword_MaskSoft) || material.shaderKeywords.Contains(Keyword_MaskHard)) + { + return true; + } + return false; + } + + public static float GetPadding(Material material, bool enableExtraPadding, bool isBold) + { + if (!isInitialized) + { + GetShaderPropertyIDs(); + } + int num = enableExtraPadding ? 4 : 0; + if (!material.HasProperty(ID_GradientScale)) + { + return (float)num; + } + Vector4 a = Vector4.zero; + Vector4 zero = Vector4.zero; + float num2 = 0f; + float num3 = 0f; + float num4 = 0f; + float num5 = 0f; + float num6 = 0f; + float num7 = 0f; + float num8 = 0f; + float num9 = 0f; + float num10 = 0f; + UpdateShaderRatios(material, isBold); + string[] shaderKeywords = material.shaderKeywords; + if (material.HasProperty(ID_ScaleRatio_A)) + { + num5 = material.GetFloat(ID_ScaleRatio_A); + } + if (material.HasProperty(ID_FaceDilate)) + { + num2 = material.GetFloat(ID_FaceDilate) * num5; + } + if (material.HasProperty(ID_OutlineSoftness)) + { + num3 = material.GetFloat(ID_OutlineSoftness) * num5; + } + if (material.HasProperty(ID_OutlineWidth)) + { + num4 = material.GetFloat(ID_OutlineWidth) * num5; + } + num10 = num4 + num3 + num2; + if (material.HasProperty(ID_GlowOffset) && shaderKeywords.Contains(Keyword_Glow)) + { + if (material.HasProperty(ID_ScaleRatio_B)) + { + num6 = material.GetFloat(ID_ScaleRatio_B); + } + num8 = material.GetFloat(ID_GlowOffset) * num6; + num9 = material.GetFloat(ID_GlowOuter) * num6; + } + num10 = Mathf.Max(num10, num2 + num8 + num9); + if (material.HasProperty(ID_UnderlaySoftness) && shaderKeywords.Contains(Keyword_Underlay)) + { + if (material.HasProperty(ID_ScaleRatio_C)) + { + num7 = material.GetFloat(ID_ScaleRatio_C); + } + float num11 = material.GetFloat(ID_UnderlayOffsetX) * num7; + float num12 = material.GetFloat(ID_UnderlayOffsetY) * num7; + float num13 = material.GetFloat(ID_UnderlayDilate) * num7; + float num14 = material.GetFloat(ID_UnderlaySoftness) * num7; + a.x = Mathf.Max(a.x, num2 + num13 + num14 - num11); + a.y = Mathf.Max(a.y, num2 + num13 + num14 - num12); + a.z = Mathf.Max(a.z, num2 + num13 + num14 + num11); + a.w = Mathf.Max(a.w, num2 + num13 + num14 + num12); + } + a.x = Mathf.Max(a.x, num10); + a.y = Mathf.Max(a.y, num10); + a.z = Mathf.Max(a.z, num10); + a.w = Mathf.Max(a.w, num10); + a.x += (float)num; + a.y += (float)num; + a.z += (float)num; + a.w += (float)num; + a.x = Mathf.Min(a.x, 1f); + a.y = Mathf.Min(a.y, 1f); + a.z = Mathf.Min(a.z, 1f); + a.w = Mathf.Min(a.w, 1f); + zero.x = ((!(zero.x < a.x)) ? zero.x : a.x); + zero.y = ((!(zero.y < a.y)) ? zero.y : a.y); + zero.z = ((!(zero.z < a.z)) ? zero.z : a.z); + zero.w = ((!(zero.w < a.w)) ? zero.w : a.w); + float @float = material.GetFloat(ID_GradientScale); + a *= @float; + num10 = Mathf.Max(a.x, a.y); + num10 = Mathf.Max(a.z, num10); + num10 = Mathf.Max(a.w, num10); + return num10 + 0.25f; + } + + public static float GetPadding(Material[] materials, bool enableExtraPadding, bool isBold) + { + if (!isInitialized) + { + GetShaderPropertyIDs(); + } + int num = enableExtraPadding ? 4 : 0; + if (!materials[0].HasProperty(ID_GradientScale)) + { + return (float)num; + } + Vector4 a = Vector4.zero; + Vector4 zero = Vector4.zero; + float num2 = 0f; + float num3 = 0f; + float num4 = 0f; + float num5 = 0f; + float num6 = 0f; + float num7 = 0f; + float num8 = 0f; + float num9 = 0f; + float num10 = 0f; + for (int i = 0; i < materials.Length; i++) + { + UpdateShaderRatios(materials[i], isBold); + string[] shaderKeywords = materials[i].shaderKeywords; + if (materials[i].HasProperty(ID_ScaleRatio_A)) + { + num5 = materials[i].GetFloat(ID_ScaleRatio_A); + } + if (materials[i].HasProperty(ID_FaceDilate)) + { + num2 = materials[i].GetFloat(ID_FaceDilate) * num5; + } + if (materials[i].HasProperty(ID_OutlineSoftness)) + { + num3 = materials[i].GetFloat(ID_OutlineSoftness) * num5; + } + if (materials[i].HasProperty(ID_OutlineWidth)) + { + num4 = materials[i].GetFloat(ID_OutlineWidth) * num5; + } + num10 = num4 + num3 + num2; + if (materials[i].HasProperty(ID_GlowOffset) && shaderKeywords.Contains(Keyword_Glow)) + { + if (materials[i].HasProperty(ID_ScaleRatio_B)) + { + num6 = materials[i].GetFloat(ID_ScaleRatio_B); + } + num8 = materials[i].GetFloat(ID_GlowOffset) * num6; + num9 = materials[i].GetFloat(ID_GlowOuter) * num6; + } + num10 = Mathf.Max(num10, num2 + num8 + num9); + if (materials[i].HasProperty(ID_UnderlaySoftness) && shaderKeywords.Contains(Keyword_Underlay)) + { + if (materials[i].HasProperty(ID_ScaleRatio_C)) + { + num7 = materials[i].GetFloat(ID_ScaleRatio_C); + } + float num11 = materials[i].GetFloat(ID_UnderlayOffsetX) * num7; + float num12 = materials[i].GetFloat(ID_UnderlayOffsetY) * num7; + float num13 = materials[i].GetFloat(ID_UnderlayDilate) * num7; + float num14 = materials[i].GetFloat(ID_UnderlaySoftness) * num7; + a.x = Mathf.Max(a.x, num2 + num13 + num14 - num11); + a.y = Mathf.Max(a.y, num2 + num13 + num14 - num12); + a.z = Mathf.Max(a.z, num2 + num13 + num14 + num11); + a.w = Mathf.Max(a.w, num2 + num13 + num14 + num12); + } + a.x = Mathf.Max(a.x, num10); + a.y = Mathf.Max(a.y, num10); + a.z = Mathf.Max(a.z, num10); + a.w = Mathf.Max(a.w, num10); + a.x += (float)num; + a.y += (float)num; + a.z += (float)num; + a.w += (float)num; + a.x = Mathf.Min(a.x, 1f); + a.y = Mathf.Min(a.y, 1f); + a.z = Mathf.Min(a.z, 1f); + a.w = Mathf.Min(a.w, 1f); + zero.x = ((!(zero.x < a.x)) ? zero.x : a.x); + zero.y = ((!(zero.y < a.y)) ? zero.y : a.y); + zero.z = ((!(zero.z < a.z)) ? zero.z : a.z); + zero.w = ((!(zero.w < a.w)) ? zero.w : a.w); + } + float @float = materials[0].GetFloat(ID_GradientScale); + a *= @float; + num10 = Mathf.Max(a.x, a.y); + num10 = Mathf.Max(a.z, num10); + num10 = Mathf.Max(a.w, num10); + return num10 + 0.25f; + } + } +} diff --git a/TMPro/SpriteAsset.cs b/TMPro/SpriteAsset.cs new file mode 100644 index 00000000..596b3f30 --- /dev/null +++ b/TMPro/SpriteAsset.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace TMPro +{ + public class SpriteAsset : ScriptableObject + { + public Texture spriteSheet; + + public Material material; + + public List spriteInfoList; + + private List m_sprites; + + private void OnEnable() + { + } + + public void AddSprites(string path) + { + } + + private void OnValidate() + { + TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(/*isChanged:*/ true, this); + } + } +} diff --git a/TMPro/SpriteInfo.cs b/TMPro/SpriteInfo.cs new file mode 100644 index 00000000..5d19bdd2 --- /dev/null +++ b/TMPro/SpriteInfo.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine; + +namespace TMPro +{ + [Serializable] + public class SpriteInfo + { + public int id; + + public string name; + + public float x; + + public float y; + + public float width; + + public float height; + + public Vector2 pivot; + + public float xOffset; + + public float yOffset; + + public float xAdvance; + + public float scale; + + public Sprite sprite; + } +} diff --git a/TMPro/TMP_CharacterInfo.cs b/TMPro/TMP_CharacterInfo.cs new file mode 100644 index 00000000..eb3a7055 --- /dev/null +++ b/TMPro/TMP_CharacterInfo.cs @@ -0,0 +1,57 @@ +using UnityEngine; + +namespace TMPro +{ + public struct TMP_CharacterInfo + { + public TMP_CharacterType type; + + public char character; + + public short lineNumber; + + public short pageNumber; + + public short index; + + public int meshIndex; + + public short vertexIndex; + + public TMP_Vertex vertex_TL; + + public TMP_Vertex vertex_BL; + + public TMP_Vertex vertex_TR; + + public TMP_Vertex vertex_BR; + + public Vector3 topLeft; + + public Vector3 bottomLeft; + + public Vector3 topRight; + + public Vector3 bottomRight; + + public float topLine; + + public float baseLine; + + public float bottomLine; + + public float xAdvance; + + public float aspectRatio; + + public float padding; + + public float scale; + + public Color32 color; + + public FontStyles style; + + public bool isVisible; + } +} diff --git a/TMPro/TMP_CharacterType.cs b/TMPro/TMP_CharacterType.cs new file mode 100644 index 00000000..8652bf14 --- /dev/null +++ b/TMPro/TMP_CharacterType.cs @@ -0,0 +1,8 @@ +namespace TMPro +{ + public enum TMP_CharacterType + { + Character, + Sprite + } +} diff --git a/TMPro/TMP_Compatibility.cs b/TMPro/TMP_Compatibility.cs new file mode 100644 index 00000000..f1249e4a --- /dev/null +++ b/TMPro/TMP_Compatibility.cs @@ -0,0 +1,19 @@ +namespace TMPro +{ + public static class TMP_Compatibility + { + public enum AnchorPositions + { + TopLeft, + Top, + TopRight, + Left, + Center, + Right, + BottomLeft, + Bottom, + BottomRight, + BaseLine + } + } +} diff --git a/TMPro/TMP_LineInfo.cs b/TMPro/TMP_LineInfo.cs new file mode 100644 index 00000000..ce819637 --- /dev/null +++ b/TMPro/TMP_LineInfo.cs @@ -0,0 +1,31 @@ +namespace TMPro +{ + public struct TMP_LineInfo + { + public int characterCount; + + public int spaceCount; + + public int wordCount; + + public int firstCharacterIndex; + + public int lastCharacterIndex; + + public int lastVisibleCharacterIndex; + + public float lineLength; + + public float lineHeight; + + public float ascender; + + public float descender; + + public float maxAdvance; + + public TextAlignmentOptions alignment; + + public Extents lineExtents; + } +} diff --git a/TMPro/TMP_MeshInfo.cs b/TMPro/TMP_MeshInfo.cs new file mode 100644 index 00000000..645f6969 --- /dev/null +++ b/TMPro/TMP_MeshInfo.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace TMPro +{ + public struct TMP_MeshInfo + { + public Vector3[] vertices; + + public Vector2[] uv0s; + + public Vector2[] uv2s; + + public Color32[] vertexColors; + + public Vector3[] normals; + + public Vector4[] tangents; + } +} diff --git a/TMPro/TMP_PageInfo.cs b/TMPro/TMP_PageInfo.cs new file mode 100644 index 00000000..051c0637 --- /dev/null +++ b/TMPro/TMP_PageInfo.cs @@ -0,0 +1,15 @@ +namespace TMPro +{ + public struct TMP_PageInfo + { + public int firstCharacterIndex; + + public int lastCharacterIndex; + + public float ascender; + + public float baseLine; + + public float descender; + } +} diff --git a/TMPro/TMP_SpriteInfo.cs b/TMPro/TMP_SpriteInfo.cs new file mode 100644 index 00000000..3450a0be --- /dev/null +++ b/TMPro/TMP_SpriteInfo.cs @@ -0,0 +1,11 @@ +namespace TMPro +{ + public struct TMP_SpriteInfo + { + public int spriteIndex; + + public int characterIndex; + + public int vertexIndex; + } +} diff --git a/TMPro/TMP_TextInfo.cs b/TMPro/TMP_TextInfo.cs new file mode 100644 index 00000000..e3ab804a --- /dev/null +++ b/TMPro/TMP_TextInfo.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; + +namespace TMPro +{ + [Serializable] + public class TMP_TextInfo + { + public int characterCount; + + public int spriteCount; + + public int spaceCount; + + public int wordCount; + + public int lineCount; + + public int pageCount; + + public TMP_CharacterInfo[] characterInfo; + + public List wordInfo; + + public TMP_LineInfo[] lineInfo; + + public TMP_PageInfo[] pageInfo; + + public TMP_MeshInfo meshInfo; + + public TMP_TextInfo() + { + characterInfo = new TMP_CharacterInfo[0]; + wordInfo = new List(32); + lineInfo = new TMP_LineInfo[16]; + pageInfo = new TMP_PageInfo[8]; + meshInfo = default(TMP_MeshInfo); + } + + public void Clear() + { + characterCount = 0; + spaceCount = 0; + wordCount = 0; + lineCount = 0; + pageCount = 0; + spriteCount = 0; + Array.Clear(characterInfo, 0, characterInfo.Length); + wordInfo.Clear(); + Array.Clear(lineInfo, 0, lineInfo.Length); + Array.Clear(pageInfo, 0, pageInfo.Length); + } + } +} diff --git a/TMPro/TMP_Utilities.cs b/TMPro/TMP_Utilities.cs new file mode 100644 index 00000000..0780f81c --- /dev/null +++ b/TMPro/TMP_Utilities.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace TMPro +{ + public static class TMP_Utilities + { + public static Dictionary LoadDictionaryFromList(List list) where T : Object + { + Dictionary dictionary = new Dictionary(); + for (int i = 0; i < list.Count; i++) + { + Dictionary dictionary2 = dictionary; + T val = list[i]; + dictionary2.Add(val.GetInstanceID(), list[i]); + } + return dictionary; + } + + public static List SaveDictionaryToList(Dictionary dict) where T : Object + { + List list = new List(); + foreach (KeyValuePair item in dict) + { + list.Add(item.Value); + } + return list; + } + } +} diff --git a/TMPro/TMP_Vertex.cs b/TMPro/TMP_Vertex.cs new file mode 100644 index 00000000..fe27027b --- /dev/null +++ b/TMPro/TMP_Vertex.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace TMPro +{ + public struct TMP_Vertex + { + public Vector3 position; + + public Vector2 uv; + + public Vector2 uv2; + + public Color32 color; + + public Vector3 normal; + + public Vector4 tangent; + } +} diff --git a/TMPro/TMP_WordInfo.cs b/TMPro/TMP_WordInfo.cs new file mode 100644 index 00000000..3755db8a --- /dev/null +++ b/TMPro/TMP_WordInfo.cs @@ -0,0 +1,13 @@ +namespace TMPro +{ + public struct TMP_WordInfo + { + public int firstCharacterIndex; + + public int lastCharacterIndex; + + public int characterCount; + + public float length; + } +} diff --git a/TMPro/TMPro_AdvancedLayout.cs b/TMPro/TMPro_AdvancedLayout.cs new file mode 100644 index 00000000..4de762b6 --- /dev/null +++ b/TMPro/TMPro_AdvancedLayout.cs @@ -0,0 +1,158 @@ +using UnityEngine; + +namespace TMPro +{ + [ExecuteInEditMode] + public class TMPro_AdvancedLayout : MonoBehaviour + { + [SerializeField] + private bool m_isEnabled = true; + + [SerializeField] + private bool isRedrawRequired; + + public AnimationCurve TranslationCurve; + + public AnimationCurve ScaleCurve; + + private TextMeshPro m_textMeshProComponent; + + private Renderer m_renderer; + + private MeshFilter m_meshFilter; + + private Material m_sharedMaterial; + + private Mesh m_mesh; + + [SerializeField] + private bool propertiesChanged; + + public bool isEnabled => m_isEnabled; + + private void Awake() + { + Debug.Log("Advanced Layout Component was added."); + m_renderer = GetComponent(); + m_sharedMaterial = m_renderer.sharedMaterial; + m_textMeshProComponent = GetComponent(); + } + + private void OnDestroy() + { + Debug.Log("Advanced Layout Component was removed."); + } + + private void Update() + { + if (propertiesChanged) + { + if (m_isEnabled) + { + m_textMeshProComponent.enableWordWrapping = false; + m_textMeshProComponent.alignment = TextAlignmentOptions.Left; + } + propertiesChanged = false; + } + if (!isRedrawRequired) + { + } + } + + public void DrawMesh() + { + TMP_MeshInfo meshInfo = m_textMeshProComponent.textInfo.meshInfo; + TMP_TextInfo textInfo = m_textMeshProComponent.textInfo; + TMP_CharacterInfo[] characterInfo = textInfo.characterInfo; + int characterCount = textInfo.characterCount; + Vector3[] vertices = meshInfo.vertices; + Vector2[] uv0s = meshInfo.uv0s; + Vector2[] uv2s = meshInfo.uv2s; + Color32[] vertexColors = meshInfo.vertexColors; + Vector3[] normals = meshInfo.normals; + Vector4[] tangents = meshInfo.tangents; + float num = 1f; + float num2 = 0f; + float num3 = 0f; + for (int i = 0; i < characterCount; i++) + { + char character = characterInfo[i].character; + GlyphInfo glyphInfo = m_textMeshProComponent.font.characterDictionary[character]; + int vertexIndex = characterInfo[i].vertexIndex; + if (characterInfo[i].isVisible) + { + float x = (characterInfo[i].bottomLeft.x + characterInfo[i].topRight.x) / 2f; + Vector3 a = new Vector3(x, 0f, 0f); + vertices[vertexIndex] += -a; + vertices[vertexIndex + 1] += -a; + vertices[vertexIndex + 2] += -a; + vertices[vertexIndex + 3] += -a; + float time = (characterCount <= 1) ? 0f : ((float)i / (float)(characterCount - 1)); + num2 = ScaleCurve.Evaluate(time); + Matrix4x4 matrix4x = Matrix4x4.TRS(new Vector3(0f, 0f, 0f), Quaternion.Euler(0f, 0f, 0f), new Vector3(num2, num2, 1f)); + vertices[vertexIndex] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex]); + vertices[vertexIndex + 1] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex + 1]); + vertices[vertexIndex + 2] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex + 2]); + vertices[vertexIndex + 3] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex + 3]); + float num4 = glyphInfo.xOffset * characterInfo[i].scale * num2 + (characterInfo[i].topRight.x - characterInfo[i].bottomLeft.x) / 2f * num2; + a = new Vector3(num4 + num3, 0f, 0f); + vertices[vertexIndex] += a; + vertices[vertexIndex + 1] += a; + vertices[vertexIndex + 2] += a; + vertices[vertexIndex + 3] += a; + uv2s[vertexIndex].y *= num2; + uv2s[vertexIndex + 1].y *= num2; + uv2s[vertexIndex + 2].y *= num2; + uv2s[vertexIndex + 3].y *= num2; + } + num3 += glyphInfo.xAdvance * characterInfo[i].scale * num2 + m_textMeshProComponent.characterSpacing; + } + int vertexIndex2 = characterInfo[characterCount - 1].vertexIndex; + float x2 = vertices[0].x; + float x3 = vertices[vertexIndex2 + 2].x; + for (int j = 0; j < characterCount; j++) + { + int vertexIndex3 = characterInfo[j].vertexIndex; + if (characterInfo[j].isVisible) + { + float num5 = (vertices[vertexIndex3].x + vertices[vertexIndex3 + 2].x) / 2f; + Vector3 vector = new Vector3(num5, 0f, 0f); + vertices[vertexIndex3] += -vector; + vertices[vertexIndex3 + 1] += -vector; + vertices[vertexIndex3 + 2] += -vector; + vertices[vertexIndex3 + 3] += -vector; + float num6 = (num5 - x2) / (x3 - x2); + float num7 = num6 + 0.0001f; + float num8 = TranslationCurve.Evaluate(num6) * num; + float num9 = TranslationCurve.Evaluate(num7) * num; + Vector3 lhs = new Vector3(1f, 0f, 0f); + Debug.DrawLine(end: new Vector3(0f - (num9 - num8), num7 * (x3 - x2) + x2 - num5, 0f), start: new Vector3(num5, num8, 0f), color: Color.green, duration: 60f); + Vector3 rhs = new Vector3(num7 * (x3 - x2) + x2, num9) - new Vector3(num5, num8); + float num10 = Mathf.Acos(Vector3.Dot(lhs, rhs.normalized)) * 57.29578f; + Vector3 vector2 = Vector3.Cross(lhs, rhs); + float z = (!(vector2.z > 0f)) ? (360f - num10) : num10; + Matrix4x4 matrix4x = Matrix4x4.TRS(new Vector3(0f, num8, 0f), Quaternion.Euler(0f, 0f, z), new Vector3(1f, 1f, 1f)); + vertices[vertexIndex3] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex3]); + vertices[vertexIndex3 + 1] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex3 + 1]); + vertices[vertexIndex3 + 2] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex3 + 2]); + vertices[vertexIndex3 + 3] = matrix4x.MultiplyPoint3x4(vertices[vertexIndex3 + 3]); + vertices[vertexIndex3] += vector; + vertices[vertexIndex3 + 1] += vector; + vertices[vertexIndex3 + 2] += vector; + vertices[vertexIndex3 + 3] += vector; + } + } + Mesh mesh = m_textMeshProComponent.mesh; + mesh.vertices = vertices; + mesh.uv = uv0s; + mesh.uv2 = uv2s; + mesh.colors32 = vertexColors; + if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_Shininess)) + { + mesh.normals = normals; + mesh.tangents = tangents; + } + mesh.RecalculateBounds(); + } + } +} diff --git a/TMPro/TMPro_EventManager.cs b/TMPro/TMPro_EventManager.cs new file mode 100644 index 00000000..056dbbb9 --- /dev/null +++ b/TMPro/TMPro_EventManager.cs @@ -0,0 +1,91 @@ +using UnityEngine; + +namespace TMPro +{ + public static class TMPro_EventManager + { + public delegate void COMPUTE_DT_EVENT_HANDLER(object Sender, Compute_DT_EventArgs e); + + public delegate void MaterialProperty_Event_Handler(bool isChanged, Material mat); + + public delegate void FontProperty_Event_Handler(bool isChanged, TextMeshProFont font); + + public delegate void SpriteAssetProperty_Event_Handler(bool isChanged, Object obj); + + public delegate void TextMeshProProperty_Event_Handler(bool isChanged, TextMeshPro obj); + + public delegate void DragAndDrop_Event_Handler(GameObject sender, Material currentMaterial, Material newMaterial); + + public delegate void OnPreRenderObject_Event_Handler(); + + public static event COMPUTE_DT_EVENT_HANDLER COMPUTE_DT_EVENT; + + public static event MaterialProperty_Event_Handler MATERIAL_PROPERTY_EVENT; + + public static event FontProperty_Event_Handler FONT_PROPERTY_EVENT; + + public static event SpriteAssetProperty_Event_Handler SPRITE_ASSET_PROPERTY_EVENT; + + public static event TextMeshProProperty_Event_Handler TEXTMESHPRO_PROPERTY_EVENT; + + public static event DragAndDrop_Event_Handler DRAG_AND_DROP_MATERIAL_EVENT; + + public static event OnPreRenderObject_Event_Handler OnPreRenderObject_Event; + + public static void ON_PRE_RENDER_OBJECT_CHANGED() + { + if (TMPro_EventManager.OnPreRenderObject_Event != null) + { + TMPro_EventManager.OnPreRenderObject_Event(); + } + } + + public static void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat) + { + if (TMPro_EventManager.MATERIAL_PROPERTY_EVENT != null) + { + TMPro_EventManager.MATERIAL_PROPERTY_EVENT(isChanged, mat); + } + } + + public static void ON_FONT_PROPERTY_CHANGED(bool isChanged, TextMeshProFont font) + { + if (TMPro_EventManager.FONT_PROPERTY_EVENT != null) + { + TMPro_EventManager.FONT_PROPERTY_EVENT(isChanged, font); + } + } + + public static void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, Object obj) + { + if (TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT != null) + { + TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT(isChanged, obj); + } + } + + public static void ON_TEXTMESHPRO_PROPERTY_CHANGED(bool isChanged, TextMeshPro obj) + { + if (TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT != null) + { + TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT(isChanged, obj); + } + } + + public static void ON_DRAG_AND_DROP_MATERIAL_CHANGED(GameObject sender, Material currentMaterial, Material newMaterial) + { + if (TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT != null) + { + TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT(sender, currentMaterial, newMaterial); + } + } + + public static void ON_COMPUTE_DT_EVENT(object Sender, Compute_DT_EventArgs e) + { + if (TMPro_EventManager.COMPUTE_DT_EVENT != null) + { + TMPro_EventManager.COMPUTE_DT_EVENT(Sender, e); + } + } + } +} diff --git a/TMPro/TMPro_ExtensionMethods.cs b/TMPro/TMPro_ExtensionMethods.cs new file mode 100644 index 00000000..f56feb76 --- /dev/null +++ b/TMPro/TMPro_ExtensionMethods.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace TMPro +{ + public static class TMPro_ExtensionMethods + { + public static string ArrayToString(this char[] chars) + { + string text = string.Empty; + for (int i = 0; i < chars.Length && chars[i] != 0; i++) + { + text += chars[i]; + } + return text; + } + + public static int FindInstanceID(this List list, T target) where T : Object + { + int instanceID = target.GetInstanceID(); + for (int i = 0; i < list.Count; i++) + { + T val = list[i]; + if (val.GetInstanceID() == instanceID) + { + return i; + } + } + return -1; + } + + public static bool Compare(this Color32 a, Color32 b) + { + return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a; + } + + public static bool CompareRGB(this Color32 a, Color32 b) + { + return a.r == b.r && a.g == b.g && a.b == b.b; + } + + public static bool Compare(this Color a, Color b) + { + return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a; + } + + public static bool CompareRGB(this Color a, Color b) + { + return a.r == b.r && a.g == b.g && a.b == b.b; + } + + public static bool Compare(this Vector3 v1, Vector3 v2, int accuracy) + { + bool flag = (int)(v1.x * (float)accuracy) == (int)(v2.x * (float)accuracy); + bool flag2 = (int)(v1.y * (float)accuracy) == (int)(v2.y * (float)accuracy); + bool flag3 = (int)(v1.z * (float)accuracy) == (int)(v2.z * (float)accuracy); + return flag && flag2 && flag3; + } + + public static bool Compare(this Quaternion q1, Quaternion q2, int accuracy) + { + bool flag = (int)(q1.x * (float)accuracy) == (int)(q2.x * (float)accuracy); + bool flag2 = (int)(q1.y * (float)accuracy) == (int)(q2.y * (float)accuracy); + bool flag3 = (int)(q1.z * (float)accuracy) == (int)(q2.z * (float)accuracy); + bool flag4 = (int)(q1.w * (float)accuracy) == (int)(q2.w * (float)accuracy); + return flag && flag2 && flag3 && flag4; + } + } +} diff --git a/TMPro/TMPro_UpdateManager.cs b/TMPro/TMPro_UpdateManager.cs new file mode 100644 index 00000000..8b42ecad --- /dev/null +++ b/TMPro/TMPro_UpdateManager.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace TMPro +{ + [ExecuteInEditMode] + public class TMPro_UpdateManager : MonoBehaviour + { + private static List m_objectList; + + private void Awake() + { + } + + public void ScheduleObjectForUpdate(TextMeshPro obj) + { + if (m_objectList == null) + { + m_objectList = new List(); + } + m_objectList.Add(obj); + } + + private void OnPreRender() + { + TMPro_EventManager.ON_PRE_RENDER_OBJECT_CHANGED(); + } + } +} diff --git a/TMPro/TextAlignmentOptions.cs b/TMPro/TextAlignmentOptions.cs new file mode 100644 index 00000000..06e95edc --- /dev/null +++ b/TMPro/TextAlignmentOptions.cs @@ -0,0 +1,22 @@ +namespace TMPro +{ + public enum TextAlignmentOptions + { + TopLeft, + Top, + TopRight, + TopJustified, + Left, + Center, + Right, + Justified, + BottomLeft, + Bottom, + BottomRight, + BottomJustified, + BaselineLeft, + Baseline, + BaselineRight, + BaselineJustified + } +} diff --git a/TMPro/TextContainer.cs b/TMPro/TextContainer.cs new file mode 100644 index 00000000..940b8734 --- /dev/null +++ b/TMPro/TextContainer.cs @@ -0,0 +1,317 @@ +using UnityEngine; + +namespace TMPro +{ + [AddComponentMenu("Layout/Text Container")] + [ExecuteInEditMode] + public class TextContainer : MonoBehaviour + { + private bool m_hasChanged; + + [SerializeField] + private Vector2 m_pivot; + + [SerializeField] + private TextContainerAnchors m_anchorPosition = TextContainerAnchors.Middle; + + [SerializeField] + private Rect m_rect; + + private bool m_isDefaultWidth; + + private bool m_isDefaultHeight; + + private bool m_isAutoFitting = true; + + private Vector3[] m_corners = new Vector3[4]; + + private Vector3[] m_worldCorners = new Vector3[4]; + + private Vector3 m_normal; + + [SerializeField] + private Vector4 m_margins; + + private Transform m_transform; + + private TextMeshPro m_textMeshPro; + + public bool hasChanged + { + get + { + return m_hasChanged; + } + set + { + m_hasChanged = value; + } + } + + public Vector2 pivot + { + get + { + return m_pivot; + } + set + { + if (m_pivot != value) + { + m_pivot = value; + m_hasChanged = true; + OnContainerChanged(); + } + } + } + + public TextContainerAnchors anchorPosition + { + get + { + return m_anchorPosition; + } + set + { + if (m_anchorPosition != value) + { + m_anchorPosition = value; + m_pivot = GetPivot(m_anchorPosition); + m_hasChanged = true; + OnContainerChanged(); + } + } + } + + public Rect rect + { + get + { + return m_rect; + } + set + { + if (m_rect != value) + { + m_rect = value; + m_hasChanged = true; + OnContainerChanged(); + } + } + } + + public Vector2 size + { + get + { + return new Vector2(m_rect.width, m_rect.height); + } + set + { + if (new Vector2(m_rect.width, m_rect.height) != value) + { + SetRect(value); + m_hasChanged = true; + m_isDefaultWidth = false; + m_isDefaultHeight = false; + OnContainerChanged(); + } + } + } + + public float width + { + get + { + return m_rect.width; + } + set + { + SetRect(new Vector2(value, m_rect.height)); + m_hasChanged = true; + m_isDefaultWidth = false; + OnContainerChanged(); + } + } + + public float height + { + get + { + return m_rect.height; + } + set + { + SetRect(new Vector2(m_rect.width, value)); + m_hasChanged = true; + m_isDefaultHeight = false; + OnContainerChanged(); + } + } + + public bool isDefaultWidth => m_isDefaultWidth; + + public bool isDefaultHeight => m_isDefaultHeight; + + public bool isAutoFitting + { + get + { + return m_isAutoFitting; + } + set + { + m_isAutoFitting = value; + } + } + + public Vector3[] corners => m_corners; + + public Vector3[] worldCorners => m_worldCorners; + + public Vector3 normal => m_normal; + + public Vector4 margins + { + get + { + return m_margins; + } + set + { + if (m_margins != value) + { + m_margins = value; + m_hasChanged = true; + OnContainerChanged(); + } + } + } + + private void Awake() + { + m_transform = (GetComponent(typeof(Transform)) as Transform); + m_textMeshPro = (GetComponent(typeof(TextMeshPro)) as TextMeshPro); + if (m_rect.width == 0f || m_rect.height == 0f) + { + if (m_textMeshPro != null && m_textMeshPro.lineLength != 72f) + { + Debug.LogWarning("Converting from using anchor and lineLength properties to Text Container."); + m_isDefaultHeight = true; + int num = (int)(m_anchorPosition = (TextContainerAnchors)m_textMeshPro.anchor); + m_pivot = GetPivot(m_anchorPosition); + m_rect.width = m_textMeshPro.lineLength; + } + else + { + m_isDefaultWidth = true; + m_isDefaultHeight = true; + m_pivot = GetPivot(m_anchorPosition); + m_rect.width = 0f; + m_rect.height = 0f; + } + m_margins = new Vector4(0f, 0f, 0f, 0f); + UpdateCorners(); + } + } + + private void OnEnable() + { + if (m_transform == null) + { + m_transform = (GetComponent(typeof(Transform)) as Transform); + } + OnContainerChanged(); + } + + private void OnDisable() + { + } + + private void OnContainerChanged() + { + UpdateCorners(); + UpdateWorldCorners(); + if (m_transform != null) + { + m_transform.hasChanged = true; + } + } + + private void OnValidate() + { + m_hasChanged = true; + OnContainerChanged(); + } + + private void LateUpdate() + { + if (m_transform.hasChanged) + { + UpdateWorldCorners(); + } + } + + private void SetRect(Vector2 size) + { + m_rect = new Rect(m_rect.x, m_rect.y, size.x, size.y); + } + + private void UpdateCorners() + { + m_corners[0] = new Vector3((0f - m_pivot.x) * m_rect.width, (0f - m_pivot.y) * m_rect.height); + m_corners[1] = new Vector3((0f - m_pivot.x) * m_rect.width, (1f - m_pivot.y) * m_rect.height); + m_corners[2] = new Vector3((1f - m_pivot.x) * m_rect.width, (1f - m_pivot.y) * m_rect.height); + m_corners[3] = new Vector3((1f - m_pivot.x) * m_rect.width, (0f - m_pivot.y) * m_rect.height); + } + + private void UpdateWorldCorners() + { + if (!(m_transform == null)) + { + Vector3 position = m_transform.position; + m_worldCorners[0] = position + m_transform.TransformDirection(m_corners[0]); + m_worldCorners[1] = position + m_transform.TransformDirection(m_corners[1]); + m_worldCorners[2] = position + m_transform.TransformDirection(m_corners[2]); + m_worldCorners[3] = position + m_transform.TransformDirection(m_corners[3]); + m_normal = Vector3.Cross(worldCorners[1] - worldCorners[0], worldCorners[3] - worldCorners[0]); + } + } + + private Vector2 GetPivot(TextContainerAnchors anchor) + { + Vector2 result = Vector2.zero; + switch (anchor) + { + case TextContainerAnchors.TopLeft: + result = new Vector2(0f, 1f); + break; + case TextContainerAnchors.Top: + result = new Vector2(0.5f, 1f); + break; + case TextContainerAnchors.TopRight: + result = new Vector2(1f, 1f); + break; + case TextContainerAnchors.Left: + result = new Vector2(0f, 0.5f); + break; + case TextContainerAnchors.Middle: + result = new Vector2(0.5f, 0.5f); + break; + case TextContainerAnchors.Right: + result = new Vector2(1f, 0.5f); + break; + case TextContainerAnchors.BottomLeft: + result = new Vector2(0f, 0f); + break; + case TextContainerAnchors.Bottom: + result = new Vector2(0.5f, 0f); + break; + case TextContainerAnchors.BottomRight: + result = new Vector2(1f, 0f); + break; + } + return result; + } + } +} diff --git a/TMPro/TextContainerAnchors.cs b/TMPro/TextContainerAnchors.cs new file mode 100644 index 00000000..6d776693 --- /dev/null +++ b/TMPro/TextContainerAnchors.cs @@ -0,0 +1,15 @@ +namespace TMPro +{ + public enum TextContainerAnchors + { + TopLeft, + Top, + TopRight, + Left, + Middle, + Right, + BottomLeft, + Bottom, + BottomRight + } +} diff --git a/TMPro/TextMeshPro.cs b/TMPro/TextMeshPro.cs new file mode 100644 index 00000000..a5c3c0fd --- /dev/null +++ b/TMPro/TextMeshPro.cs @@ -0,0 +1,3471 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using UnityEngine; + +namespace TMPro +{ + [AddComponentMenu("Mesh/TextMesh Pro")] + [ExecuteInEditMode] + [RequireComponent(typeof(MeshFilter))] + [RequireComponent(typeof(MeshRenderer))] + [RequireComponent(typeof(TextContainer))] + public class TextMeshPro : MonoBehaviour + { + private enum TextInputSources + { + Text, + SetText, + SetCharArray + } + + [SerializeField] + private string m_text; + + [SerializeField] + private TextMeshProFont m_fontAsset; + + private Material m_fontMaterial; + + private Material m_sharedMaterial; + + [SerializeField] + private FontStyles m_fontStyle; + + private FontStyles m_style; + + [SerializeField] + private bool m_isOverlay; + + [SerializeField] + private Color m_fontColor = Color.white; + + private Color32 m_fontColor32 = Color.white; + + [SerializeField] + private VertexGradient m_fontColorGradient = new VertexGradient(Color.white); + + [SerializeField] + private bool m_enableVertexGradient; + + [SerializeField] + private Color32 m_faceColor = Color.white; + + [SerializeField] + private Color32 m_outlineColor = Color.black; + + private float m_outlineWidth; + + [SerializeField] + private float m_fontSize = 36f; + + [SerializeField] + private float m_fontSizeMin; + + [SerializeField] + private float m_fontSizeMax; + + [SerializeField] + private float m_fontSizeBase = 36f; + + [SerializeField] + private float m_charSpacingMax; + + [SerializeField] + private float m_lineSpacingMax; + + private float m_currentFontSize; + + [SerializeField] + private float m_characterSpacing; + + private float m_cSpacing; + + private float m_monoSpacing; + + [SerializeField] + private Vector4 m_textRectangle; + + [SerializeField] + private float m_lineSpacing; + + private float m_lineSpacingDelta; + + private float m_lineHeight; + + [SerializeField] + private float m_paragraphSpacing; + + [SerializeField] + private float m_lineLength; + + [SerializeField] + private TMP_Compatibility.AnchorPositions m_anchor; + + [SerializeField] + private TextAlignmentOptions m_textAlignment; + + private TextAlignmentOptions m_lineJustification; + + [SerializeField] + private bool m_enableKerning; + + private bool m_anchorDampening; + + private float m_baseDampeningWidth; + + [SerializeField] + private bool m_overrideHtmlColors; + + [SerializeField] + private bool m_enableExtraPadding; + + [SerializeField] + private bool checkPaddingRequired; + + [SerializeField] + private bool m_enableWordWrapping; + + private bool m_isCharacterWrappingEnabled; + + [SerializeField] + private TextOverflowModes m_overflowMode; + + [SerializeField] + private float m_wordWrappingRatios = 0.4f; + + [SerializeField] + private TextureMappingOptions m_horizontalMapping; + + [SerializeField] + private TextureMappingOptions m_verticalMapping; + + [SerializeField] + private Vector2 m_uvOffset = Vector2.zero; + + [SerializeField] + private float m_uvLineOffset; + + [SerializeField] + private bool isInputParsingRequired; + + [SerializeField] + private bool havePropertiesChanged; + + [SerializeField] + private bool hasFontAssetChanged; + + [SerializeField] + private bool m_isRichText = true; + + [SerializeField] + private TextInputSources m_inputSource; + + private string old_text; + + private float old_arg0; + + private float old_arg1; + + private float old_arg2; + + private int m_fontIndex; + + private float m_fontScale; + + private bool m_isRecalculateScaleRequired; + + private Vector3 m_lossyScale; + + private float m_xAdvance; + + private float m_indent; + + private float m_maxXAdvance; + + private Vector3 m_anchorOffset; + + private TMP_TextInfo m_textInfo; + + private char[] m_htmlTag = new char[128]; + + [SerializeField] + private Renderer m_renderer; + + private MeshFilter m_meshFilter; + + private Mesh m_mesh; + + private Transform m_transform; + + private Color32 m_htmlColor = new Color(255f, 255f, 255f, 128f); + + private float m_tabSpacing; + + private float m_spacing; + + private Vector2[] m_spacePositions = new Vector2[8]; + + private float m_baselineOffset; + + private float m_padding; + + private Vector4 m_alignmentPadding; + + private bool m_isUsingBold; + + private Vector2 k_InfinityVector = new Vector2(float.PositiveInfinity, float.PositiveInfinity); + + private bool m_isFirstAllocation; + + private int m_max_characters = 8; + + private int m_max_numberOfLines = 4; + + private int[] m_char_buffer; + + private char[] m_input_CharArray = new char[256]; + + private int m_charArray_Length; + + private List m_VisibleCharacters = new List(); + + private readonly float[] k_Power = new float[10] + { + 0.5f, + 0.05f, + 0.005f, + 0.0005f, + 5E-05f, + 5E-06f, + 5E-07f, + 5E-08f, + 5E-09f, + 5E-10f + }; + + private GlyphInfo m_cached_GlyphInfo; + + private GlyphInfo m_cached_Underline_GlyphInfo; + + private WordWrapState m_SavedWordWrapState = default(WordWrapState); + + private WordWrapState m_SavedLineState = default(WordWrapState); + + private int m_characterCount; + + private int m_visibleCharacterCount; + + private int m_firstVisibleCharacterOfLine; + + private int m_lastVisibleCharacterOfLine; + + private int m_lineNumber; + + private int m_pageNumber; + + private float m_maxAscender; + + private float m_maxDescender; + + private float m_maxFontScale; + + private float m_lineOffset; + + private Extents m_meshExtents; + + private float m_preferredWidth; + + private float m_preferredHeight; + + private Vector3[] m_vertices; + + private Vector3[] m_normals; + + private Vector4[] m_tangents; + + private Vector2[] m_uvs; + + private Vector2[] m_uv2s; + + private Color32[] m_vertColors; + + private int[] m_triangles; + + private Bounds m_default_bounds = new Bounds(Vector3.zero, new Vector3(1000f, 1000f, 0f)); + + [SerializeField] + private bool m_ignoreCulling = true; + + [SerializeField] + private bool m_isOrthographic; + + [SerializeField] + private bool m_isCullingEnabled; + + private int m_sortingLayerID; + + private int m_maxVisibleCharacters = -1; + + private int m_maxVisibleLines = -1; + + [SerializeField] + private int m_pageToDisplay; + + private bool m_isNewPage; + + private bool m_isTextTruncated; + + [SerializeField] + private TextMeshProFont[] m_fontAssetArray; + + private List m_sharedMaterials = new List(16); + + private int m_selectedFontAsset; + + private MaterialPropertyBlock m_maskingPropertyBlock; + + private bool m_isMaskingEnabled; + + private bool isMaskUpdateRequired; + + private bool m_isMaterialBlockSet; + + [SerializeField] + private MaskingTypes m_maskType; + + private Matrix4x4 m_EnvMapMatrix = default(Matrix4x4); + + private TextRenderFlags m_renderMode; + + [SerializeField] + private bool m_isNewTextObject; + + private TextContainer m_textContainer; + + private float m_marginWidth; + + [SerializeField] + private bool m_enableAutoSizing; + + private float m_maxFontSize; + + private float m_minFontSize; + + private Stopwatch m_StopWatch; + + private bool isDebugOutputDone; + + private int m_recursiveCount; + + private int loopCountA; + + private int loopCountB; + + private int loopCountC; + + private int loopCountD; + + private int loopCountE; + + private GameObject m_prefabParent; + + public string text + { + get + { + return m_text; + } + set + { + m_inputSource = TextInputSources.Text; + havePropertiesChanged = true; + isInputParsingRequired = true; + m_text = value; + } + } + + public TextMeshProFont font + { + get + { + return m_fontAsset; + } + set + { + if (m_fontAsset != value) + { + m_fontAsset = value; + LoadFontAsset(); + havePropertiesChanged = true; + } + } + } + + public Material fontMaterial + { + get + { + if (m_fontMaterial == null) + { + SetFontMaterial(m_sharedMaterial); + return m_sharedMaterial; + } + return m_sharedMaterial; + } + set + { + SetFontMaterial(value); + havePropertiesChanged = true; + } + } + + public Material fontSharedMaterial + { + get + { + return m_renderer.sharedMaterial; + } + set + { + if (m_sharedMaterial != value) + { + SetSharedFontMaterial(value); + havePropertiesChanged = true; + } + } + } + + public bool isOverlay + { + get + { + return m_isOverlay; + } + set + { + m_isOverlay = value; + SetShaderType(); + havePropertiesChanged = true; + } + } + + public Color color + { + get + { + return m_fontColor; + } + set + { + if (!m_fontColor.Compare(value)) + { + havePropertiesChanged = true; + m_fontColor = value; + } + } + } + + public VertexGradient colorGradient + { + get + { + return m_fontColorGradient; + } + set + { + havePropertiesChanged = true; + m_fontColorGradient = value; + } + } + + public bool enableVertexGradient + { + get + { + return m_enableVertexGradient; + } + set + { + havePropertiesChanged = true; + m_enableVertexGradient = value; + } + } + + public Color32 faceColor + { + get + { + return m_faceColor; + } + set + { + if (!m_faceColor.Compare(value)) + { + SetFaceColor(value); + havePropertiesChanged = true; + m_faceColor = value; + } + } + } + + public Color32 outlineColor + { + get + { + return m_outlineColor; + } + set + { + if (!m_outlineColor.Compare(value)) + { + SetOutlineColor(value); + havePropertiesChanged = true; + m_outlineColor = value; + } + } + } + + public float outlineWidth + { + get + { + return m_outlineWidth; + } + set + { + SetOutlineThickness(value); + havePropertiesChanged = true; + checkPaddingRequired = true; + m_outlineWidth = value; + } + } + + public float fontSize + { + get + { + return m_fontSize; + } + set + { + if (m_fontSize != value) + { + havePropertiesChanged = true; + m_fontSize = value; + } + } + } + + public float fontScale => m_fontScale; + + public FontStyles fontStyle + { + get + { + return m_fontStyle; + } + set + { + m_fontStyle = value; + havePropertiesChanged = true; + checkPaddingRequired = true; + } + } + + public float characterSpacing + { + get + { + return m_characterSpacing; + } + set + { + if (m_characterSpacing != value) + { + havePropertiesChanged = true; + m_characterSpacing = value; + } + } + } + + public bool richText + { + get + { + return m_isRichText; + } + set + { + m_isRichText = value; + havePropertiesChanged = true; + isInputParsingRequired = true; + } + } + + [Obsolete("The length of the line is now controlled by the size of the text container and margins.")] + public float lineLength + { + get + { + return m_lineLength; + } + set + { + UnityEngine.Debug.Log("lineLength set called."); + } + } + + public TextOverflowModes OverflowMode + { + get + { + return m_overflowMode; + } + set + { + m_overflowMode = value; + havePropertiesChanged = true; + } + } + + public Bounds bounds + { + get + { + if (m_mesh != null) + { + return m_mesh.bounds; + } + return default(Bounds); + } + } + + public float lineSpacing + { + get + { + return m_lineSpacing; + } + set + { + if (m_lineSpacing != value) + { + havePropertiesChanged = true; + m_lineSpacing = value; + } + } + } + + public float paragraphSpacing + { + get + { + return m_paragraphSpacing; + } + set + { + if (m_paragraphSpacing != value) + { + havePropertiesChanged = true; + m_paragraphSpacing = value; + } + } + } + + [Obsolete("The length of the line is now controlled by the size of the text container and margins.")] + public TMP_Compatibility.AnchorPositions anchor + { + get + { + return m_anchor; + } + } + + public TextAlignmentOptions alignment + { + get + { + return m_textAlignment; + } + set + { + if (m_textAlignment != value) + { + havePropertiesChanged = true; + m_textAlignment = value; + } + } + } + + public bool enableKerning + { + get + { + return m_enableKerning; + } + set + { + if (m_enableKerning != value) + { + havePropertiesChanged = true; + m_enableKerning = value; + } + } + } + + public bool anchorDampening + { + get + { + return m_anchorDampening; + } + set + { + if (m_anchorDampening != value) + { + havePropertiesChanged = true; + m_anchorDampening = value; + } + } + } + + public bool overrideColorTags + { + get + { + return m_overrideHtmlColors; + } + set + { + if (m_overrideHtmlColors != value) + { + havePropertiesChanged = true; + m_overrideHtmlColors = value; + } + } + } + + public bool extraPadding + { + get + { + return m_enableExtraPadding; + } + set + { + if (m_enableExtraPadding != value) + { + havePropertiesChanged = true; + checkPaddingRequired = true; + m_enableExtraPadding = value; + } + } + } + + public bool enableWordWrapping + { + get + { + return m_enableWordWrapping; + } + set + { + if (m_enableWordWrapping != value) + { + havePropertiesChanged = true; + isInputParsingRequired = true; + m_enableWordWrapping = value; + } + } + } + + public TextureMappingOptions horizontalMapping + { + get + { + return m_horizontalMapping; + } + set + { + if (m_horizontalMapping != value) + { + havePropertiesChanged = true; + m_horizontalMapping = value; + } + } + } + + public TextureMappingOptions verticalMapping + { + get + { + return m_verticalMapping; + } + set + { + if (m_verticalMapping != value) + { + havePropertiesChanged = true; + m_verticalMapping = value; + } + } + } + + public bool ignoreVisibility + { + get + { + return m_ignoreCulling; + } + set + { + if (m_ignoreCulling != value) + { + havePropertiesChanged = true; + m_ignoreCulling = value; + } + } + } + + public bool isOrthographic + { + get + { + return m_isOrthographic; + } + set + { + havePropertiesChanged = true; + m_isOrthographic = value; + } + } + + public bool enableCulling + { + get + { + return m_isCullingEnabled; + } + set + { + m_isCullingEnabled = value; + SetCulling(); + havePropertiesChanged = true; + } + } + + public int sortingLayerID + { + get + { + return m_renderer.sortingLayerID; + } + set + { + m_renderer.sortingLayerID = value; + } + } + + public int sortingOrder + { + get + { + return m_renderer.sortingOrder; + } + set + { + m_renderer.sortingOrder = value; + } + } + + public bool hasChanged + { + get + { + return havePropertiesChanged; + } + set + { + havePropertiesChanged = value; + } + } + + public TextRenderFlags renderMode + { + get + { + return m_renderMode; + } + set + { + m_renderMode = value; + havePropertiesChanged = true; + } + } + + public TextContainer textContainer => m_textContainer; + + public int maxVisibleCharacters + { + get + { + return m_maxVisibleCharacters; + } + set + { + if (m_maxVisibleCharacters != value) + { + havePropertiesChanged = true; + m_maxVisibleCharacters = value; + } + } + } + + public int maxVisibleLines + { + get + { + return m_maxVisibleLines; + } + set + { + if (m_maxVisibleLines != value) + { + havePropertiesChanged = true; + isInputParsingRequired = true; + m_maxVisibleLines = value; + } + } + } + + public int pageToDisplay + { + get + { + return m_pageToDisplay; + } + set + { + havePropertiesChanged = true; + m_pageToDisplay = value; + } + } + + public float preferredWidth => m_preferredWidth; + + public Vector2[] spacePositions => m_spacePositions; + + public bool enableAutoSizing + { + get + { + return m_enableAutoSizing; + } + set + { + m_enableAutoSizing = value; + } + } + + public float fontSizeMin + { + get + { + return m_fontSizeMin; + } + set + { + m_fontSizeMin = value; + } + } + + public float fontSizeMax + { + get + { + return m_fontSizeMax; + } + set + { + m_fontSizeMax = value; + } + } + + public MaskingTypes maskType + { + get + { + return m_maskType; + } + set + { + m_maskType = value; + havePropertiesChanged = true; + isMaskUpdateRequired = true; + } + } + + public TMP_TextInfo textInfo => m_textInfo; + + public Mesh mesh => m_mesh; + + private void Awake() + { + m_textContainer = GetComponent(); + if (m_textContainer == null) + { + m_textContainer = base.gameObject.AddComponent(); + } + m_renderer = GetComponent(); + if (m_renderer == null) + { + m_renderer = base.gameObject.AddComponent(); + } + m_transform = base.gameObject.transform; + m_meshFilter = GetComponent(); + if (m_meshFilter == null) + { + m_meshFilter = base.gameObject.AddComponent(); + } + if (m_mesh == null) + { + m_mesh = new Mesh(); + m_mesh.hideFlags = HideFlags.HideAndDontSave; + m_meshFilter.mesh = m_mesh; + } + m_meshFilter.hideFlags = HideFlags.HideInInspector; + LoadFontAsset(); + m_char_buffer = new int[m_max_characters]; + m_cached_GlyphInfo = new GlyphInfo(); + m_vertices = new Vector3[0]; + m_isFirstAllocation = true; + m_textInfo = new TMP_TextInfo(); + m_textInfo.wordInfo = new List(); + m_textInfo.lineInfo = new TMP_LineInfo[m_max_numberOfLines]; + m_textInfo.pageInfo = new TMP_PageInfo[16]; + m_textInfo.meshInfo = default(TMP_MeshInfo); + m_fontAssetArray = new TextMeshProFont[16]; + if (m_fontAsset == null) + { + UnityEngine.Debug.LogWarning("Please assign a Font Asset to this " + base.transform.name + " gameobject."); + } + else + { + if (m_fontSizeMin == 0f) + { + m_fontSizeMin = m_fontSize / 2f; + } + if (m_fontSizeMax == 0f) + { + m_fontSizeMax = m_fontSize * 2f; + } + isInputParsingRequired = true; + havePropertiesChanged = true; + ForceMeshUpdate(); + } + } + + private void OnEnable() + { + if (m_meshFilter.sharedMesh == null) + { + m_meshFilter.mesh = m_mesh; + } + TMPro_EventManager.OnPreRenderObject_Event += OnPreRenderObject; + } + + private void OnDisable() + { + TMPro_EventManager.OnPreRenderObject_Event -= OnPreRenderObject; + } + + private void OnDestroy() + { + if (m_mesh != null) + { + UnityEngine.Object.DestroyImmediate(m_mesh); + } + } + + private void Reset() + { + if (m_mesh != null) + { + UnityEngine.Object.DestroyImmediate(m_mesh); + } + Awake(); + } + + private void LoadFontAsset() + { + ShaderUtilities.GetShaderPropertyIDs(); + if (m_fontAsset == null) + { + m_fontAsset = (Resources.Load("Fonts & Materials/ARIAL SDF", typeof(TextMeshProFont)) as TextMeshProFont); + if (m_fontAsset == null) + { + UnityEngine.Debug.LogWarning("The ARIAL SDF Font Asset was not found. There is no Font Asset assigned to " + base.gameObject.name + "."); + return; + } + if (m_fontAsset.characterDictionary == null) + { + UnityEngine.Debug.Log("Dictionary is Null!"); + } + m_renderer.sharedMaterial = m_fontAsset.material; + m_sharedMaterial = m_fontAsset.material; + m_sharedMaterial.SetFloat("_CullMode", 0f); + m_sharedMaterial.SetFloat("_ZTestMode", 4f); + m_renderer.receiveShadows = false; + m_renderer.castShadows = false; + } + else + { + if (m_fontAsset.characterDictionary == null) + { + m_fontAsset.ReadFontDefinition(); + } + if (m_renderer.sharedMaterial == null || m_renderer.sharedMaterial.mainTexture == null || m_fontAsset.atlas.GetInstanceID() != m_renderer.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID()) + { + m_renderer.sharedMaterial = m_fontAsset.material; + m_sharedMaterial = m_fontAsset.material; + } + else + { + m_sharedMaterial = m_renderer.sharedMaterial; + } + m_sharedMaterial.SetFloat("_ZTestMode", 4f); + if (m_sharedMaterial.passCount > 1) + { + m_renderer.receiveShadows = false; + m_renderer.castShadows = true; + } + else + { + m_renderer.receiveShadows = false; + m_renderer.castShadows = false; + } + } + m_padding = ShaderUtilities.GetPadding(m_renderer.sharedMaterials, m_enableExtraPadding, m_isUsingBold); + m_alignmentPadding = ShaderUtilities.GetFontExtent(m_sharedMaterial); + m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial); + if (!m_fontAsset.characterDictionary.TryGetValue(95, out m_cached_Underline_GlyphInfo)) + { + UnityEngine.Debug.LogWarning("Underscore character wasn't found in the current Font Asset. No characters assigned for Underline."); + } + m_sharedMaterials.Add(m_sharedMaterial); + } + + private void ScheduleUpdate() + { + } + + private void UpdateEnvMapMatrix() + { + if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_EnvMap) && !(m_sharedMaterial.GetTexture(ShaderUtilities.ID_EnvMap) == null)) + { + Vector3 euler = m_sharedMaterial.GetVector(ShaderUtilities.ID_EnvMatrixRotation); + m_EnvMapMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(euler), Vector3.one); + m_sharedMaterial.SetMatrix(ShaderUtilities.ID_EnvMatrix, m_EnvMapMatrix); + } + } + + private void EnableMasking() + { + if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_MaskCoord)) + { + m_sharedMaterial.EnableKeyword("MASK_SOFT"); + m_sharedMaterial.DisableKeyword("MASK_HARD"); + m_sharedMaterial.DisableKeyword("MASK_OFF"); + m_isMaskingEnabled = true; + UpdateMask(); + } + } + + private void DisableMasking() + { + if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_MaskCoord)) + { + m_sharedMaterial.EnableKeyword("MASK_OFF"); + m_sharedMaterial.DisableKeyword("MASK_HARD"); + m_sharedMaterial.DisableKeyword("MASK_SOFT"); + m_isMaskingEnabled = false; + UpdateMask(); + } + } + + private void UpdateMask() + { + if (m_isMaskingEnabled) + { + if (m_isMaskingEnabled && m_fontMaterial == null) + { + CreateMaterialInstance(); + } + Vector4 margins = m_textContainer.margins; + float x = margins.x; + Vector4 margins2 = m_textContainer.margins; + float num = Mathf.Min(Mathf.Min(x, margins2.z), m_sharedMaterial.GetFloat(ShaderUtilities.ID_MaskSoftnessX)); + Vector4 margins3 = m_textContainer.margins; + float y = margins3.y; + Vector4 margins4 = m_textContainer.margins; + float num2 = Mathf.Min(Mathf.Min(y, margins4.w), m_sharedMaterial.GetFloat(ShaderUtilities.ID_MaskSoftnessY)); + num = ((!(num > 0f)) ? 0f : num); + num2 = ((!(num2 > 0f)) ? 0f : num2); + float width = m_textContainer.width; + Vector4 margins5 = m_textContainer.margins; + float num3 = width - Mathf.Max(margins5.x, 0f); + Vector4 margins6 = m_textContainer.margins; + float z = (num3 - Mathf.Max(margins6.z, 0f)) / 2f + num; + float height = m_textContainer.height; + Vector4 margins7 = m_textContainer.margins; + float num4 = height - Mathf.Max(margins7.y, 0f); + Vector4 margins8 = m_textContainer.margins; + float w = (num4 - Mathf.Max(margins8.w, 0f)) / 2f + num2; + Vector2 pivot = m_textContainer.pivot; + float num5 = (0.5f - pivot.x) * m_textContainer.width; + Vector4 margins9 = m_textContainer.margins; + float num6 = Mathf.Max(margins9.x, 0f); + Vector4 margins10 = m_textContainer.margins; + float x2 = num5 + (num6 - Mathf.Max(margins10.z, 0f)) / 2f; + Vector2 pivot2 = m_textContainer.pivot; + float num7 = (0.5f - pivot2.y) * m_textContainer.height; + Vector4 margins11 = m_textContainer.margins; + float num8 = 0f - Mathf.Max(margins11.y, 0f); + Vector4 margins12 = m_textContainer.margins; + Vector2 vector = new Vector2(x2, num7 + (num8 + Mathf.Max(margins12.w, 0f)) / 2f); + Vector4 vector2 = new Vector4(vector.x, vector.y, z, w); + m_fontMaterial.SetVector(ShaderUtilities.ID_MaskCoord, vector2); + m_fontMaterial.SetFloat(ShaderUtilities.ID_MaskSoftnessX, num); + m_fontMaterial.SetFloat(ShaderUtilities.ID_MaskSoftnessY, num2); + } + } + + private void SetMeshArrays(int size) + { + int num = size * 4; + int num2 = size * 6; + m_vertices = new Vector3[num]; + m_normals = new Vector3[num]; + m_tangents = new Vector4[num]; + m_uvs = new Vector2[num]; + m_uv2s = new Vector2[num]; + m_vertColors = new Color32[num]; + m_triangles = new int[num2]; + for (int i = 0; i < size; i++) + { + int num3 = i * 4; + int num4 = i * 6; + m_vertices[0 + num3] = Vector3.zero; + m_vertices[1 + num3] = Vector3.zero; + m_vertices[2 + num3] = Vector3.zero; + m_vertices[3 + num3] = Vector3.zero; + m_uvs[0 + num3] = Vector2.zero; + m_uvs[1 + num3] = Vector2.zero; + m_uvs[2 + num3] = Vector2.zero; + m_uvs[3 + num3] = Vector2.zero; + m_normals[0 + num3] = new Vector3(0f, 0f, -1f); + m_normals[1 + num3] = new Vector3(0f, 0f, -1f); + m_normals[2 + num3] = new Vector3(0f, 0f, -1f); + m_normals[3 + num3] = new Vector3(0f, 0f, -1f); + m_tangents[0 + num3] = new Vector4(-1f, 0f, 0f, 1f); + m_tangents[1 + num3] = new Vector4(-1f, 0f, 0f, 1f); + m_tangents[2 + num3] = new Vector4(-1f, 0f, 0f, 1f); + m_tangents[3 + num3] = new Vector4(-1f, 0f, 0f, 1f); + m_triangles[0 + num4] = 0 + num3; + m_triangles[1 + num4] = 1 + num3; + m_triangles[2 + num4] = 2 + num3; + m_triangles[3 + num4] = 3 + num3; + m_triangles[4 + num4] = 2 + num3; + m_triangles[5 + num4] = 1 + num3; + } + m_mesh.vertices = m_vertices; + m_mesh.uv = m_uvs; + m_mesh.normals = m_normals; + m_mesh.tangents = m_tangents; + m_mesh.triangles = m_triangles; + m_mesh.bounds = m_default_bounds; + } + + private void SetFontMaterial(Material mat) + { + if (m_renderer == null) + { + m_renderer = GetComponent(); + } + m_renderer.material = mat; + m_fontMaterial = m_renderer.material; + m_sharedMaterial = m_fontMaterial; + m_padding = ShaderUtilities.GetPadding(m_renderer.sharedMaterials, m_enableExtraPadding, m_isUsingBold); + m_alignmentPadding = ShaderUtilities.GetFontExtent(m_sharedMaterial); + } + + private void SetSharedFontMaterial(Material mat) + { + if (m_renderer == null) + { + m_renderer = GetComponent(); + } + m_renderer.sharedMaterial = mat; + m_sharedMaterial = m_renderer.sharedMaterial; + m_padding = ShaderUtilities.GetPadding(m_renderer.sharedMaterials, m_enableExtraPadding, m_isUsingBold); + m_alignmentPadding = ShaderUtilities.GetFontExtent(m_sharedMaterial); + } + + private void SetOutlineThickness(float thickness) + { + thickness = Mathf.Clamp01(thickness); + m_renderer.material.SetFloat(ShaderUtilities.ID_OutlineWidth, thickness); + if (m_fontMaterial == null) + { + m_fontMaterial = m_renderer.material; + } + m_fontMaterial = m_renderer.material; + } + + private void SetFaceColor(Color32 color) + { + m_renderer.material.SetColor(ShaderUtilities.ID_FaceColor, color); + if (m_fontMaterial == null) + { + m_fontMaterial = m_renderer.material; + } + } + + private void SetOutlineColor(Color32 color) + { + m_renderer.material.SetColor(ShaderUtilities.ID_OutlineColor, color); + if (m_fontMaterial == null) + { + m_fontMaterial = m_renderer.material; + } + } + + private void CreateMaterialInstance() + { + Material material = new Material(m_sharedMaterial); + material.shaderKeywords = m_sharedMaterial.shaderKeywords; + material.name += " Instance"; + m_fontMaterial = material; + } + + private void SetShaderType() + { + if (m_isOverlay) + { + m_renderer.material.SetFloat("_ZTestMode", 8f); + m_renderer.material.renderQueue = 4000; + m_sharedMaterial = m_renderer.material; + } + else + { + m_renderer.material.SetFloat("_ZTestMode", 4f); + m_renderer.material.renderQueue = -1; + m_sharedMaterial = m_renderer.material; + } + } + + private void SetCulling() + { + if (m_isCullingEnabled) + { + m_renderer.material.SetFloat("_CullMode", 2f); + } + else + { + m_renderer.material.SetFloat("_CullMode", 0f); + } + } + + private void SetPerspectiveCorrection() + { + if (m_isOrthographic) + { + m_sharedMaterial.SetFloat(ShaderUtilities.ID_PerspectiveFilter, 0f); + } + else + { + m_sharedMaterial.SetFloat(ShaderUtilities.ID_PerspectiveFilter, 0.875f); + } + } + + private void AddIntToCharArray(int number, ref int index, int precision) + { + if (number < 0) + { + m_input_CharArray[index++] = '-'; + number = -number; + } + int num = index; + do + { + m_input_CharArray[num++] = (char)(number % 10 + 48); + number /= 10; + } + while (number > 0); + int num3 = num; + while (index + 1 < num) + { + num--; + char c = m_input_CharArray[index]; + m_input_CharArray[index] = m_input_CharArray[num]; + m_input_CharArray[num] = c; + index++; + } + index = num3; + } + + private void AddFloatToCharArray(float number, ref int index, int precision) + { + if (number < 0f) + { + m_input_CharArray[index++] = '-'; + number = 0f - number; + } + number += k_Power[Mathf.Min(9, precision)]; + int num = (int)number; + AddIntToCharArray(num, ref index, precision); + if (precision > 0) + { + m_input_CharArray[index++] = '.'; + number -= (float)num; + for (int i = 0; i < precision; i++) + { + number *= 10f; + int num2 = (int)number; + m_input_CharArray[index++] = (char)(num2 + 48); + number -= (float)num2; + } + } + } + + private void StringToCharArray(string text, ref int[] chars) + { + if (text != null) + { + if (chars.Length <= text.Length) + { + int num = (text.Length <= 1024) ? Mathf.NextPowerOfTwo(text.Length + 1) : (text.Length + 256); + chars = new int[num]; + } + int num2 = 0; + for (int i = 0; i < text.Length; i++) + { + if (text[i] == '\\' && i < text.Length - 1) + { + switch (text[i + 1]) + { + case 't': + break; + case 'n': + goto IL_00a4; + default: + goto IL_00b7; + } + chars[num2] = 9; + i++; + num2++; + continue; + } + goto IL_00b7; + IL_00a4: + chars[num2] = 10; + i++; + num2++; + continue; + IL_00b7: + chars[num2] = text[i]; + num2++; + } + chars[num2] = 0; + } + } + + private void SetTextArrayToCharArray(char[] charArray, ref int[] charBuffer) + { + if (charArray != null && m_charArray_Length != 0) + { + if (charBuffer.Length <= m_charArray_Length) + { + int num = (m_charArray_Length <= 1024) ? Mathf.NextPowerOfTwo(m_charArray_Length + 1) : (m_charArray_Length + 256); + charBuffer = new int[num]; + } + int num2 = 0; + for (int i = 0; i < m_charArray_Length; i++) + { + if (charArray[i] == '\\' && i < m_charArray_Length - 1) + { + switch (charArray[i + 1]) + { + case 't': + break; + case 'n': + goto IL_00a7; + default: + goto IL_00ba; + } + charBuffer[num2] = 9; + i++; + num2++; + continue; + } + goto IL_00ba; + IL_00a7: + charBuffer[num2] = 10; + i++; + num2++; + continue; + IL_00ba: + charBuffer[num2] = charArray[i]; + num2++; + } + charBuffer[num2] = 0; + } + } + + private int GetArraySizes(int[] chars) + { + int num = 0; + int num2 = 0; + int endIndex = 0; + m_isUsingBold = false; + m_VisibleCharacters.Clear(); + for (int i = 0; chars[i] != 0; i++) + { + int num3 = chars[i]; + if (m_isRichText && num3 == 60 && ValidateHtmlTag(chars, i + 1, out endIndex)) + { + i = endIndex; + if ((m_style & FontStyles.Underline) == FontStyles.Underline) + { + num += 3; + } + if ((m_style & FontStyles.Bold) == FontStyles.Bold) + { + m_isUsingBold = true; + } + } + else + { + if (num3 != 32 && num3 != 9 && num3 != 10 && num3 != 13) + { + num++; + } + m_VisibleCharacters.Add((char)num3); + num2++; + } + } + return num2; + } + + private int SetArraySizes(int[] chars) + { + int num = 0; + int num2 = 0; + int endIndex = 0; + m_isUsingBold = false; + m_VisibleCharacters.Clear(); + for (int i = 0; chars[i] != 0; i++) + { + int num3 = chars[i]; + if (m_isRichText && num3 == 60 && ValidateHtmlTag(chars, i + 1, out endIndex)) + { + i = endIndex; + if ((m_style & FontStyles.Underline) == FontStyles.Underline) + { + num += 3; + } + if ((m_style & FontStyles.Bold) == FontStyles.Bold) + { + m_isUsingBold = true; + } + } + else + { + if (num3 != 32 && num3 != 9 && num3 != 10 && num3 != 13) + { + num++; + } + m_VisibleCharacters.Add((char)num3); + num2++; + } + } + if (m_textInfo.characterInfo == null || num2 > m_textInfo.characterInfo.Length) + { + m_textInfo.characterInfo = new TMP_CharacterInfo[(num2 <= 1024) ? Mathf.NextPowerOfTwo(num2) : (num2 + 256)]; + } + if (num * 4 > m_vertices.Length) + { + if (m_isFirstAllocation) + { + SetMeshArrays(num); + m_isFirstAllocation = false; + } + else + { + SetMeshArrays((num <= 1024) ? Mathf.NextPowerOfTwo(num) : (num + 256)); + } + } + return num2; + } + + private void OnDidApplyAnimationProperties() + { + havePropertiesChanged = true; + isMaskUpdateRequired = true; + } + + private void OnPreRenderObject() + { + } + + private void OnWillRenderObject() + { + if (!(m_fontAsset == null)) + { + if (m_transform.hasChanged) + { + m_transform.hasChanged = false; + if (m_transform.lossyScale != m_lossyScale) + { + havePropertiesChanged = true; + m_lossyScale = m_transform.lossyScale; + } + if (m_textContainer != null && m_textContainer.hasChanged) + { + isMaskUpdateRequired = true; + if (m_isTextTruncated) + { + isInputParsingRequired = true; + m_isTextTruncated = false; + } + m_textContainer.hasChanged = false; + havePropertiesChanged = true; + } + } + if (havePropertiesChanged || m_fontAsset.propertiesChanged) + { + if (hasFontAssetChanged || m_fontAsset.propertiesChanged) + { + LoadFontAsset(); + hasFontAssetChanged = false; + if (m_fontAsset == null || m_renderer.sharedMaterial == null) + { + return; + } + m_fontAsset.propertiesChanged = false; + } + if (isMaskUpdateRequired) + { + UpdateMask(); + isMaskUpdateRequired = false; + } + if (isInputParsingRequired) + { + isInputParsingRequired = false; + switch (m_inputSource) + { + case TextInputSources.Text: + StringToCharArray(m_text, ref m_char_buffer); + break; + case TextInputSources.SetText: + SetTextArrayToCharArray(m_input_CharArray, ref m_char_buffer); + break; + } + } + if (m_enableAutoSizing) + { + m_fontSize = Mathf.Clamp(m_fontSize, m_fontSizeMin, m_fontSizeMax); + } + m_maxFontSize = m_fontSizeMax; + m_minFontSize = m_fontSizeMin; + m_lineSpacingDelta = 0f; + m_recursiveCount = 0; + m_isCharacterWrappingEnabled = false; + m_isTextTruncated = false; + GenerateTextMesh(); + havePropertiesChanged = false; + } + } + } + + private void GenerateTextMesh() + { + if (m_fontAsset.characterDictionary == null) + { + UnityEngine.Debug.Log("Can't Generate Mesh! No Font Asset has been assigned to Object ID: " + GetInstanceID()); + } + else + { + if (m_textInfo != null) + { + m_textInfo.Clear(); + } + if (m_char_buffer == null || m_char_buffer[0] == 0) + { + if (m_vertices != null) + { + Array.Clear(m_vertices, 0, m_vertices.Length); + m_mesh.vertices = m_vertices; + } + m_preferredWidth = 0f; + m_preferredHeight = 0f; + } + else + { + int num = SetArraySizes(m_char_buffer); + m_fontIndex = 0; + m_fontAssetArray[m_fontIndex] = m_fontAsset; + m_fontScale = m_fontSize / m_fontAssetArray[m_fontIndex].fontInfo.PointSize * ((!m_isOrthographic) ? 0.1f : 1f); + float fontScale = m_fontScale; + m_maxFontScale = 0f; + float num2 = 0f; + m_currentFontSize = m_fontSize; + float num3 = 0f; + int num4 = 0; + m_style = m_fontStyle; + m_lineJustification = m_textAlignment; + if (checkPaddingRequired) + { + checkPaddingRequired = false; + m_padding = ShaderUtilities.GetPadding(m_renderer.sharedMaterials, m_enableExtraPadding, m_isUsingBold); + m_alignmentPadding = ShaderUtilities.GetFontExtent(m_sharedMaterial); + m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial); + } + float num5 = 0f; + float num6 = 1f; + m_baselineOffset = 0f; + bool flag = false; + Vector3 start = Vector3.zero; + Vector3 zero = Vector3.zero; + m_fontColor32 = m_fontColor; + m_htmlColor = m_fontColor32; + m_lineOffset = 0f; + m_lineHeight = 0f; + m_cSpacing = 0f; + m_monoSpacing = 0f; + float num7 = 0f; + m_xAdvance = 0f; + m_indent = 0f; + m_maxXAdvance = 0f; + m_lineNumber = 0; + m_pageNumber = 0; + m_characterCount = 0; + m_visibleCharacterCount = 0; + m_firstVisibleCharacterOfLine = 0; + m_lastVisibleCharacterOfLine = 0; + int num8 = 0; + Vector3[] corners = m_textContainer.corners; + Vector4 margins = m_textContainer.margins; + m_marginWidth = m_textContainer.rect.width - margins.z - margins.x; + float num9 = m_textContainer.rect.height - margins.y - margins.w; + m_preferredWidth = 0f; + m_preferredHeight = 0f; + bool flag2 = true; + bool flag3 = false; + m_SavedWordWrapState = default(WordWrapState); + m_SavedLineState = default(WordWrapState); + int num10 = 0; + m_meshExtents = new Extents(k_InfinityVector, -k_InfinityVector); + if (m_textInfo.lineInfo == null) + { + m_textInfo.lineInfo = new TMP_LineInfo[2]; + } + for (int i = 0; i < m_textInfo.lineInfo.Length; i++) + { + m_textInfo.lineInfo[i] = default(TMP_LineInfo); + m_textInfo.lineInfo[i].lineExtents = new Extents(k_InfinityVector, -k_InfinityVector); + m_textInfo.lineInfo[i].ascender = 0f - k_InfinityVector.x; + m_textInfo.lineInfo[i].descender = k_InfinityVector.x; + } + m_maxAscender = 0f; + m_maxDescender = 0f; + m_isNewPage = false; + float num11 = 0f; + int endIndex = 0; + for (int j = 0; m_char_buffer[j] != 0; j++) + { + num4 = m_char_buffer[j]; + loopCountE++; + if (m_isRichText && num4 == 60 && ValidateHtmlTag(m_char_buffer, j + 1, out endIndex)) + { + j = endIndex; + if (m_isRecalculateScaleRequired) + { + m_fontScale = m_currentFontSize / m_fontAssetArray[m_fontIndex].fontInfo.PointSize * ((!m_isOrthographic) ? 0.1f : 1f); + m_isRecalculateScaleRequired = false; + } + continue; + } + bool flag4 = false; + if ((m_style & FontStyles.UpperCase) == FontStyles.UpperCase) + { + if (char.IsLower((char)num4)) + { + num4 -= 32; + } + } + else if ((m_style & FontStyles.LowerCase) == FontStyles.LowerCase) + { + if (char.IsUpper((char)num4)) + { + num4 += 32; + } + } + else if ((m_fontStyle & FontStyles.SmallCaps) == FontStyles.SmallCaps || (m_style & FontStyles.SmallCaps) == FontStyles.SmallCaps) + { + if (char.IsLower((char)num4)) + { + m_fontScale = m_currentFontSize * 0.8f / m_fontAssetArray[m_fontIndex].fontInfo.PointSize * ((!m_isOrthographic) ? 0.1f : 1f); + num4 -= 32; + } + else + { + m_fontScale = m_currentFontSize / m_fontAssetArray[m_fontIndex].fontInfo.PointSize * ((!m_isOrthographic) ? 0.1f : 1f); + } + } + m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(num4, out m_cached_GlyphInfo); + if (m_cached_GlyphInfo == null) + { + if (char.IsLower((char)num4)) + { + if (m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(num4 - 32, out m_cached_GlyphInfo)) + { + num4 -= 32; + } + } + else if (char.IsUpper((char)num4) && m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(num4 + 32, out m_cached_GlyphInfo)) + { + num4 += 32; + } + if (m_cached_GlyphInfo == null) + { + m_fontAssetArray[m_fontIndex].characterDictionary.TryGetValue(88, out m_cached_GlyphInfo); + if (m_cached_GlyphInfo == null) + { + UnityEngine.Debug.LogWarning("Character with ASCII value of " + num4 + " was not found in the Font Asset Glyph Table."); + continue; + } + UnityEngine.Debug.LogWarning("Character with ASCII value of " + num4 + " was not found in the Font Asset Glyph Table."); + num4 = 88; + flag4 = true; + } + } + m_textInfo.characterInfo[m_characterCount].character = (char)num4; + m_textInfo.characterInfo[m_characterCount].color = m_htmlColor; + m_textInfo.characterInfo[m_characterCount].style = m_style; + m_textInfo.characterInfo[m_characterCount].index = (short)j; + if (m_enableKerning && m_characterCount >= 1) + { + int character = m_textInfo.characterInfo[m_characterCount - 1].character; + KerningPairKey kerningPairKey = new KerningPairKey(character, num4); + m_fontAssetArray[m_fontIndex].kerningDictionary.TryGetValue(kerningPairKey.key, out KerningPair value); + if (value != null) + { + m_xAdvance += value.XadvanceOffset * m_fontScale; + } + } + if (m_monoSpacing != 0f && m_xAdvance != 0f) + { + m_xAdvance -= (m_cached_GlyphInfo.width / 2f + m_cached_GlyphInfo.xOffset) * m_fontScale; + } + if ((m_style & FontStyles.Bold) == FontStyles.Bold || (m_fontStyle & FontStyles.Bold) == FontStyles.Bold) + { + num5 = m_fontAssetArray[m_fontIndex].BoldStyle * 2f; + num6 = 1.07f; + } + else + { + num5 = m_fontAssetArray[m_fontIndex].NormalStyle * 2f; + num6 = 1f; + } + Vector3 vector = new Vector3(0f + m_xAdvance + (m_cached_GlyphInfo.xOffset - m_padding - num5) * m_fontScale, (m_cached_GlyphInfo.yOffset + m_baselineOffset + m_padding) * m_fontScale - m_lineOffset, 0f); + Vector3 vector2 = new Vector3(vector.x, vector.y - (m_cached_GlyphInfo.height + m_padding * 2f) * m_fontScale, 0f); + Vector3 vector3 = new Vector3(vector2.x + (m_cached_GlyphInfo.width + m_padding * 2f + num5 * 2f) * m_fontScale, vector.y, 0f); + Vector3 vector4 = new Vector3(vector3.x, vector2.y, 0f); + if ((m_style & FontStyles.Italic) == FontStyles.Italic || (m_fontStyle & FontStyles.Italic) == FontStyles.Italic) + { + float num12 = (float)(int)m_fontAssetArray[m_fontIndex].ItalicStyle * 0.01f; + Vector3 b = new Vector3(num12 * ((m_cached_GlyphInfo.yOffset + m_padding + num5) * m_fontScale), 0f, 0f); + Vector3 b2 = new Vector3(num12 * ((m_cached_GlyphInfo.yOffset - m_cached_GlyphInfo.height - m_padding - num5) * m_fontScale), 0f, 0f); + vector += b; + vector2 += b2; + vector3 += b; + vector4 += b2; + } + m_textInfo.characterInfo[m_characterCount].topLeft = vector; + m_textInfo.characterInfo[m_characterCount].bottomLeft = vector2; + m_textInfo.characterInfo[m_characterCount].topRight = vector3; + m_textInfo.characterInfo[m_characterCount].bottomRight = vector4; + float num13 = (m_fontAsset.fontInfo.Ascender + m_baselineOffset + m_alignmentPadding.y) * m_fontScale; + if (m_lineNumber == 0) + { + m_maxAscender = ((!(m_maxAscender > num13)) ? num13 : m_maxAscender); + } + if (m_lineOffset == 0f) + { + num11 = ((!(num11 > num13)) ? num13 : num11); + } + float num14 = (m_fontAsset.fontInfo.Descender + m_baselineOffset + m_alignmentPadding.w) * m_fontScale - m_lineOffset; + m_textInfo.characterInfo[m_characterCount].isVisible = false; + if (num4 != 32 && num4 != 9 && num4 != 10 && num4 != 13) + { + int num15 = m_visibleCharacterCount * 4; + m_textInfo.characterInfo[m_characterCount].isVisible = true; + m_textInfo.characterInfo[m_characterCount].vertexIndex = (short)(0 + num15); + m_vertices[0 + num15] = m_textInfo.characterInfo[m_characterCount].bottomLeft; + m_vertices[1 + num15] = m_textInfo.characterInfo[m_characterCount].topLeft; + m_vertices[2 + num15] = m_textInfo.characterInfo[m_characterCount].bottomRight; + m_vertices[3 + num15] = m_textInfo.characterInfo[m_characterCount].topRight; + if (m_baselineOffset == 0f) + { + m_maxFontScale = Mathf.Max(m_maxFontScale, m_fontScale); + } + if (m_xAdvance + m_cached_GlyphInfo.xAdvance * m_fontScale > m_marginWidth + 0.0001f && !m_textContainer.isDefaultWidth) + { + num8 = m_characterCount - 1; + if (enableWordWrapping && m_characterCount != m_firstVisibleCharacterOfLine) + { + if (num10 == m_SavedWordWrapState.previous_WordBreak) + { + if (m_enableAutoSizing && m_fontSize > m_fontSizeMin) + { + m_maxFontSize = m_fontSize; + float num16 = Mathf.Max((m_fontSize - m_minFontSize) / 2f, 0.01f); + m_fontSize -= num16; + m_fontSize = (float)(int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 100f + 0.5f) / 100f; + GenerateTextMesh(); + return; + } + if (!m_isCharacterWrappingEnabled) + { + m_isCharacterWrappingEnabled = true; + } + else + { + flag3 = true; + } + m_recursiveCount++; + if (m_recursiveCount > 5) + { + continue; + } + } + j = RestoreWordWrappingState(ref m_SavedWordWrapState); + num10 = j; + if (m_lineNumber > 0 && m_maxFontScale != 0f && m_lineHeight == 0f && m_maxFontScale != num2 && !m_isNewPage) + { + float num17 = m_fontAssetArray[m_fontIndex].fontInfo.LineHeight - (m_fontAssetArray[m_fontIndex].fontInfo.Ascender - m_fontAssetArray[m_fontIndex].fontInfo.Descender); + float num18 = (m_fontAssetArray[m_fontIndex].fontInfo.Ascender + num17 + m_lineSpacing + m_lineSpacingDelta) * m_maxFontScale - (m_fontAssetArray[m_fontIndex].fontInfo.Descender - num17) * num2; + m_lineOffset += num18 - num7; + AdjustLineOffset(m_firstVisibleCharacterOfLine, m_characterCount - 1, num18 - num7); + } + m_isNewPage = false; + float num19 = (m_fontAsset.fontInfo.Ascender + m_alignmentPadding.y) * m_maxFontScale - m_lineOffset; + float num20 = (m_fontAsset.fontInfo.Ascender + m_baselineOffset + m_alignmentPadding.y) * m_fontScale - m_lineOffset; + num19 = ((!(num19 > num20)) ? num20 : num19); + float num21 = (m_fontAsset.fontInfo.Descender + m_alignmentPadding.w) * m_maxFontScale - m_lineOffset; + float num22 = (m_fontAsset.fontInfo.Descender + m_baselineOffset + m_alignmentPadding.w) * m_fontScale - m_lineOffset; + num21 = ((!(num21 < num22)) ? num22 : num21); + if (m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].isVisible) + { + m_maxDescender = ((!(m_maxDescender < num21)) ? num21 : m_maxDescender); + } + m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex = m_firstVisibleCharacterOfLine; + m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = ((m_characterCount - 1 <= 0) ? 1 : (m_characterCount - 1)); + m_textInfo.lineInfo[m_lineNumber].lastVisibleCharacterIndex = m_lastVisibleCharacterOfLine; + m_textInfo.lineInfo[m_lineNumber].lineExtents.min = new Vector2(m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].bottomLeft.x, num21); + m_textInfo.lineInfo[m_lineNumber].lineExtents.max = new Vector2(m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].topRight.x, num19); + m_textInfo.lineInfo[m_lineNumber].lineLength = m_textInfo.lineInfo[m_lineNumber].lineExtents.max.x - m_padding * m_maxFontScale; + m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - m_characterSpacing; + m_firstVisibleCharacterOfLine = m_characterCount; + m_preferredWidth += m_xAdvance; + if (m_enableWordWrapping) + { + m_preferredHeight = m_maxAscender - m_maxDescender; + } + else + { + m_preferredHeight = Mathf.Max(m_preferredHeight, num19 - num21); + } + SaveWordWrappingState(ref m_SavedLineState, j, m_characterCount - 1); + m_lineNumber++; + if (m_lineNumber >= m_textInfo.lineInfo.Length) + { + ResizeLineExtents(m_lineNumber); + } + if (m_lineHeight == 0f) + { + num7 = (m_fontAssetArray[m_fontIndex].fontInfo.LineHeight + m_lineSpacing + m_lineSpacingDelta) * m_fontScale; + m_lineOffset += num7; + } + else + { + m_lineOffset += (m_lineHeight + m_lineSpacing) * fontScale; + } + num2 = m_fontScale; + m_xAdvance = 0f + m_indent; + m_maxFontScale = 0f; + continue; + } + if (m_enableAutoSizing && m_fontSize > m_fontSizeMin) + { + m_maxFontSize = m_fontSize; + float num23 = Mathf.Max((m_fontSize - m_minFontSize) / 2f, 0.01f); + m_fontSize -= num23; + m_fontSize = (float)(int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 100f + 0.5f) / 100f; + m_recursiveCount = 0; + GenerateTextMesh(); + return; + } + switch (m_overflowMode) + { + case TextOverflowModes.Overflow: + if (m_isMaskingEnabled) + { + DisableMasking(); + } + break; + case TextOverflowModes.Ellipsis: + if (m_isMaskingEnabled) + { + DisableMasking(); + } + m_isTextTruncated = true; + if (m_characterCount >= 1) + { + m_char_buffer[j - 1] = 8230; + m_char_buffer[j] = 0; + GenerateTextMesh(); + return; + } + m_textInfo.characterInfo[m_characterCount].isVisible = false; + m_visibleCharacterCount--; + break; + case TextOverflowModes.Masking: + if (!m_isMaskingEnabled) + { + EnableMasking(); + } + break; + case TextOverflowModes.ScrollRect: + if (!m_isMaskingEnabled) + { + EnableMasking(); + } + break; + case TextOverflowModes.Truncate: + if (m_isMaskingEnabled) + { + DisableMasking(); + } + m_textInfo.characterInfo[m_characterCount].isVisible = false; + break; + } + } + Color32 color = flag4 ? ((Color32)Color.red) : ((!m_overrideHtmlColors) ? m_htmlColor : m_fontColor32); + if ((m_style & FontStyles.Bold) == FontStyles.Bold || (m_fontStyle & FontStyles.Bold) == FontStyles.Bold) + { + color.a = ((m_fontColor32.a >= color.a) ? ((byte)(color.a >> 1)) : ((byte)(m_fontColor32.a >> 1))); + color.a += 128; + } + else + { + color.a = ((m_fontColor32.a >= color.a) ? ((byte)(color.a >> 1)) : ((byte)(m_fontColor32.a >> 1))); + } + if (!m_enableVertexGradient) + { + m_vertColors[0 + num15] = color; + m_vertColors[1 + num15] = color; + m_vertColors[2 + num15] = color; + m_vertColors[3 + num15] = color; + } + else + { + if (!m_overrideHtmlColors && !m_htmlColor.CompareRGB(m_fontColor32)) + { + m_vertColors[0 + num15] = color; + m_vertColors[1 + num15] = color; + m_vertColors[2 + num15] = color; + m_vertColors[3 + num15] = color; + } + else + { + m_vertColors[0 + num15] = m_fontColorGradient.bottomLeft; + m_vertColors[1 + num15] = m_fontColorGradient.topLeft; + m_vertColors[2 + num15] = m_fontColorGradient.bottomRight; + m_vertColors[3 + num15] = m_fontColorGradient.topRight; + } + m_vertColors[0 + num15].a = color.a; + m_vertColors[1 + num15].a = color.a; + m_vertColors[2 + num15].a = color.a; + m_vertColors[3 + num15].a = color.a; + } + if (!m_sharedMaterial.HasProperty(ShaderUtilities.ID_WeightNormal)) + { + num5 = 0f; + } + Vector2 vector5 = new Vector2((m_cached_GlyphInfo.x - m_padding - num5) / m_fontAssetArray[m_fontIndex].fontInfo.AtlasWidth, 1f - (m_cached_GlyphInfo.y + m_padding + num5 + m_cached_GlyphInfo.height) / m_fontAssetArray[m_fontIndex].fontInfo.AtlasHeight); + Vector2 vector6 = new Vector2(vector5.x, 1f - (m_cached_GlyphInfo.y - m_padding - num5) / m_fontAssetArray[m_fontIndex].fontInfo.AtlasHeight); + Vector2 vector7 = new Vector2((m_cached_GlyphInfo.x + m_padding + num5 + m_cached_GlyphInfo.width) / m_fontAssetArray[m_fontIndex].fontInfo.AtlasWidth, vector5.y); + Vector2 vector8 = new Vector2(vector7.x, vector6.y); + m_uvs[0 + num15] = vector5; + m_uvs[1 + num15] = vector6; + m_uvs[2 + num15] = vector7; + m_uvs[3 + num15] = vector8; + m_visibleCharacterCount++; + if (m_textInfo.characterInfo[m_characterCount].isVisible) + { + m_lastVisibleCharacterOfLine = m_characterCount; + } + } + else if (num4 == 9 || num4 == 32) + { + m_textInfo.lineInfo[m_lineNumber].spaceCount++; + m_textInfo.spaceCount++; + } + m_textInfo.characterInfo[m_characterCount].lineNumber = (short)m_lineNumber; + m_textInfo.characterInfo[m_characterCount].pageNumber = (short)m_pageNumber; + m_textInfo.lineInfo[m_lineNumber].characterCount++; + if ((num4 != 10 && num4 != 13 && num4 != 8230) || m_textInfo.lineInfo[m_lineNumber].characterCount == 1) + { + m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification; + } + if (m_maxAscender - num14 + m_alignmentPadding.w * 2f * m_fontScale > num9 && !m_textContainer.isDefaultHeight) + { + if (m_enableAutoSizing && m_lineSpacingDelta > m_lineSpacingMax) + { + m_lineSpacingDelta -= 1f; + GenerateTextMesh(); + } + else if (m_enableAutoSizing && m_fontSize > m_fontSizeMin) + { + m_maxFontSize = m_fontSize; + float num24 = Mathf.Max((m_fontSize - m_minFontSize) / 2f, 0.025f); + m_fontSize -= num24; + m_fontSize = (float)(int)(Mathf.Max(m_fontSize, m_fontSizeMin) * 100f + 0.5f) / 100f; + m_recursiveCount = 0; + GenerateTextMesh(); + } + else + { + switch (m_overflowMode) + { + case TextOverflowModes.Overflow: + if (m_isMaskingEnabled) + { + DisableMasking(); + } + goto IL_1d5c; + case TextOverflowModes.Ellipsis: + break; + case TextOverflowModes.Masking: + if (!m_isMaskingEnabled) + { + EnableMasking(); + } + goto IL_1d5c; + case TextOverflowModes.ScrollRect: + if (!m_isMaskingEnabled) + { + EnableMasking(); + } + goto IL_1d5c; + case TextOverflowModes.Truncate: + goto IL_1c6e; + case TextOverflowModes.Page: + goto IL_1cd1; + default: + goto IL_1d5c; + } + if (m_isMaskingEnabled) + { + DisableMasking(); + } + if (m_lineNumber > 0) + { + m_char_buffer[m_textInfo.characterInfo[num8].index] = 8230; + m_char_buffer[m_textInfo.characterInfo[num8].index + 1] = 0; + GenerateTextMesh(); + m_isTextTruncated = true; + } + else + { + m_char_buffer[0] = 0; + GenerateTextMesh(); + m_isTextTruncated = true; + } + } + return; + } + goto IL_1d5c; + IL_1cd1: + if (m_isMaskingEnabled) + { + DisableMasking(); + } + if (num4 != 13 && num4 != 10) + { + j = RestoreWordWrappingState(ref m_SavedLineState); + if (j == 0) + { + m_char_buffer[0] = 0; + GenerateTextMesh(); + m_isTextTruncated = true; + return; + } + m_isNewPage = true; + m_xAdvance = 0f + m_indent; + m_lineOffset = 0f; + m_pageNumber++; + continue; + } + goto IL_1d5c; + IL_1d5c: + if (num4 == 9) + { + m_xAdvance += m_fontAsset.fontInfo.TabWidth * m_fontScale * 5f; + } + else if (m_monoSpacing != 0f) + { + m_xAdvance += (m_monoSpacing + m_cached_GlyphInfo.width / 2f + m_cached_GlyphInfo.xOffset) * m_fontScale + m_characterSpacing + m_cSpacing; + } + else + { + m_xAdvance += m_cached_GlyphInfo.xAdvance * num6 * m_fontScale + m_characterSpacing + m_cSpacing; + } + m_textInfo.characterInfo[m_characterCount].xAdvance = m_xAdvance; + if (num4 == 13) + { + m_maxXAdvance = Mathf.Max(m_maxXAdvance, m_preferredWidth + m_xAdvance + m_alignmentPadding.z * m_fontScale); + m_preferredWidth = 0f; + m_xAdvance = 0f + m_indent; + } + if (num4 == 10 || m_characterCount == num - 1) + { + if (m_lineNumber > 0 && m_maxFontScale != 0f && m_lineHeight == 0f && m_maxFontScale != num2 && !m_isNewPage) + { + float num25 = m_fontAssetArray[m_fontIndex].fontInfo.LineHeight - (m_fontAssetArray[m_fontIndex].fontInfo.Ascender - m_fontAssetArray[m_fontIndex].fontInfo.Descender); + float num26 = (m_fontAssetArray[m_fontIndex].fontInfo.Ascender + num25 + m_lineSpacing + m_paragraphSpacing + m_lineSpacingDelta) * m_maxFontScale - (m_fontAssetArray[m_fontIndex].fontInfo.Descender - num25) * num2; + m_lineOffset += num26 - num7; + AdjustLineOffset(m_firstVisibleCharacterOfLine, m_characterCount, num26 - num7); + } + m_isNewPage = false; + float num27 = (m_fontAsset.fontInfo.Ascender + m_alignmentPadding.y) * m_maxFontScale - m_lineOffset; + float num28 = (m_fontAsset.fontInfo.Ascender + m_baselineOffset + m_alignmentPadding.y) * m_fontScale - m_lineOffset; + num27 = ((!(num27 > num28)) ? num28 : num27); + float num29 = (m_fontAsset.fontInfo.Descender + m_alignmentPadding.w) * m_maxFontScale - m_lineOffset; + float num30 = (m_fontAsset.fontInfo.Descender + m_baselineOffset + m_alignmentPadding.w) * m_fontScale - m_lineOffset; + num29 = ((!(num29 < num30)) ? num30 : num29); + if (m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].isVisible) + { + m_maxDescender = ((!(m_maxDescender < num29)) ? num29 : m_maxDescender); + } + m_textInfo.lineInfo[m_lineNumber].firstCharacterIndex = m_firstVisibleCharacterOfLine; + m_textInfo.lineInfo[m_lineNumber].lastCharacterIndex = m_characterCount; + m_textInfo.lineInfo[m_lineNumber].lastVisibleCharacterIndex = m_lastVisibleCharacterOfLine; + m_textInfo.lineInfo[m_lineNumber].lineExtents.min = new Vector2(m_textInfo.characterInfo[m_firstVisibleCharacterOfLine].bottomLeft.x, num29); + m_textInfo.lineInfo[m_lineNumber].lineExtents.max = new Vector2(m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].topRight.x, num27); + m_textInfo.lineInfo[m_lineNumber].lineLength = m_textInfo.lineInfo[m_lineNumber].lineExtents.max.x - m_padding * m_maxFontScale; + m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance - m_characterSpacing; + m_firstVisibleCharacterOfLine = m_characterCount + 1; + if (num4 == 10 && m_characterCount != num - 1) + { + m_maxXAdvance = Mathf.Max(m_maxXAdvance, m_preferredWidth + m_xAdvance + m_alignmentPadding.z * m_fontScale); + m_preferredWidth = 0f; + } + else + { + m_preferredWidth = Mathf.Max(m_maxXAdvance, m_preferredWidth + m_xAdvance + m_alignmentPadding.z * m_fontScale); + } + if (m_enableWordWrapping) + { + m_preferredHeight = m_maxAscender - m_maxDescender; + } + else + { + m_preferredHeight = Mathf.Max(m_preferredHeight, num27 - num29); + } + if (num4 == 10) + { + SaveWordWrappingState(ref m_SavedLineState, j, m_characterCount); + SaveWordWrappingState(ref m_SavedWordWrapState, j, m_characterCount); + m_lineNumber++; + if (m_lineNumber >= m_textInfo.lineInfo.Length) + { + ResizeLineExtents(m_lineNumber); + } + if (m_lineHeight == 0f) + { + num7 = (m_fontAssetArray[m_fontIndex].fontInfo.LineHeight + m_paragraphSpacing + m_lineSpacing + m_lineSpacingDelta) * m_fontScale; + m_lineOffset += num7; + } + else + { + m_lineOffset += (m_lineHeight + m_paragraphSpacing + m_lineSpacing) * fontScale; + } + num2 = m_fontScale; + m_maxFontScale = 0f; + m_xAdvance = 0f + m_indent; + num8 = m_characterCount - 1; + } + } + m_textInfo.characterInfo[m_characterCount].baseLine = m_textInfo.characterInfo[m_characterCount].topRight.y - (m_cached_GlyphInfo.yOffset + m_padding) * m_fontScale; + m_textInfo.characterInfo[m_characterCount].topLine = m_textInfo.characterInfo[m_characterCount].baseLine + (m_fontAssetArray[m_fontIndex].fontInfo.Ascender + m_alignmentPadding.y) * m_fontScale; + m_textInfo.characterInfo[m_characterCount].bottomLine = m_textInfo.characterInfo[m_characterCount].baseLine + (m_fontAssetArray[m_fontIndex].fontInfo.Descender - m_alignmentPadding.w) * m_fontScale; + m_textInfo.characterInfo[m_characterCount].padding = m_padding * m_fontScale; + m_textInfo.characterInfo[m_characterCount].aspectRatio = m_cached_GlyphInfo.width / m_cached_GlyphInfo.height; + m_textInfo.characterInfo[m_characterCount].scale = m_fontScale; + if (m_textInfo.characterInfo[m_characterCount].isVisible) + { + m_meshExtents.min = new Vector2(Mathf.Min(m_meshExtents.min.x, m_textInfo.characterInfo[m_characterCount].bottomLeft.x), Mathf.Min(m_meshExtents.min.y, m_textInfo.characterInfo[m_characterCount].bottomLeft.y)); + m_meshExtents.max = new Vector2(Mathf.Max(m_meshExtents.max.x, m_textInfo.characterInfo[m_characterCount].topRight.x), Mathf.Max(m_meshExtents.max.y, m_textInfo.characterInfo[m_characterCount].topLeft.y)); + } + if (num4 != 13 && num4 != 10 && m_pageNumber < 16) + { + m_textInfo.pageInfo[m_pageNumber].ascender = num11; + m_textInfo.pageInfo[m_pageNumber].descender = ((!(num14 < m_textInfo.pageInfo[m_pageNumber].descender)) ? m_textInfo.pageInfo[m_pageNumber].descender : num14); + if (m_pageNumber == 0 && m_characterCount == 0) + { + m_textInfo.pageInfo[m_pageNumber].firstCharacterIndex = m_characterCount; + } + else if (m_characterCount > 0 && m_pageNumber != m_textInfo.characterInfo[m_characterCount - 1].pageNumber) + { + m_textInfo.pageInfo[m_pageNumber - 1].lastCharacterIndex = m_characterCount - 1; + m_textInfo.pageInfo[m_pageNumber].firstCharacterIndex = m_characterCount; + } + else if (m_characterCount == num - 1) + { + m_textInfo.pageInfo[m_pageNumber].lastCharacterIndex = m_characterCount; + } + } + if (m_enableWordWrapping || m_overflowMode == TextOverflowModes.Truncate || m_overflowMode == TextOverflowModes.Ellipsis) + { + if (num4 == 9 || num4 == 32) + { + SaveWordWrappingState(ref m_SavedWordWrapState, j, m_characterCount); + m_isCharacterWrappingEnabled = false; + flag2 = false; + } + else if (((flag2 || m_isCharacterWrappingEnabled) && m_characterCount < num - 1 && !m_fontAsset.lineBreakingInfo.leadingCharacters.ContainsKey(num4) && !m_fontAsset.lineBreakingInfo.followingCharacters.ContainsKey(m_VisibleCharacters[m_characterCount + 1])) || flag3) + { + SaveWordWrappingState(ref m_SavedWordWrapState, j, m_characterCount); + } + } + m_characterCount++; + continue; + IL_1c6e: + if (m_isMaskingEnabled) + { + DisableMasking(); + } + if (m_lineNumber > 0) + { + m_char_buffer[m_textInfo.characterInfo[num8].index + 1] = 0; + GenerateTextMesh(); + m_isTextTruncated = true; + } + else + { + m_char_buffer[0] = 0; + GenerateTextMesh(); + m_isTextTruncated = true; + } + return; + } + num3 = m_maxFontSize - m_minFontSize; + if ((!m_textContainer.isDefaultWidth || !m_textContainer.isDefaultHeight) && !m_isCharacterWrappingEnabled && m_enableAutoSizing && num3 > 0.25f && m_fontSize < m_fontSizeMax) + { + m_minFontSize = m_fontSize; + m_fontSize += Mathf.Max(m_maxFontSize + m_fontSize / 2f, 0.01f); + m_fontSize = (float)(int)(Mathf.Min(m_fontSize, m_fontSizeMax) * 100f + 0.5f) / 100f; + GenerateTextMesh(); + } + else + { + if (m_characterCount < m_textInfo.characterInfo.Length) + { + m_textInfo.characterInfo[m_characterCount].character = '\0'; + } + m_isCharacterWrappingEnabled = false; + if (m_renderMode != TextRenderFlags.GetPreferredSizes) + { + if (m_visibleCharacterCount == 0) + { + if (m_vertices != null) + { + Array.Clear(m_vertices, 0, m_vertices.Length); + m_mesh.vertices = m_vertices; + } + } + else + { + int index = m_visibleCharacterCount * 4; + Array.Clear(m_vertices, index, m_vertices.Length - index); + switch (m_textAlignment) + { + case TextAlignmentOptions.TopLeft: + case TextAlignmentOptions.Top: + case TextAlignmentOptions.TopRight: + case TextAlignmentOptions.TopJustified: + if (m_overflowMode != TextOverflowModes.Page) + { + m_anchorOffset = corners[1] + new Vector3(0f + margins.x, 0f - m_maxAscender - margins.y, 0f); + } + else + { + m_anchorOffset = corners[1] + new Vector3(0f + margins.x, 0f - m_textInfo.pageInfo[m_pageToDisplay].ascender - margins.y, 0f); + } + break; + case TextAlignmentOptions.Left: + case TextAlignmentOptions.Center: + case TextAlignmentOptions.Right: + case TextAlignmentOptions.Justified: + if (m_overflowMode != TextOverflowModes.Page) + { + m_anchorOffset = (corners[0] + corners[1]) / 2f + new Vector3(0f + margins.x, 0f - (m_maxAscender + margins.y + m_maxDescender - margins.w) / 2f, 0f); + } + else + { + m_anchorOffset = (corners[0] + corners[1]) / 2f + new Vector3(0f + margins.x, 0f - (m_textInfo.pageInfo[m_pageToDisplay].ascender + margins.y + m_textInfo.pageInfo[m_pageToDisplay].descender - margins.w) / 2f, 0f); + } + break; + case TextAlignmentOptions.BottomLeft: + case TextAlignmentOptions.Bottom: + case TextAlignmentOptions.BottomRight: + case TextAlignmentOptions.BottomJustified: + if (m_overflowMode != TextOverflowModes.Page) + { + m_anchorOffset = corners[0] + new Vector3(0f + margins.x, 0f - m_maxDescender + margins.w, 0f); + } + else + { + m_anchorOffset = corners[0] + new Vector3(0f + margins.x, 0f - m_textInfo.pageInfo[m_pageToDisplay].descender + margins.w, 0f); + } + break; + case TextAlignmentOptions.BaselineLeft: + case TextAlignmentOptions.Baseline: + case TextAlignmentOptions.BaselineRight: + m_anchorOffset = (corners[0] + corners[1]) / 2f + new Vector3(0f + margins.x, 0f, 0f); + break; + } + Vector3 vector9 = Vector3.zero; + Vector3 zero2 = Vector3.zero; + int num31 = 0; + int num32 = 0; + int num33 = 0; + int num34 = 0; + bool flag5 = false; + int num35 = 0; + int num36 = 0; + for (int k = 0; k < m_characterCount; k++) + { + int lineNumber = m_textInfo.characterInfo[k].lineNumber; + char character2 = m_textInfo.characterInfo[k].character; + TMP_LineInfo tMP_LineInfo = m_textInfo.lineInfo[lineNumber]; + TextAlignmentOptions alignment = tMP_LineInfo.alignment; + num33 = lineNumber + 1; + switch (alignment) + { + case TextAlignmentOptions.TopLeft: + case TextAlignmentOptions.Left: + case TextAlignmentOptions.BottomLeft: + case TextAlignmentOptions.BaselineLeft: + vector9 = Vector3.zero; + break; + case TextAlignmentOptions.Top: + case TextAlignmentOptions.Center: + case TextAlignmentOptions.Bottom: + case TextAlignmentOptions.Baseline: + vector9 = new Vector3(m_marginWidth / 2f - tMP_LineInfo.maxAdvance / 2f, 0f, 0f); + break; + case TextAlignmentOptions.TopRight: + case TextAlignmentOptions.Right: + case TextAlignmentOptions.BottomRight: + case TextAlignmentOptions.BaselineRight: + vector9 = new Vector3(m_marginWidth - tMP_LineInfo.maxAdvance, 0f, 0f); + break; + case TextAlignmentOptions.TopJustified: + case TextAlignmentOptions.Justified: + case TextAlignmentOptions.BottomJustified: + { + num4 = m_textInfo.characterInfo[k].character; + char character3 = m_textInfo.characterInfo[tMP_LineInfo.lastCharacterIndex].character; + if (char.IsWhiteSpace(character3) && !char.IsControl(character3) && lineNumber < m_lineNumber) + { + float num37 = corners[3].x - margins.z - (corners[0].x + margins.x) - tMP_LineInfo.maxAdvance; + vector9 = ((lineNumber == num34 && k != 0) ? ((num4 != 9 && num4 != 32) ? (vector9 + new Vector3(num37 * m_wordWrappingRatios / (float)(tMP_LineInfo.characterCount - tMP_LineInfo.spaceCount - 1), 0f, 0f)) : (vector9 + new Vector3(num37 * (1f - m_wordWrappingRatios) / (float)(tMP_LineInfo.spaceCount - 1), 0f, 0f))) : Vector3.zero); + } + else + { + vector9 = Vector3.zero; + } + break; + } + } + zero2 = m_anchorOffset + vector9; + if (m_textInfo.characterInfo[k].isVisible) + { + Extents lineExtents = tMP_LineInfo.lineExtents; + float num38 = m_uvLineOffset * (float)lineNumber % 1f + m_uvOffset.x; + switch (m_horizontalMapping) + { + case TextureMappingOptions.Character: + m_uv2s[num31].x = 0f + m_uvOffset.x; + m_uv2s[num31 + 1].x = 0f + m_uvOffset.x; + m_uv2s[num31 + 2].x = 1f + m_uvOffset.x; + m_uv2s[num31 + 3].x = 1f + m_uvOffset.x; + break; + case TextureMappingOptions.Line: + if (m_textAlignment != TextAlignmentOptions.Justified) + { + m_uv2s[num31].x = (m_vertices[num31].x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + num38; + m_uv2s[num31 + 1].x = (m_vertices[num31 + 1].x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + num38; + m_uv2s[num31 + 2].x = (m_vertices[num31 + 2].x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + num38; + m_uv2s[num31 + 3].x = (m_vertices[num31 + 3].x - lineExtents.min.x) / (lineExtents.max.x - lineExtents.min.x) + num38; + } + else + { + m_uv2s[num31].x = (m_vertices[num31].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + m_uv2s[num31 + 1].x = (m_vertices[num31 + 1].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + m_uv2s[num31 + 2].x = (m_vertices[num31 + 2].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + m_uv2s[num31 + 3].x = (m_vertices[num31 + 3].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + } + break; + case TextureMappingOptions.Paragraph: + m_uv2s[num31].x = (m_vertices[num31].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + m_uv2s[num31 + 1].x = (m_vertices[num31 + 1].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + m_uv2s[num31 + 2].x = (m_vertices[num31 + 2].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + m_uv2s[num31 + 3].x = (m_vertices[num31 + 3].x + vector9.x - m_meshExtents.min.x) / (m_meshExtents.max.x - m_meshExtents.min.x) + num38; + break; + case TextureMappingOptions.MatchAspect: + { + switch (m_verticalMapping) + { + case TextureMappingOptions.Character: + m_uv2s[num31].y = 0f + m_uvOffset.y; + m_uv2s[num31 + 1].y = 1f + m_uvOffset.y; + m_uv2s[num31 + 2].y = 0f + m_uvOffset.y; + m_uv2s[num31 + 3].y = 1f + m_uvOffset.y; + break; + case TextureMappingOptions.Line: + m_uv2s[num31].y = (m_vertices[num31].y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + num38; + m_uv2s[num31 + 1].y = (m_vertices[num31 + 1].y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + num38; + m_uv2s[num31 + 2].y = m_uv2s[num31].y; + m_uv2s[num31 + 3].y = m_uv2s[num31 + 1].y; + break; + case TextureMappingOptions.Paragraph: + m_uv2s[num31].y = (m_vertices[num31].y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y) + num38; + m_uv2s[num31 + 1].y = (m_vertices[num31 + 1].y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y) + num38; + m_uv2s[num31 + 2].y = m_uv2s[num31].y; + m_uv2s[num31 + 3].y = m_uv2s[num31 + 1].y; + break; + case TextureMappingOptions.MatchAspect: + UnityEngine.Debug.Log("ERROR: Cannot Match both Vertical & Horizontal."); + break; + } + float num39 = (1f - (m_uv2s[num31].y + m_uv2s[num31 + 1].y) * m_textInfo.characterInfo[k].aspectRatio) / 2f; + m_uv2s[num31].x = m_uv2s[num31].y * m_textInfo.characterInfo[k].aspectRatio + num39 + num38; + m_uv2s[num31 + 1].x = m_uv2s[num31].x; + m_uv2s[num31 + 2].x = m_uv2s[num31 + 1].y * m_textInfo.characterInfo[k].aspectRatio + num39 + num38; + m_uv2s[num31 + 3].x = m_uv2s[num31 + 2].x; + break; + } + } + switch (m_verticalMapping) + { + case TextureMappingOptions.Character: + m_uv2s[num31].y = 0f + m_uvOffset.y; + m_uv2s[num31 + 1].y = 1f + m_uvOffset.y; + m_uv2s[num31 + 2].y = 0f + m_uvOffset.y; + m_uv2s[num31 + 3].y = 1f + m_uvOffset.y; + break; + case TextureMappingOptions.Line: + m_uv2s[num31].y = (m_vertices[num31].y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + m_uvOffset.y; + m_uv2s[num31 + 1].y = (m_vertices[num31 + 1].y - lineExtents.min.y) / (lineExtents.max.y - lineExtents.min.y) + m_uvOffset.y; + m_uv2s[num31 + 2].y = m_uv2s[num31].y; + m_uv2s[num31 + 3].y = m_uv2s[num31 + 1].y; + break; + case TextureMappingOptions.Paragraph: + m_uv2s[num31].y = (m_vertices[num31].y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y) + m_uvOffset.y; + m_uv2s[num31 + 1].y = (m_vertices[num31 + 1].y - m_meshExtents.min.y) / (m_meshExtents.max.y - m_meshExtents.min.y) + m_uvOffset.y; + m_uv2s[num31 + 2].y = m_uv2s[num31].y; + m_uv2s[num31 + 3].y = m_uv2s[num31 + 1].y; + break; + case TextureMappingOptions.MatchAspect: + { + float num40 = (1f - (m_uv2s[num31].x + m_uv2s[num31 + 2].x) / m_textInfo.characterInfo[k].aspectRatio) / 2f; + m_uv2s[num31].y = num40 + m_uv2s[num31].x / m_textInfo.characterInfo[k].aspectRatio + m_uvOffset.y; + m_uv2s[num31 + 1].y = num40 + m_uv2s[num31 + 2].x / m_textInfo.characterInfo[k].aspectRatio + m_uvOffset.y; + m_uv2s[num31 + 2].y = m_uv2s[num31].y; + m_uv2s[num31 + 3].y = m_uv2s[num31 + 1].y; + break; + } + } + float scale = m_textInfo.characterInfo[k].scale; + Vector3 lossyScale = m_transform.lossyScale; + float scale2 = scale * lossyScale.z; + float x = m_uv2s[num31].x; + float y = m_uv2s[num31].y; + float x2 = m_uv2s[num31 + 3].x; + float y2 = m_uv2s[num31 + 3].y; + float num41 = Mathf.Floor(x); + float num42 = Mathf.Floor(y); + x -= num41; + x2 -= num41; + y -= num42; + y2 -= num42; + m_uv2s[num31] = PackUV(x, y, scale2); + m_uv2s[num31 + 1] = PackUV(x, y2, scale2); + m_uv2s[num31 + 2] = PackUV(x2, y, scale2); + m_uv2s[num31 + 3] = PackUV(x2, y2, scale2); + if ((m_maxVisibleCharacters != -1 && k >= m_maxVisibleCharacters) || (m_maxVisibleLines != -1 && lineNumber >= m_maxVisibleLines) || (m_overflowMode == TextOverflowModes.Page && m_textInfo.characterInfo[k].pageNumber != m_pageToDisplay)) + { + m_vertices[num31] *= 0f; + m_vertices[num31 + 1] *= 0f; + m_vertices[num31 + 2] *= 0f; + m_vertices[num31 + 3] *= 0f; + } + else + { + m_vertices[num31] += zero2; + m_vertices[num31 + 1] += zero2; + m_vertices[num31 + 2] += zero2; + m_vertices[num31 + 3] += zero2; + } + num31 += 4; + } + m_textInfo.characterInfo[k].bottomLeft += zero2; + m_textInfo.characterInfo[k].topRight += zero2; + m_textInfo.characterInfo[k].topLine += zero2.y; + m_textInfo.characterInfo[k].bottomLine += zero2.y; + m_textInfo.characterInfo[k].baseLine += zero2.y; + m_textInfo.lineInfo[lineNumber].ascender = ((!(m_textInfo.characterInfo[k].topLine > m_textInfo.lineInfo[lineNumber].ascender)) ? m_textInfo.lineInfo[lineNumber].ascender : m_textInfo.characterInfo[k].topLine); + m_textInfo.lineInfo[lineNumber].descender = ((!(m_textInfo.characterInfo[k].bottomLine < m_textInfo.lineInfo[lineNumber].descender)) ? m_textInfo.lineInfo[lineNumber].descender : m_textInfo.characterInfo[k].bottomLine); + if (lineNumber != num34 || k == m_characterCount - 1) + { + if (lineNumber != num34) + { + m_textInfo.lineInfo[num34].lineExtents.min = new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[num34].firstCharacterIndex].bottomLeft.x, m_textInfo.lineInfo[num34].descender); + m_textInfo.lineInfo[num34].lineExtents.max = new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[num34].lastVisibleCharacterIndex].topRight.x, m_textInfo.lineInfo[num34].ascender); + } + if (k == m_characterCount - 1) + { + m_textInfo.lineInfo[lineNumber].lineExtents.min = new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[lineNumber].firstCharacterIndex].bottomLeft.x, m_textInfo.lineInfo[lineNumber].descender); + m_textInfo.lineInfo[lineNumber].lineExtents.max = new Vector2(m_textInfo.characterInfo[m_textInfo.lineInfo[lineNumber].lastVisibleCharacterIndex].topRight.x, m_textInfo.lineInfo[lineNumber].ascender); + } + } + if (char.IsLetterOrDigit(character2) && k < m_characterCount - 1) + { + if (!flag5) + { + flag5 = true; + num35 = k; + } + } + else if (((char.IsPunctuation(character2) || char.IsWhiteSpace(character2) || k == m_characterCount - 1) && flag5) || k == 0) + { + num36 = ((k != m_characterCount - 1 || !char.IsLetterOrDigit(character2)) ? (k - 1) : k); + flag5 = false; + num32++; + m_textInfo.lineInfo[lineNumber].wordCount++; + TMP_WordInfo item = default(TMP_WordInfo); + item.firstCharacterIndex = num35; + item.lastCharacterIndex = num36; + item.characterCount = num36 - num35 + 1; + m_textInfo.wordInfo.Add(item); + } + if ((m_textInfo.characterInfo[k].style & FontStyles.Underline) == FontStyles.Underline && k != m_textInfo.lineInfo[lineNumber].lastCharacterIndex) + { + if (!flag) + { + flag = true; + start = new Vector3(m_textInfo.characterInfo[k].bottomLeft.x, m_textInfo.characterInfo[k].baseLine + font.fontInfo.Underline * m_fontScale, 0f); + } + } + else if (flag) + { + flag = false; + zero = ((k != m_characterCount - 1 && (m_textInfo.characterInfo[k].character == ' ' || m_textInfo.characterInfo[k].character == '\n')) ? new Vector3(m_textInfo.characterInfo[k - 1].topRight.x, m_textInfo.characterInfo[k - 1].baseLine + font.fontInfo.Underline * m_fontScale, 0f) : new Vector3(m_textInfo.characterInfo[k].topRight.x, m_textInfo.characterInfo[k].baseLine + font.fontInfo.Underline * m_fontScale, 0f)); + DrawUnderlineMesh(start, zero, ref index); + } + num34 = lineNumber; + } + m_textInfo.characterCount = (short)m_characterCount; + m_textInfo.lineCount = (short)num33; + m_textInfo.wordCount = ((num32 == 0 || m_characterCount <= 0) ? 1 : ((short)num32)); + m_textInfo.pageCount = m_pageNumber; + m_textInfo.meshInfo.vertices = m_vertices; + m_textInfo.meshInfo.uv0s = m_uvs; + m_textInfo.meshInfo.uv2s = m_uv2s; + m_textInfo.meshInfo.vertexColors = m_vertColors; + if (m_renderMode == TextRenderFlags.Render) + { + m_mesh.MarkDynamic(); + m_mesh.vertices = m_vertices; + m_mesh.uv = m_uvs; + m_mesh.uv2 = m_uv2s; + m_mesh.colors32 = m_vertColors; + } + m_mesh.RecalculateBounds(); + if ((m_textContainer.isDefaultWidth || m_textContainer.isDefaultHeight) && m_textContainer.isAutoFitting) + { + if (m_textContainer.isDefaultWidth) + { + m_textContainer.width = m_preferredWidth + margins.x + margins.z; + } + if (m_textContainer.isDefaultHeight) + { + m_textContainer.height = m_preferredHeight + margins.y + margins.w; + } + if (m_isMaskingEnabled) + { + isMaskUpdateRequired = true; + } + GenerateTextMesh(); + } + } + } + } + } + } + } + + private void DrawUnderlineMesh(Vector3 start, Vector3 end, ref int index) + { + int num = index + 12; + if (num > m_vertices.Length) + { + SetMeshArrays(num / 4 + 16); + GenerateTextMesh(); + } + else + { + start.y = Mathf.Min(start.y, end.y); + end.y = Mathf.Min(start.y, end.y); + float num2 = m_cached_Underline_GlyphInfo.width / 2f * m_fontScale; + if (end.x - start.x < m_cached_Underline_GlyphInfo.width * m_fontScale) + { + num2 = (end.x - start.x) / 2f; + } + float height = m_cached_Underline_GlyphInfo.height; + m_vertices[index] = start + new Vector3(0f, 0f - (height + m_padding) * m_fontScale, 0f); + m_vertices[index + 1] = start + new Vector3(0f, m_padding * m_fontScale, 0f); + m_vertices[index + 2] = m_vertices[index] + new Vector3(num2, 0f, 0f); + m_vertices[index + 3] = start + new Vector3(num2, m_padding * m_fontScale, 0f); + m_vertices[index + 4] = m_vertices[index + 2]; + m_vertices[index + 5] = m_vertices[index + 3]; + m_vertices[index + 6] = end + new Vector3(0f - num2, (0f - (height + m_padding)) * m_fontScale, 0f); + m_vertices[index + 7] = end + new Vector3(0f - num2, m_padding * m_fontScale, 0f); + m_vertices[index + 8] = m_vertices[index + 6]; + m_vertices[index + 9] = m_vertices[index + 7]; + m_vertices[index + 10] = end + new Vector3(0f, (0f - (height + m_padding)) * m_fontScale, 0f); + m_vertices[index + 11] = end + new Vector3(0f, m_padding * m_fontScale, 0f); + Vector2 vector = new Vector2((m_cached_Underline_GlyphInfo.x - m_padding) / m_fontAsset.fontInfo.AtlasWidth, 1f - (m_cached_Underline_GlyphInfo.y + m_padding + m_cached_Underline_GlyphInfo.height) / m_fontAsset.fontInfo.AtlasHeight); + Vector2 vector2 = new Vector2(vector.x, 1f - (m_cached_Underline_GlyphInfo.y - m_padding) / m_fontAsset.fontInfo.AtlasHeight); + Vector2 vector3 = new Vector2((m_cached_Underline_GlyphInfo.x + m_padding + m_cached_Underline_GlyphInfo.width / 2f) / m_fontAsset.fontInfo.AtlasWidth, vector.y); + Vector2 vector4 = new Vector2(vector3.x, vector2.y); + Vector2 vector5 = new Vector2((m_cached_Underline_GlyphInfo.x + m_padding + m_cached_Underline_GlyphInfo.width) / m_fontAsset.fontInfo.AtlasWidth, vector.y); + Vector2 vector6 = new Vector2(vector5.x, vector2.y); + m_uvs[0 + index] = vector; + m_uvs[1 + index] = vector2; + m_uvs[2 + index] = vector3; + m_uvs[3 + index] = vector4; + m_uvs[4 + index] = new Vector2(vector3.x - vector3.x * 0.001f, vector.y); + m_uvs[5 + index] = new Vector2(vector3.x - vector3.x * 0.001f, vector2.y); + m_uvs[6 + index] = new Vector2(vector3.x + vector3.x * 0.001f, vector.y); + m_uvs[7 + index] = new Vector2(vector3.x + vector3.x * 0.001f, vector2.y); + m_uvs[8 + index] = vector3; + m_uvs[9 + index] = vector4; + m_uvs[10 + index] = vector5; + m_uvs[11 + index] = vector6; + float num3 = 0f; + float x = (m_vertices[index + 2].x - start.x) / (end.x - start.x); + float fontScale = m_fontScale; + Vector3 lossyScale = m_transform.lossyScale; + float num4 = fontScale * lossyScale.z; + float scale = num4; + m_uv2s[0 + index] = PackUV(0f, 0f, num4); + m_uv2s[1 + index] = PackUV(0f, 1f, num4); + m_uv2s[2 + index] = PackUV(x, 0f, num4); + m_uv2s[3 + index] = PackUV(x, 1f, num4); + num3 = (m_vertices[index + 4].x - start.x) / (end.x - start.x); + x = (m_vertices[index + 6].x - start.x) / (end.x - start.x); + m_uv2s[4 + index] = PackUV(num3, 0f, scale); + m_uv2s[5 + index] = PackUV(num3, 1f, scale); + m_uv2s[6 + index] = PackUV(x, 0f, scale); + m_uv2s[7 + index] = PackUV(x, 1f, scale); + num3 = (m_vertices[index + 8].x - start.x) / (end.x - start.x); + x = (m_vertices[index + 6].x - start.x) / (end.x - start.x); + m_uv2s[8 + index] = PackUV(num3, 0f, num4); + m_uv2s[9 + index] = PackUV(num3, 1f, num4); + m_uv2s[10 + index] = PackUV(1f, 0f, num4); + m_uv2s[11 + index] = PackUV(1f, 1f, num4); + Color32 color = new Color32(m_fontColor32.r, m_fontColor32.g, m_fontColor32.b, (byte)((int)m_fontColor32.a / 2)); + m_vertColors[0 + index] = color; + m_vertColors[1 + index] = color; + m_vertColors[2 + index] = color; + m_vertColors[3 + index] = color; + m_vertColors[4 + index] = color; + m_vertColors[5 + index] = color; + m_vertColors[6 + index] = color; + m_vertColors[7 + index] = color; + m_vertColors[8 + index] = color; + m_vertColors[9 + index] = color; + m_vertColors[10 + index] = color; + m_vertColors[11 + index] = color; + index += 12; + } + } + + private void UpdateMeshData(TMP_CharacterInfo[] characterInfo, int characterCount, Mesh mesh, Vector3[] vertices, Vector2[] uv0s, Vector2[] uv2s, Color32[] vertexColors, Vector3[] normals, Vector4[] tangents) + { + } + + private void AdjustLineOffset(int startIndex, int endIndex, float offset) + { + Vector3 vector = new Vector3(0f, offset, 0f); + for (int i = startIndex; i <= endIndex; i++) + { + if (m_textInfo.characterInfo[i].isVisible) + { + int vertexIndex = m_textInfo.characterInfo[i].vertexIndex; + m_textInfo.characterInfo[i].bottomLeft -= vector; + m_textInfo.characterInfo[i].topRight -= vector; + m_textInfo.characterInfo[i].bottomLine -= vector.y; + m_textInfo.characterInfo[i].topLine -= vector.y; + m_vertices[0 + vertexIndex] -= vector; + m_vertices[1 + vertexIndex] -= vector; + m_vertices[2 + vertexIndex] -= vector; + m_vertices[3 + vertexIndex] -= vector; + } + } + } + + private void SaveWordWrappingState(ref WordWrapState state, int index, int count) + { + state.previous_WordBreak = index; + state.total_CharacterCount = count; + state.visible_CharacterCount = m_visibleCharacterCount; + state.firstVisibleCharacterIndex = m_firstVisibleCharacterOfLine; + state.lastVisibleCharIndex = m_lastVisibleCharacterOfLine; + state.xAdvance = m_xAdvance; + state.maxAscender = m_maxAscender; + state.maxDescender = m_maxDescender; + state.preferredWidth = m_preferredWidth; + state.preferredHeight = m_preferredHeight; + state.fontScale = m_fontScale; + state.maxFontScale = m_maxFontScale; + state.currentFontSize = m_currentFontSize; + state.lineOffset = m_lineOffset; + state.baselineOffset = m_baselineOffset; + state.fontStyle = m_style; + state.vertexColor = m_htmlColor; + state.meshExtents = m_meshExtents; + state.lineInfo = m_textInfo.lineInfo[m_lineNumber]; + state.textInfo = m_textInfo; + } + + private int RestoreWordWrappingState(ref WordWrapState state) + { + m_textInfo.lineInfo[m_lineNumber] = state.lineInfo; + m_textInfo = ((state.textInfo == null) ? m_textInfo : state.textInfo); + m_currentFontSize = state.currentFontSize; + m_fontScale = state.fontScale; + m_baselineOffset = state.baselineOffset; + m_style = state.fontStyle; + m_htmlColor = state.vertexColor; + m_characterCount = state.total_CharacterCount + 1; + m_visibleCharacterCount = state.visible_CharacterCount; + m_firstVisibleCharacterOfLine = state.firstVisibleCharacterIndex; + m_lastVisibleCharacterOfLine = state.lastVisibleCharIndex; + m_meshExtents = state.meshExtents; + m_xAdvance = state.xAdvance; + m_maxAscender = state.maxAscender; + m_maxDescender = state.maxDescender; + m_preferredWidth = state.preferredWidth; + m_preferredHeight = state.preferredHeight; + m_lineOffset = state.lineOffset; + m_maxFontScale = state.maxFontScale; + return state.previous_WordBreak; + } + + private Vector2 PackUV(float x, float y, float scale) + { + x = x % 5f / 5f; + y = y % 5f / 5f; + return new Vector2(Mathf.Round(x * 4096f) + y, scale); + } + + private void ResizeLineExtents(int size) + { + size = ((size <= 1024) ? Mathf.NextPowerOfTwo(size + 1) : (size + 256)); + TMP_LineInfo[] array = new TMP_LineInfo[size]; + for (int i = 0; i < size; i++) + { + if (i < m_textInfo.lineInfo.Length) + { + array[i] = m_textInfo.lineInfo[i]; + } + else + { + array[i].lineExtents = new Extents(k_InfinityVector, -k_InfinityVector); + array[i].ascender = 0f - k_InfinityVector.x; + array[i].descender = k_InfinityVector.x; + } + } + m_textInfo.lineInfo = array; + } + + private int HexToInt(char hex) + { + switch (hex) + { + case '0': + return 0; + case '1': + return 1; + case '2': + return 2; + case '3': + return 3; + case '4': + return 4; + case '5': + return 5; + case '6': + return 6; + case '7': + return 7; + case '8': + return 8; + case '9': + return 9; + case 'A': + return 10; + case 'B': + return 11; + case 'C': + return 12; + case 'D': + return 13; + case 'E': + return 14; + case 'F': + return 15; + case 'a': + return 10; + case 'b': + return 11; + case 'c': + return 12; + case 'd': + return 13; + case 'e': + return 14; + case 'f': + return 15; + default: + return 15; + } + } + + private Color32 HexCharsToColor(char[] hexChars, int tagCount) + { + switch (tagCount) + { + case 7: + { + byte r4 = (byte)(HexToInt(hexChars[1]) * 16 + HexToInt(hexChars[2])); + byte g4 = (byte)(HexToInt(hexChars[3]) * 16 + HexToInt(hexChars[4])); + byte b4 = (byte)(HexToInt(hexChars[5]) * 16 + HexToInt(hexChars[6])); + return new Color32(r4, g4, b4, byte.MaxValue); + } + case 9: + { + byte r3 = (byte)(HexToInt(hexChars[1]) * 16 + HexToInt(hexChars[2])); + byte g3 = (byte)(HexToInt(hexChars[3]) * 16 + HexToInt(hexChars[4])); + byte b3 = (byte)(HexToInt(hexChars[5]) * 16 + HexToInt(hexChars[6])); + byte a2 = (byte)(HexToInt(hexChars[7]) * 16 + HexToInt(hexChars[8])); + return new Color32(r3, g3, b3, a2); + } + case 13: + { + byte r2 = (byte)(HexToInt(hexChars[7]) * 16 + HexToInt(hexChars[8])); + byte g2 = (byte)(HexToInt(hexChars[9]) * 16 + HexToInt(hexChars[10])); + byte b2 = (byte)(HexToInt(hexChars[11]) * 16 + HexToInt(hexChars[12])); + return new Color32(r2, g2, b2, byte.MaxValue); + } + case 15: + { + byte r = (byte)(HexToInt(hexChars[7]) * 16 + HexToInt(hexChars[8])); + byte g = (byte)(HexToInt(hexChars[9]) * 16 + HexToInt(hexChars[10])); + byte b = (byte)(HexToInt(hexChars[11]) * 16 + HexToInt(hexChars[12])); + byte a = (byte)(HexToInt(hexChars[13]) * 16 + HexToInt(hexChars[14])); + return new Color32(r, g, b, a); + } + default: + return new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); + } + } + + private float ConvertToFloat(char[] chars, int startIndex, int endIndex, int decimalPointIndex) + { + float num = 0f; + float num2 = 1f; + decimalPointIndex = ((decimalPointIndex <= 0) ? (endIndex + 1) : decimalPointIndex); + if (chars[startIndex] == '-') + { + startIndex++; + num2 = -1f; + } + if (chars[startIndex] == '+' || chars[startIndex] == '%') + { + startIndex++; + } + for (int i = startIndex; i < endIndex + 1; i++) + { + switch (decimalPointIndex - i) + { + case 4: + num += (float)((chars[i] - 48) * 1000); + break; + case 3: + num += (float)((chars[i] - 48) * 100); + break; + case 2: + num += (float)((chars[i] - 48) * 10); + break; + case 1: + num += (float)(chars[i] - 48); + break; + case -1: + num += (float)(chars[i] - 48) * 0.1f; + break; + case -2: + num += (float)(chars[i] - 48) * 0.01f; + break; + case -3: + num += (float)(chars[i] - 48) * 0.001f; + break; + } + } + return num * num2; + } + + private bool ValidateHtmlTag(int[] chars, int startIndex, out int endIndex) + { + Array.Clear(m_htmlTag, 0, m_htmlTag.Length); + int num = 0; + int num2 = 0; + int num3 = 0; + int startIndex2 = 0; + int num4 = 0; + int decimalPointIndex = 0; + endIndex = startIndex; + bool flag = false; + int num5 = 1; + for (int i = startIndex; chars[i] != 0; i++) + { + if (num >= m_htmlTag.Length) + { + break; + } + if (chars[i] == 60) + { + break; + } + if (chars[i] == 62) + { + flag = true; + endIndex = i; + m_htmlTag[num] = '\0'; + break; + } + m_htmlTag[num] = (char)chars[i]; + num++; + if (chars[i] == 61) + { + num5 = 0; + } + num2 += chars[i] * num * num5; + num3 += chars[i] * num * (1 - num5); + switch (chars[i]) + { + case 61: + startIndex2 = num; + break; + case 46: + decimalPointIndex = num - 1; + break; + } + } + if (!flag) + { + return false; + } + if (m_htmlTag[0] == '#' && num == 7) + { + m_htmlColor = HexCharsToColor(m_htmlTag, num); + return true; + } + if (m_htmlTag[0] != '#' || num != 9) + { + switch (num2) + { + case 98: + m_style |= FontStyles.Bold; + return true; + case 105: + m_style |= FontStyles.Italic; + return true; + case 117: + m_style |= FontStyles.Underline; + return true; + case 241: + return true; + case 243: + m_style &= (FontStyles)(-2); + return true; + case 257: + m_style &= (FontStyles)(-3); + return true; + case 281: + m_style &= (FontStyles)(-5); + return true; + case 643: + m_currentFontSize *= ((!(m_fontAsset.fontInfo.SubSize > 0f)) ? 1f : m_fontAsset.fontInfo.SubSize); + m_baselineOffset = m_fontAsset.fontInfo.SubscriptOffset; + m_isRecalculateScaleRequired = true; + return true; + case 679: + { + float num6 = ConvertToFloat(m_htmlTag, startIndex2, num - 1, decimalPointIndex); + m_xAdvance = num6 * m_fontScale * m_fontAsset.fontInfo.TabWidth; + return true; + } + case 685: + m_currentFontSize *= ((!(m_fontAsset.fontInfo.SubSize > 0f)) ? 1f : m_fontAsset.fontInfo.SubSize); + m_baselineOffset = m_fontAsset.fontInfo.SuperscriptOffset; + m_isRecalculateScaleRequired = true; + return true; + case 1019: + if (m_overflowMode == TextOverflowModes.Page) + { + m_xAdvance = 0f + m_indent; + m_lineOffset = 0f; + m_pageNumber++; + m_isNewPage = true; + } + return true; + case 1020: + m_currentFontSize /= ((!(m_fontAsset.fontInfo.SubSize > 0f)) ? 1f : m_fontAsset.fontInfo.SubSize); + m_baselineOffset = 0f; + m_isRecalculateScaleRequired = true; + return true; + case 1076: + m_currentFontSize /= ((!(m_fontAsset.fontInfo.SubSize > 0f)) ? 1f : m_fontAsset.fontInfo.SubSize); + m_baselineOffset = 0f; + m_isRecalculateScaleRequired = true; + return true; + case 1095: + { + num4 = num - 1; + float num7 = 0f; + if (m_htmlTag[5] == '%') + { + num7 = ConvertToFloat(m_htmlTag, startIndex2, num4, decimalPointIndex); + m_currentFontSize = m_fontSize * num7 / 100f; + m_isRecalculateScaleRequired = true; + return true; + } + if (m_htmlTag[5] == '+') + { + num7 = ConvertToFloat(m_htmlTag, startIndex2, num4, decimalPointIndex); + m_currentFontSize = m_fontSize + num7; + m_isRecalculateScaleRequired = true; + return true; + } + if (m_htmlTag[5] == '-') + { + num7 = ConvertToFloat(m_htmlTag, startIndex2, num4, decimalPointIndex); + m_currentFontSize = m_fontSize + num7; + m_isRecalculateScaleRequired = true; + return true; + } + num7 = ConvertToFloat(m_htmlTag, startIndex2, num4, decimalPointIndex); + if (num7 == 73493f) + { + return false; + } + m_currentFontSize = num7; + m_isRecalculateScaleRequired = true; + return true; + } + case 1118: + UnityEngine.Debug.Log("Font Tag used."); + return true; + case 1531: + { + float num6 = ConvertToFloat(m_htmlTag, startIndex2, num - 1, decimalPointIndex); + m_xAdvance += num6 * m_fontScale * m_fontAsset.fontInfo.TabWidth; + return true; + } + case 1550: + m_htmlColor.a = (byte)(HexToInt(m_htmlTag[7]) * 16 + HexToInt(m_htmlTag[8])); + return true; + case 1585: + m_currentFontSize = m_fontSize; + m_isRecalculateScaleRequired = true; + return true; + case 1590: + switch (num3) + { + case 4008: + m_lineJustification = TextAlignmentOptions.Left; + return true; + case 5247: + m_lineJustification = TextAlignmentOptions.Right; + return true; + case 6496: + m_lineJustification = TextAlignmentOptions.Center; + return true; + case 10897: + m_lineJustification = TextAlignmentOptions.Justified; + return true; + default: + return false; + } + case 1659: + if (m_htmlTag[6] == '#' && num == 13) + { + m_htmlColor = HexCharsToColor(m_htmlTag, num); + return true; + } + if (m_htmlTag[6] != '#' || num != 15) + { + switch (num3) + { + case 2872: + m_htmlColor = Color.red; + return true; + case 3979: + m_htmlColor = Color.blue; + return true; + case 4956: + m_htmlColor = Color.black; + return true; + case 5128: + m_htmlColor = Color.green; + return true; + case 5247: + m_htmlColor = Color.white; + return true; + case 6373: + m_htmlColor = new Color32(byte.MaxValue, 128, 0, byte.MaxValue); + return true; + case 6632: + m_htmlColor = new Color32(160, 32, 240, byte.MaxValue); + return true; + case 6722: + m_htmlColor = Color.yellow; + return true; + default: + return false; + } + } + m_htmlColor = HexCharsToColor(m_htmlTag, num); + return true; + case 1901: + m_lineHeight = ConvertToFloat(m_htmlTag, startIndex2, num - 1, decimalPointIndex); + return true; + case 2030: + return true; + case 2154: + m_cSpacing = ConvertToFloat(m_htmlTag, startIndex2, num - 1, decimalPointIndex); + return true; + case 2160: + m_lineJustification = m_textAlignment; + return true; + case 2164: + m_monoSpacing = ConvertToFloat(m_htmlTag, startIndex2, num - 1, decimalPointIndex); + return true; + case 2249: + m_htmlColor = m_fontColor32; + return true; + case 2275: + m_indent = ConvertToFloat(m_htmlTag, startIndex2, num - 1, decimalPointIndex); + m_xAdvance = m_indent; + return true; + case 2287: + UnityEngine.Debug.Log("Sprite Tag used."); + return true; + case 2521: + m_lineHeight = 0f; + return true; + case 2844: + m_monoSpacing = 0f; + return true; + case 2824: + m_cSpacing = 0f; + return true; + case 2964: + m_indent = 0f; + return true; + case 2995: + m_style |= FontStyles.UpperCase; + return true; + case 3778: + m_style &= (FontStyles)(-17); + return true; + case 4800: + m_style |= FontStyles.SmallCaps; + return true; + case 5807: + m_currentFontSize = m_fontSize; + m_style &= (FontStyles)(-33); + m_isRecalculateScaleRequired = true; + return true; + default: + return false; + } + } + m_htmlColor = HexCharsToColor(m_htmlTag, num); + return true; + } + + public void UpdateMeshPadding() + { + m_padding = ShaderUtilities.GetPadding(m_renderer.sharedMaterials, m_enableExtraPadding, m_isUsingBold); + havePropertiesChanged = true; + } + + public void ForceMeshUpdate() + { + havePropertiesChanged = true; + OnWillRenderObject(); + } + + public void UpdateFontAsset() + { + LoadFontAsset(); + } + + public TMP_TextInfo GetTextInfo(string text) + { + StringToCharArray(text, ref m_char_buffer); + m_renderMode = TextRenderFlags.DontRender; + GenerateTextMesh(); + m_renderMode = TextRenderFlags.Render; + return textInfo; + } + + public void SetText(string text, float arg0) + { + SetText(text, arg0, 255f, 255f); + } + + public void SetText(string text, float arg0, float arg1) + { + SetText(text, arg0, arg1, 255f); + } + + public void SetText(string text, float arg0, float arg1, float arg2) + { + if (!(text == old_text) || arg0 != old_arg0 || arg1 != old_arg1 || arg2 != old_arg2) + { + if (m_input_CharArray.Length < text.Length) + { + m_input_CharArray = new char[Mathf.NextPowerOfTwo(text.Length + 1)]; + } + old_text = text; + old_arg1 = 255f; + old_arg2 = 255f; + int precision = 0; + int index = 0; + for (int i = 0; i < text.Length; i++) + { + char c = text[i]; + if (c == '{') + { + if (text[i + 2] == ':') + { + precision = text[i + 3] - 48; + } + switch (text[i + 1]) + { + case '0': + old_arg0 = arg0; + AddFloatToCharArray(arg0, ref index, precision); + break; + case '1': + old_arg1 = arg1; + AddFloatToCharArray(arg1, ref index, precision); + break; + case '2': + old_arg2 = arg2; + AddFloatToCharArray(arg2, ref index, precision); + break; + } + i = ((text[i + 2] != ':') ? (i + 2) : (i + 4)); + } + else + { + m_input_CharArray[index] = c; + index++; + } + } + m_input_CharArray[index] = '\0'; + m_charArray_Length = index; + m_inputSource = TextInputSources.SetText; + isInputParsingRequired = true; + havePropertiesChanged = true; + } + } + + public void SetCharArray(char[] charArray) + { + if (charArray != null && charArray.Length != 0) + { + if (m_char_buffer.Length <= charArray.Length) + { + int num = Mathf.NextPowerOfTwo(charArray.Length + 1); + m_char_buffer = new int[num]; + } + int num2 = 0; + for (int i = 0; i < charArray.Length; i++) + { + if (charArray[i] == '\\' && i < charArray.Length - 1) + { + switch (charArray[i + 1]) + { + case 't': + break; + case 'n': + goto IL_0086; + default: + goto IL_009d; + } + m_char_buffer[num2] = 9; + i++; + num2++; + continue; + } + goto IL_009d; + IL_0086: + m_char_buffer[num2] = 10; + i++; + num2++; + continue; + IL_009d: + m_char_buffer[num2] = charArray[i]; + num2++; + } + m_char_buffer[num2] = 0; + m_inputSource = TextInputSources.SetCharArray; + havePropertiesChanged = true; + isInputParsingRequired = true; + } + } + } +} diff --git a/TMPro/TextMeshProFont.cs b/TMPro/TextMeshProFont.cs new file mode 100644 index 00000000..6fe3482e --- /dev/null +++ b/TMPro/TextMeshProFont.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace TMPro +{ + [Serializable] + public class TextMeshProFont : ScriptableObject + { + [SerializeField] + private FaceInfo m_fontInfo; + + public int fontHashCode; + + [SerializeField] + public Texture2D atlas; + + [SerializeField] + public Material material; + + public int materialHashCode; + + [SerializeField] + private List m_glyphInfoList; + + private Dictionary m_characterDictionary; + + private Dictionary m_kerningDictionary; + + [SerializeField] + private KerningTable m_kerningInfo; + + [SerializeField] + private KerningPair m_kerningPair; + + [SerializeField] + private LineBreakingTable m_lineBreakingInfo; + + [SerializeField] + public FontCreationSetting fontCreationSettings; + + [SerializeField] + public bool propertiesChanged; + + private int[] m_characterSet; + + public float NormalStyle; + + public float BoldStyle = 0.75f; + + public byte ItalicStyle = 35; + + public FaceInfo fontInfo => m_fontInfo; + + public Dictionary characterDictionary => m_characterDictionary; + + public Dictionary kerningDictionary => m_kerningDictionary; + + public KerningTable kerningInfo => m_kerningInfo; + + public LineBreakingTable lineBreakingInfo => m_lineBreakingInfo; + + private void OnEnable() + { + if (m_characterDictionary == null) + { + ReadFontDefinition(); + } + } + + private void OnDisable() + { + } + + public void AddFaceInfo(FaceInfo faceInfo) + { + m_fontInfo = faceInfo; + } + + public void AddGlyphInfo(GlyphInfo[] glyphInfo) + { + m_glyphInfoList = new List(); + m_characterSet = new int[m_fontInfo.CharacterCount]; + for (int i = 0; i < m_fontInfo.CharacterCount; i++) + { + GlyphInfo glyphInfo2 = new GlyphInfo(); + glyphInfo2.id = glyphInfo[i].id; + glyphInfo2.x = glyphInfo[i].x; + glyphInfo2.y = glyphInfo[i].y; + glyphInfo2.width = glyphInfo[i].width; + glyphInfo2.height = glyphInfo[i].height; + glyphInfo2.xOffset = glyphInfo[i].xOffset; + glyphInfo2.yOffset = glyphInfo[i].yOffset + m_fontInfo.Padding; + glyphInfo2.xAdvance = glyphInfo[i].xAdvance; + m_glyphInfoList.Add(glyphInfo2); + m_characterSet[i] = glyphInfo2.id; + } + m_glyphInfoList = (from s in m_glyphInfoList + orderby s.id + select s).ToList(); + } + + public void AddKerningInfo(KerningTable kerningTable) + { + m_kerningInfo = kerningTable; + } + + public void ReadFontDefinition() + { + if (m_fontInfo != null) + { + m_characterDictionary = new Dictionary(); + foreach (GlyphInfo glyphInfo2 in m_glyphInfoList) + { + if (!m_characterDictionary.ContainsKey(glyphInfo2.id)) + { + m_characterDictionary.Add(glyphInfo2.id, glyphInfo2); + } + } + GlyphInfo glyphInfo = new GlyphInfo(); + if (m_characterDictionary.ContainsKey(32)) + { + m_characterDictionary[32].width = m_fontInfo.Ascender / 5f; + m_characterDictionary[32].height = m_fontInfo.Ascender - m_fontInfo.Descender; + m_characterDictionary[32].yOffset = m_fontInfo.Ascender; + } + else + { + glyphInfo = new GlyphInfo(); + glyphInfo.id = 32; + glyphInfo.x = 0f; + glyphInfo.y = 0f; + glyphInfo.width = m_fontInfo.Ascender / 5f; + glyphInfo.height = m_fontInfo.Ascender - m_fontInfo.Descender; + glyphInfo.xOffset = 0f; + glyphInfo.yOffset = m_fontInfo.Ascender; + glyphInfo.xAdvance = m_fontInfo.PointSize / 4f; + m_characterDictionary.Add(32, glyphInfo); + } + if (!m_characterDictionary.ContainsKey(10)) + { + glyphInfo = new GlyphInfo(); + glyphInfo.id = 10; + glyphInfo.x = 0f; + glyphInfo.y = 0f; + glyphInfo.width = 0f; + glyphInfo.height = 0f; + glyphInfo.xOffset = 0f; + glyphInfo.yOffset = 0f; + glyphInfo.xAdvance = 0f; + m_characterDictionary.Add(10, glyphInfo); + m_characterDictionary.Add(13, glyphInfo); + } + int num = 10; + if (!m_characterDictionary.ContainsKey(9)) + { + glyphInfo = new GlyphInfo(); + glyphInfo.id = 9; + glyphInfo.x = m_characterDictionary[32].x; + glyphInfo.y = m_characterDictionary[32].y; + glyphInfo.width = m_characterDictionary[32].width * (float)num; + glyphInfo.height = m_characterDictionary[32].height; + glyphInfo.xOffset = m_characterDictionary[32].xOffset; + glyphInfo.yOffset = m_characterDictionary[32].yOffset; + glyphInfo.xAdvance = m_characterDictionary[32].xAdvance * (float)num; + m_characterDictionary.Add(9, glyphInfo); + } + m_fontInfo.TabWidth = m_characterDictionary[32].xAdvance; + m_kerningDictionary = new Dictionary(); + List kerningPairs = m_kerningInfo.kerningPairs; + for (int i = 0; i < kerningPairs.Count; i++) + { + KerningPair kerningPair = kerningPairs[i]; + KerningPairKey kerningPairKey = new KerningPairKey(kerningPair.AscII_Left, kerningPair.AscII_Right); + if (!m_kerningDictionary.ContainsKey(kerningPairKey.key)) + { + m_kerningDictionary.Add(kerningPairKey.key, kerningPair); + } + else + { + Debug.Log("Kerning Key for [" + kerningPairKey.ascii_Left + "] and [" + kerningPairKey.ascii_Right + "] already exists."); + } + } + m_lineBreakingInfo = new LineBreakingTable(); + TextAsset textAsset = Resources.Load("LineBreaking Leading Characters", typeof(TextAsset)) as TextAsset; + if (textAsset != null) + { + m_lineBreakingInfo.leadingCharacters = GetCharacters(textAsset); + } + TextAsset textAsset2 = Resources.Load("LineBreaking Following Characters", typeof(TextAsset)) as TextAsset; + if (textAsset2 != null) + { + m_lineBreakingInfo.followingCharacters = GetCharacters(textAsset2); + } + string name = base.name; + fontHashCode = 0; + for (int j = 0; j < name.Length; j++) + { + fontHashCode = (fontHashCode << 5) - fontHashCode + name[j]; + } + string name2 = material.name; + materialHashCode = 0; + for (int k = 0; k < name2.Length; k++) + { + materialHashCode = (materialHashCode << 5) - materialHashCode + name2[k]; + } + } + } + + private Dictionary GetCharacters(TextAsset file) + { + Dictionary dictionary = new Dictionary(); + string text = file.text; + foreach (char c in text) + { + if (!dictionary.ContainsKey(c)) + { + dictionary.Add(c, c); + } + } + return dictionary; + } + } +} diff --git a/TMPro/TextOverflowModes.cs b/TMPro/TextOverflowModes.cs new file mode 100644 index 00000000..c6005909 --- /dev/null +++ b/TMPro/TextOverflowModes.cs @@ -0,0 +1,12 @@ +namespace TMPro +{ + public enum TextOverflowModes + { + Overflow, + Ellipsis, + Masking, + Truncate, + ScrollRect, + Page + } +} diff --git a/TMPro/TextRenderFlags.cs b/TMPro/TextRenderFlags.cs new file mode 100644 index 00000000..cc7405ae --- /dev/null +++ b/TMPro/TextRenderFlags.cs @@ -0,0 +1,9 @@ +namespace TMPro +{ + public enum TextRenderFlags + { + Render, + DontRender, + GetPreferredSizes + } +} diff --git a/TMPro/TextureMappingOptions.cs b/TMPro/TextureMappingOptions.cs new file mode 100644 index 00000000..3318c4da --- /dev/null +++ b/TMPro/TextureMappingOptions.cs @@ -0,0 +1,10 @@ +namespace TMPro +{ + public enum TextureMappingOptions + { + Character, + Line, + Paragraph, + MatchAspect + } +} diff --git a/TMPro/VertexGradient.cs b/TMPro/VertexGradient.cs new file mode 100644 index 00000000..6428cfb0 --- /dev/null +++ b/TMPro/VertexGradient.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine; + +namespace TMPro +{ + [Serializable] + public struct VertexGradient + { + public Color topLeft; + + public Color topRight; + + public Color bottomLeft; + + public Color bottomRight; + + public VertexGradient(Color color) + { + topLeft = color; + topRight = color; + bottomLeft = color; + bottomRight = color; + } + + public VertexGradient(Color color0, Color color1, Color color2, Color color3) + { + topLeft = color0; + topRight = color1; + bottomLeft = color2; + bottomRight = color3; + } + } +} diff --git a/TMPro/WordWrapState.cs b/TMPro/WordWrapState.cs new file mode 100644 index 00000000..92ab8b64 --- /dev/null +++ b/TMPro/WordWrapState.cs @@ -0,0 +1,53 @@ +using UnityEngine; + +namespace TMPro +{ + public struct WordWrapState + { + public int previous_WordBreak; + + public int total_CharacterCount; + + public int visible_CharacterCount; + + public int visible_SpriteCount; + + public int firstVisibleCharacterIndex; + + public int lastVisibleCharIndex; + + public float maxAscender; + + public float maxDescender; + + public float xAdvance; + + public float preferredWidth; + + public float preferredHeight; + + public float maxFontScale; + + public float previousLineScale; + + public int wordCount; + + public FontStyles fontStyle; + + public float fontScale; + + public float currentFontSize; + + public float baselineOffset; + + public float lineOffset; + + public TMP_TextInfo textInfo; + + public TMP_LineInfo lineInfo; + + public Color32 vertexColor; + + public Extents meshExtents; + } +} diff --git a/TextRefresher.cs b/TextRefresher.cs new file mode 100644 index 00000000..02fd746a --- /dev/null +++ b/TextRefresher.cs @@ -0,0 +1,62 @@ +using Assets.Scripts.Core; +using TMPro; +using UnityEngine; + +public class TextRefresher : MonoBehaviour +{ + private bool isFullscreen; + + private int width; + + private bool language; + + private UILabel label; + + private TextMeshPro textMesh; + + public string English; + + public string Japanese; + + private void UpdateText() + { + if (textMesh != null) + { + textMesh.text = ((!language) ? Japanese : English); + } + else + { + label.text = ((!language) ? Japanese : English); + label.UpdateNGUIText(); + } + } + + private void Start() + { + isFullscreen = Screen.fullScreen; + width = Screen.width; + language = GameSystem.Instance.UseEnglishText; + label = GetComponent(); + textMesh = GetComponent(); + UpdateText(); + } + + private void Update() + { + if (Screen.fullScreen != isFullscreen) + { + isFullscreen = Screen.fullScreen; + UpdateText(); + } + if (width != Screen.width) + { + width = Screen.width; + UpdateText(); + } + if (language != GameSystem.Instance.UseEnglishText) + { + language = GameSystem.Instance.UseEnglishText; + UpdateText(); + } + } +} diff --git a/Triangulate.cs b/Triangulate.cs new file mode 100644 index 00000000..0276c450 --- /dev/null +++ b/Triangulate.cs @@ -0,0 +1,155 @@ +using System.Collections.Generic; +using UnityEngine; + +public class Triangulate +{ + private static float EPSILON = 1E-10f; + + public static float Area(ref List contour) + { + int count = contour.Count; + float num = 0f; + int index = count - 1; + int num2 = 0; + while (num2 < count) + { + float num3 = num; + Vector2 vector = contour[index]; + float x = vector.x; + Vector2 vector2 = contour[num2]; + float num4 = x * vector2.y; + Vector2 vector3 = contour[num2]; + float x2 = vector3.x; + Vector2 vector4 = contour[index]; + num = num3 + (num4 - x2 * vector4.y); + index = num2++; + } + return num * 0.5f; + } + + public static bool InsideTriangle(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Px, float Py) + { + float num = Cx - Bx; + float num2 = Cy - By; + float num3 = Ax - Cx; + float num4 = Ay - Cy; + float num5 = Bx - Ax; + float num6 = By - Ay; + float num7 = Px - Ax; + float num8 = Py - Ay; + float num9 = Px - Bx; + float num10 = Py - By; + float num11 = Px - Cx; + float num12 = Py - Cy; + float num13 = num * num10 - num2 * num9; + float num14 = num5 * num8 - num6 * num7; + float num15 = num3 * num12 - num4 * num11; + return num13 >= 0f && num15 >= 0f && num14 >= 0f; + } + + public static bool Snip(ref List contour, int u, int v, int w, int n, ref List V) + { + Vector2 vector = contour[V[u]]; + float x = vector.x; + Vector2 vector2 = contour[V[u]]; + float y = vector2.y; + Vector2 vector3 = contour[V[v]]; + float x2 = vector3.x; + Vector2 vector4 = contour[V[v]]; + float y2 = vector4.y; + Vector2 vector5 = contour[V[w]]; + float x3 = vector5.x; + Vector2 vector6 = contour[V[w]]; + float y3 = vector6.y; + if (EPSILON > (x2 - x) * (y3 - y) - (y2 - y) * (x3 - x)) + { + return false; + } + for (int i = 0; i < n; i++) + { + if (i != u && i != v && i != w) + { + Vector2 vector7 = contour[V[i]]; + float x4 = vector7.x; + Vector2 vector8 = contour[V[i]]; + float y4 = vector8.y; + if (InsideTriangle(x, y, x2, y2, x3, y3, x4, y4)) + { + return false; + } + } + } + return true; + } + + public static bool Process(ref List contour, ref List result, out bool counterClockwise) + { + counterClockwise = false; + int count = contour.Count; + if (count < 3) + { + return false; + } + List V = new List(); + if (0f < Area(ref contour)) + { + counterClockwise = true; + for (int i = 0; i < count; i++) + { + V.Add(i); + } + } + else + { + for (int j = 0; j < count; j++) + { + V.Add(count - 1 - j); + } + } + int num = count; + int num2 = 2 * num; + int num3 = 0; + int num4 = num - 1; + while (num > 2) + { + if (0 >= num2--) + { + return false; + } + int num6 = num4; + if (num <= num6) + { + num6 = 0; + } + num4 = num6 + 1; + if (num <= num4) + { + num4 = 0; + } + int num7 = num4 + 1; + if (num <= num7) + { + num7 = 0; + } + if (Snip(ref contour, num6, num4, num7, num, ref V)) + { + int item = V[num6]; + int item2 = V[num4]; + int item3 = V[num7]; + result.Add(item3); + result.Add(item2); + result.Add(item); + num3++; + int num8 = num4; + for (int k = num4 + 1; k < num; k++) + { + V[num8] = V[k]; + num8++; + } + num--; + num2 = 2 * num; + } + } + return true; + } +} diff --git a/TweenAction.cs b/TweenAction.cs new file mode 100644 index 00000000..5734ad31 --- /dev/null +++ b/TweenAction.cs @@ -0,0 +1,35 @@ +public enum TweenAction +{ + MOVE_X, + MOVE_Y, + MOVE_Z, + MOVE_LOCAL_X, + MOVE_LOCAL_Y, + MOVE_LOCAL_Z, + MOVE_CURVED, + MOVE_CURVED_LOCAL, + MOVE_SPLINE, + MOVE_SPLINE_LOCAL, + SCALE_X, + SCALE_Y, + SCALE_Z, + ROTATE_X, + ROTATE_Y, + ROTATE_Z, + ROTATE_AROUND, + ALPHA, + ALPHA_VERTEX, + CALLBACK, + MOVE, + MOVE_LOCAL, + ROTATE, + ROTATE_LOCAL, + SCALE, + VALUE3, + GUI_MOVE, + GUI_MOVE_MARGIN, + GUI_SCALE, + GUI_ALPHA, + GUI_ROTATE, + DELAYED_SOUND +} diff --git a/TweenAlpha.cs b/TweenAlpha.cs new file mode 100644 index 00000000..ac0499db --- /dev/null +++ b/TweenAlpha.cs @@ -0,0 +1,134 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Alpha")] +public class TweenAlpha : UITweener +{ + [Range(0f, 1f)] + public float from = 1f; + + [Range(0f, 1f)] + public float to = 1f; + + private bool mCached; + + private UIRect mRect; + + private Material mMat; + + private SpriteRenderer mSr; + + [Obsolete("Use 'value' instead")] + public float alpha + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public float value + { + get + { + if (!mCached) + { + Cache(); + } + if (mRect != null) + { + return mRect.alpha; + } + if (!(mSr != null)) + { + float result; + if (mMat != null) + { + Color color = mMat.color; + result = color.a; + } + else + { + result = 1f; + } + return result; + } + Color color2 = mSr.color; + return color2.a; + } + set + { + if (!mCached) + { + Cache(); + } + if (mRect != null) + { + mRect.alpha = value; + } + else if (mSr != null) + { + Color color = mSr.color; + color.a = value; + mSr.color = color; + } + else if (mMat != null) + { + Color color2 = mMat.color; + color2.a = value; + mMat.color = color2; + } + } + } + + private void Cache() + { + mCached = true; + mRect = GetComponent(); + mSr = GetComponent(); + if (mRect == null && mSr == null) + { + Renderer component = GetComponent(); + if (component != null) + { + mMat = component.material; + } + if (mMat == null) + { + mRect = GetComponentInChildren(); + } + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = Mathf.Lerp(from, to, factor); + } + + public static TweenAlpha Begin(GameObject go, float duration, float alpha) + { + TweenAlpha tweenAlpha = UITweener.Begin(go, duration); + tweenAlpha.from = tweenAlpha.value; + tweenAlpha.to = alpha; + if (duration <= 0f) + { + tweenAlpha.Sample(1f, isFinished: true); + tweenAlpha.enabled = false; + } + return tweenAlpha; + } + + public override void SetStartToCurrentValue() + { + from = value; + } + + public override void SetEndToCurrentValue() + { + to = value; + } +} diff --git a/TweenColor.cs b/TweenColor.cs new file mode 100644 index 00000000..6752ded4 --- /dev/null +++ b/TweenColor.cs @@ -0,0 +1,153 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Color")] +public class TweenColor : UITweener +{ + public Color from = Color.white; + + public Color to = Color.white; + + private bool mCached; + + private UIWidget mWidget; + + private Material mMat; + + private Light mLight; + + private SpriteRenderer mSr; + + [Obsolete("Use 'value' instead")] + public Color color + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public Color value + { + get + { + if (!mCached) + { + Cache(); + } + if (mWidget != null) + { + return mWidget.color; + } + if (mMat != null) + { + return mMat.color; + } + if (mSr != null) + { + return mSr.color; + } + if (mLight != null) + { + return mLight.color; + } + return Color.black; + } + set + { + if (!mCached) + { + Cache(); + } + if (mWidget != null) + { + mWidget.color = value; + } + else if (mMat != null) + { + mMat.color = value; + } + else if (mSr != null) + { + mSr.color = value; + } + else if (mLight != null) + { + mLight.color = value; + mLight.enabled = (value.r + value.g + value.b > 0.01f); + } + } + } + + private void Cache() + { + mCached = true; + mWidget = GetComponent(); + if (!(mWidget != null)) + { + mSr = GetComponent(); + if (!(mSr != null)) + { + Renderer component = GetComponent(); + if (component != null) + { + mMat = component.material; + } + else + { + mLight = GetComponent(); + if (mLight == null) + { + mWidget = GetComponentInChildren(); + } + } + } + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = Color.Lerp(from, to, factor); + } + + public static TweenColor Begin(GameObject go, float duration, Color color) + { + TweenColor tweenColor = UITweener.Begin(go, duration); + tweenColor.from = tweenColor.value; + tweenColor.to = color; + if (duration <= 0f) + { + tweenColor.Sample(1f, isFinished: true); + tweenColor.enabled = false; + } + return tweenColor; + } + + [ContextMenu("Set 'From' to current value")] + public override void SetStartToCurrentValue() + { + from = value; + } + + [ContextMenu("Set 'To' to current value")] + public override void SetEndToCurrentValue() + { + to = value; + } + + [ContextMenu("Assume value of 'From'")] + private void SetCurrentValueToStart() + { + value = from; + } + + [ContextMenu("Assume value of 'To'")] + private void SetCurrentValueToEnd() + { + value = to; + } +} diff --git a/TweenFOV.cs b/TweenFOV.cs new file mode 100644 index 00000000..5a9cd869 --- /dev/null +++ b/TweenFOV.cs @@ -0,0 +1,92 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Field of View")] +[RequireComponent(typeof(Camera))] +public class TweenFOV : UITweener +{ + public float from = 45f; + + public float to = 45f; + + private Camera mCam; + + public Camera cachedCamera + { + get + { + if (mCam == null) + { + mCam = GetComponent(); + } + return mCam; + } + } + + [Obsolete("Use 'value' instead")] + public float fov + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public float value + { + get + { + return cachedCamera.fieldOfView; + } + set + { + cachedCamera.fieldOfView = value; + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = from * (1f - factor) + to * factor; + } + + public static TweenFOV Begin(GameObject go, float duration, float to) + { + TweenFOV tweenFOV = UITweener.Begin(go, duration); + tweenFOV.from = tweenFOV.value; + tweenFOV.to = to; + if (duration <= 0f) + { + tweenFOV.Sample(1f, isFinished: true); + tweenFOV.enabled = false; + } + return tweenFOV; + } + + [ContextMenu("Set 'From' to current value")] + public override void SetStartToCurrentValue() + { + from = value; + } + + [ContextMenu("Set 'To' to current value")] + public override void SetEndToCurrentValue() + { + to = value; + } + + [ContextMenu("Assume value of 'From'")] + private void SetCurrentValueToStart() + { + value = from; + } + + [ContextMenu("Assume value of 'To'")] + private void SetCurrentValueToEnd() + { + value = to; + } +} diff --git a/TweenHeight.cs b/TweenHeight.cs new file mode 100644 index 00000000..007b6f75 --- /dev/null +++ b/TweenHeight.cs @@ -0,0 +1,109 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Height")] +[RequireComponent(typeof(UIWidget))] +public class TweenHeight : UITweener +{ + public int from = 100; + + public int to = 100; + + public bool updateTable; + + private UIWidget mWidget; + + private UITable mTable; + + public UIWidget cachedWidget + { + get + { + if (mWidget == null) + { + mWidget = GetComponent(); + } + return mWidget; + } + } + + [Obsolete("Use 'value' instead")] + public int height + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public int value + { + get + { + return cachedWidget.height; + } + set + { + cachedWidget.height = value; + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = Mathf.RoundToInt((float)from * (1f - factor) + (float)to * factor); + if (updateTable) + { + if (mTable == null) + { + mTable = NGUITools.FindInParents(base.gameObject); + if (mTable == null) + { + updateTable = false; + return; + } + } + mTable.repositionNow = true; + } + } + + public static TweenHeight Begin(UIWidget widget, float duration, int height) + { + TweenHeight tweenHeight = UITweener.Begin(widget.gameObject, duration); + tweenHeight.from = widget.height; + tweenHeight.to = height; + if (duration <= 0f) + { + tweenHeight.Sample(1f, isFinished: true); + tweenHeight.enabled = false; + } + return tweenHeight; + } + + [ContextMenu("Set 'From' to current value")] + public override void SetStartToCurrentValue() + { + from = value; + } + + [ContextMenu("Set 'To' to current value")] + public override void SetEndToCurrentValue() + { + to = value; + } + + [ContextMenu("Assume value of 'From'")] + private void SetCurrentValueToStart() + { + value = from; + } + + [ContextMenu("Assume value of 'To'")] + private void SetCurrentValueToEnd() + { + value = to; + } +} diff --git a/TweenOrthoSize.cs b/TweenOrthoSize.cs new file mode 100644 index 00000000..6864aa2b --- /dev/null +++ b/TweenOrthoSize.cs @@ -0,0 +1,78 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Orthographic Size")] +[RequireComponent(typeof(Camera))] +public class TweenOrthoSize : UITweener +{ + public float from = 1f; + + public float to = 1f; + + private Camera mCam; + + public Camera cachedCamera + { + get + { + if (mCam == null) + { + mCam = GetComponent(); + } + return mCam; + } + } + + [Obsolete("Use 'value' instead")] + public float orthoSize + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public float value + { + get + { + return cachedCamera.orthographicSize; + } + set + { + cachedCamera.orthographicSize = value; + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = from * (1f - factor) + to * factor; + } + + public static TweenOrthoSize Begin(GameObject go, float duration, float to) + { + TweenOrthoSize tweenOrthoSize = UITweener.Begin(go, duration); + tweenOrthoSize.from = tweenOrthoSize.value; + tweenOrthoSize.to = to; + if (duration <= 0f) + { + tweenOrthoSize.Sample(1f, isFinished: true); + tweenOrthoSize.enabled = false; + } + return tweenOrthoSize; + } + + public override void SetStartToCurrentValue() + { + from = value; + } + + public override void SetEndToCurrentValue() + { + to = value; + } +} diff --git a/TweenPosition.cs b/TweenPosition.cs new file mode 100644 index 00000000..eaa10087 --- /dev/null +++ b/TweenPosition.cs @@ -0,0 +1,130 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Position")] +public class TweenPosition : UITweener +{ + public Vector3 from; + + public Vector3 to; + + [HideInInspector] + public bool worldSpace; + + private Transform mTrans; + + private UIRect mRect; + + public Transform cachedTransform + { + get + { + if (mTrans == null) + { + mTrans = base.transform; + } + return mTrans; + } + } + + [Obsolete("Use 'value' instead")] + public Vector3 position + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public Vector3 value + { + get + { + return (!worldSpace) ? cachedTransform.localPosition : cachedTransform.position; + } + set + { + if (mRect == null || !mRect.isAnchored || worldSpace) + { + if (worldSpace) + { + cachedTransform.position = value; + } + else + { + cachedTransform.localPosition = value; + } + } + else + { + value -= cachedTransform.localPosition; + NGUIMath.MoveRect(mRect, value.x, value.y); + } + } + } + + private void Awake() + { + mRect = GetComponent(); + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = from * (1f - factor) + to * factor; + } + + public static TweenPosition Begin(GameObject go, float duration, Vector3 pos) + { + TweenPosition tweenPosition = UITweener.Begin(go, duration); + tweenPosition.from = tweenPosition.value; + tweenPosition.to = pos; + if (duration <= 0f) + { + tweenPosition.Sample(1f, isFinished: true); + tweenPosition.enabled = false; + } + return tweenPosition; + } + + public static TweenPosition Begin(GameObject go, float duration, Vector3 pos, bool worldSpace) + { + TweenPosition tweenPosition = UITweener.Begin(go, duration); + tweenPosition.worldSpace = worldSpace; + tweenPosition.from = tweenPosition.value; + tweenPosition.to = pos; + if (duration <= 0f) + { + tweenPosition.Sample(1f, isFinished: true); + tweenPosition.enabled = false; + } + return tweenPosition; + } + + [ContextMenu("Set 'From' to current value")] + public override void SetStartToCurrentValue() + { + from = value; + } + + [ContextMenu("Set 'To' to current value")] + public override void SetEndToCurrentValue() + { + to = value; + } + + [ContextMenu("Assume value of 'From'")] + private void SetCurrentValueToStart() + { + value = from; + } + + [ContextMenu("Assume value of 'To'")] + private void SetCurrentValueToEnd() + { + value = to; + } +} diff --git a/TweenRotation.cs b/TweenRotation.cs new file mode 100644 index 00000000..e987a5fa --- /dev/null +++ b/TweenRotation.cs @@ -0,0 +1,91 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Rotation")] +public class TweenRotation : UITweener +{ + public Vector3 from; + + public Vector3 to; + + private Transform mTrans; + + public Transform cachedTransform + { + get + { + if (mTrans == null) + { + mTrans = base.transform; + } + return mTrans; + } + } + + [Obsolete("Use 'value' instead")] + public Quaternion rotation + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public Quaternion value + { + get + { + return cachedTransform.localRotation; + } + set + { + cachedTransform.localRotation = value; + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = Quaternion.Euler(new Vector3(Mathf.Lerp(from.x, to.x, factor), Mathf.Lerp(from.y, to.y, factor), Mathf.Lerp(from.z, to.z, factor))); + } + + public static TweenRotation Begin(GameObject go, float duration, Quaternion rot) + { + TweenRotation tweenRotation = UITweener.Begin(go, duration); + tweenRotation.from = tweenRotation.value.eulerAngles; + tweenRotation.to = rot.eulerAngles; + if (duration <= 0f) + { + tweenRotation.Sample(1f, isFinished: true); + tweenRotation.enabled = false; + } + return tweenRotation; + } + + [ContextMenu("Set 'From' to current value")] + public override void SetStartToCurrentValue() + { + from = value.eulerAngles; + } + + [ContextMenu("Set 'To' to current value")] + public override void SetEndToCurrentValue() + { + to = value.eulerAngles; + } + + [ContextMenu("Assume value of 'From'")] + private void SetCurrentValueToStart() + { + value = Quaternion.Euler(from); + } + + [ContextMenu("Assume value of 'To'")] + private void SetCurrentValueToEnd() + { + value = Quaternion.Euler(to); + } +} diff --git a/TweenScale.cs b/TweenScale.cs new file mode 100644 index 00000000..3c75a40d --- /dev/null +++ b/TweenScale.cs @@ -0,0 +1,108 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Scale")] +public class TweenScale : UITweener +{ + public Vector3 from = Vector3.one; + + public Vector3 to = Vector3.one; + + public bool updateTable; + + private Transform mTrans; + + private UITable mTable; + + public Transform cachedTransform + { + get + { + if (mTrans == null) + { + mTrans = base.transform; + } + return mTrans; + } + } + + public Vector3 value + { + get + { + return cachedTransform.localScale; + } + set + { + cachedTransform.localScale = value; + } + } + + [Obsolete("Use 'value' instead")] + public Vector3 scale + { + get + { + return value; + } + set + { + this.value = value; + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = from * (1f - factor) + to * factor; + if (updateTable) + { + if (mTable == null) + { + mTable = NGUITools.FindInParents(base.gameObject); + if (mTable == null) + { + updateTable = false; + return; + } + } + mTable.repositionNow = true; + } + } + + public static TweenScale Begin(GameObject go, float duration, Vector3 scale) + { + TweenScale tweenScale = UITweener.Begin(go, duration); + tweenScale.from = tweenScale.value; + tweenScale.to = scale; + if (duration <= 0f) + { + tweenScale.Sample(1f, isFinished: true); + tweenScale.enabled = false; + } + return tweenScale; + } + + [ContextMenu("Set 'From' to current value")] + public override void SetStartToCurrentValue() + { + from = value; + } + + [ContextMenu("Set 'To' to current value")] + public override void SetEndToCurrentValue() + { + to = value; + } + + [ContextMenu("Assume value of 'From'")] + private void SetCurrentValueToStart() + { + value = from; + } + + [ContextMenu("Assume value of 'To'")] + private void SetCurrentValueToEnd() + { + value = to; + } +} diff --git a/TweenTransform.cs b/TweenTransform.cs new file mode 100644 index 00000000..bb079279 --- /dev/null +++ b/TweenTransform.cs @@ -0,0 +1,67 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Transform")] +public class TweenTransform : UITweener +{ + public Transform from; + + public Transform to; + + public bool parentWhenFinished; + + private Transform mTrans; + + private Vector3 mPos; + + private Quaternion mRot; + + private Vector3 mScale; + + protected override void OnUpdate(float factor, bool isFinished) + { + if (to != null) + { + if (mTrans == null) + { + mTrans = base.transform; + mPos = mTrans.position; + mRot = mTrans.rotation; + mScale = mTrans.localScale; + } + if (from != null) + { + mTrans.position = from.position * (1f - factor) + to.position * factor; + mTrans.localScale = from.localScale * (1f - factor) + to.localScale * factor; + mTrans.rotation = Quaternion.Slerp(from.rotation, to.rotation, factor); + } + else + { + mTrans.position = mPos * (1f - factor) + to.position * factor; + mTrans.localScale = mScale * (1f - factor) + to.localScale * factor; + mTrans.rotation = Quaternion.Slerp(mRot, to.rotation, factor); + } + if (parentWhenFinished && isFinished) + { + mTrans.parent = to; + } + } + } + + public static TweenTransform Begin(GameObject go, float duration, Transform to) + { + return Begin(go, duration, null, to); + } + + public static TweenTransform Begin(GameObject go, float duration, Transform from, Transform to) + { + TweenTransform tweenTransform = UITweener.Begin(go, duration); + tweenTransform.from = from; + tweenTransform.to = to; + if (duration <= 0f) + { + tweenTransform.Sample(1f, isFinished: true); + tweenTransform.enabled = false; + } + return tweenTransform; + } +} diff --git a/TweenVolume.cs b/TweenVolume.cs new file mode 100644 index 00000000..fb3852c0 --- /dev/null +++ b/TweenVolume.cs @@ -0,0 +1,88 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Volume")] +[RequireComponent(typeof(AudioSource))] +public class TweenVolume : UITweener +{ + [Range(0f, 1f)] + public float from = 1f; + + [Range(0f, 1f)] + public float to = 1f; + + private AudioSource mSource; + + public AudioSource audioSource + { + get + { + if (mSource == null) + { + mSource = GetComponent(); + if (mSource == null) + { + mSource = GetComponent(); + if (mSource == null) + { + Debug.LogError("TweenVolume needs an AudioSource to work with", this); + base.enabled = false; + } + } + } + return mSource; + } + } + + [Obsolete("Use 'value' instead")] + public float volume + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public float value + { + get + { + return (!(audioSource != null)) ? 0f : mSource.volume; + } + set + { + if (audioSource != null) + { + mSource.volume = value; + } + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = from * (1f - factor) + to * factor; + mSource.enabled = (mSource.volume > 0.01f); + } + + public static TweenVolume Begin(GameObject go, float duration, float targetVolume) + { + TweenVolume tweenVolume = UITweener.Begin(go, duration); + tweenVolume.from = tweenVolume.value; + tweenVolume.to = targetVolume; + return tweenVolume; + } + + public override void SetStartToCurrentValue() + { + from = value; + } + + public override void SetEndToCurrentValue() + { + to = value; + } +} diff --git a/TweenWidth.cs b/TweenWidth.cs new file mode 100644 index 00000000..408def10 --- /dev/null +++ b/TweenWidth.cs @@ -0,0 +1,109 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Tween/Tween Width")] +[RequireComponent(typeof(UIWidget))] +public class TweenWidth : UITweener +{ + public int from = 100; + + public int to = 100; + + public bool updateTable; + + private UIWidget mWidget; + + private UITable mTable; + + public UIWidget cachedWidget + { + get + { + if (mWidget == null) + { + mWidget = GetComponent(); + } + return mWidget; + } + } + + [Obsolete("Use 'value' instead")] + public int width + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public int value + { + get + { + return cachedWidget.width; + } + set + { + cachedWidget.width = value; + } + } + + protected override void OnUpdate(float factor, bool isFinished) + { + value = Mathf.RoundToInt((float)from * (1f - factor) + (float)to * factor); + if (updateTable) + { + if (mTable == null) + { + mTable = NGUITools.FindInParents(base.gameObject); + if (mTable == null) + { + updateTable = false; + return; + } + } + mTable.repositionNow = true; + } + } + + public static TweenWidth Begin(UIWidget widget, float duration, int width) + { + TweenWidth tweenWidth = UITweener.Begin(widget.gameObject, duration); + tweenWidth.from = widget.width; + tweenWidth.to = width; + if (duration <= 0f) + { + tweenWidth.Sample(1f, isFinished: true); + tweenWidth.enabled = false; + } + return tweenWidth; + } + + [ContextMenu("Set 'From' to current value")] + public override void SetStartToCurrentValue() + { + from = value; + } + + [ContextMenu("Set 'To' to current value")] + public override void SetEndToCurrentValue() + { + to = value; + } + + [ContextMenu("Assume value of 'From'")] + private void SetCurrentValueToStart() + { + value = from; + } + + [ContextMenu("Assume value of 'To'")] + private void SetCurrentValueToEnd() + { + value = to; + } +} diff --git a/TypewriterEffect.cs b/TypewriterEffect.cs new file mode 100644 index 00000000..10a5f371 --- /dev/null +++ b/TypewriterEffect.cs @@ -0,0 +1,226 @@ +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Typewriter Effect")] +[RequireComponent(typeof(UILabel))] +public class TypewriterEffect : MonoBehaviour +{ + private struct FadeEntry + { + public int index; + + public string text; + + public float alpha; + } + + public static TypewriterEffect current; + + public int charsPerSecond = 20; + + public float fadeInTime; + + public float delayOnPeriod; + + public float delayOnNewLine; + + public UIScrollView scrollView; + + public bool keepFullDimensions; + + public List onFinished = new List(); + + private UILabel mLabel; + + private string mFullText = string.Empty; + + private int mCurrentOffset; + + private float mNextChar; + + private bool mReset = true; + + private bool mActive; + + private BetterList mFade = new BetterList(); + + public bool isActive => mActive; + + public void ResetToBeginning() + { + Finish(); + mReset = true; + mActive = true; + mNextChar = 0f; + mCurrentOffset = 0; + } + + public void Finish() + { + if (mActive) + { + mActive = false; + if (!mReset) + { + mCurrentOffset = mFullText.Length; + mFade.Clear(); + mLabel.text = mFullText; + } + if (keepFullDimensions && scrollView != null) + { + scrollView.UpdatePosition(); + } + current = this; + EventDelegate.Execute(onFinished); + current = null; + } + } + + private void OnEnable() + { + mReset = true; + mActive = true; + } + + private void Update() + { + if (mActive) + { + if (mReset) + { + mCurrentOffset = 0; + mReset = false; + mLabel = GetComponent(); + mFullText = mLabel.processedText; + mFade.Clear(); + if (keepFullDimensions && scrollView != null) + { + scrollView.UpdatePosition(); + } + } + while (mCurrentOffset < mFullText.Length && mNextChar <= RealTime.time) + { + int num = mCurrentOffset; + charsPerSecond = Mathf.Max(1, charsPerSecond); + while (NGUIText.ParseSymbol(mFullText, ref mCurrentOffset)) + { + } + mCurrentOffset++; + if (mCurrentOffset >= mFullText.Length) + { + break; + } + float num2 = 1f / (float)charsPerSecond; + char c = (num >= mFullText.Length) ? '\n' : mFullText[num]; + if (c == '\n') + { + num2 += delayOnNewLine; + } + else if (num + 1 == mFullText.Length || mFullText[num + 1] <= ' ') + { + switch (c) + { + case '.': + if (num + 2 < mFullText.Length && mFullText[num + 1] == '.' && mFullText[num + 2] == '.') + { + num2 += delayOnPeriod * 3f; + num += 2; + } + else + { + num2 += delayOnPeriod; + } + break; + case '!': + case '?': + num2 += delayOnPeriod; + break; + } + } + if (mNextChar == 0f) + { + mNextChar = RealTime.time + num2; + } + else + { + mNextChar += num2; + } + if (fadeInTime != 0f) + { + FadeEntry item = default(FadeEntry); + item.index = num; + item.alpha = 0f; + item.text = mFullText.Substring(num, mCurrentOffset - num); + mFade.Add(item); + } + else + { + mLabel.text = ((!keepFullDimensions) ? mFullText.Substring(0, mCurrentOffset) : (mFullText.Substring(0, mCurrentOffset) + "[00]" + mFullText.Substring(mCurrentOffset))); + if (!keepFullDimensions && scrollView != null) + { + scrollView.UpdatePosition(); + } + } + } + if (mFade.size != 0) + { + int num3 = 0; + while (num3 < mFade.size) + { + FadeEntry value = mFade[num3]; + value.alpha += RealTime.deltaTime / fadeInTime; + if (value.alpha < 1f) + { + mFade[num3] = value; + num3++; + } + else + { + mFade.RemoveAt(num3); + } + } + if (mFade.size == 0) + { + if (keepFullDimensions) + { + mLabel.text = mFullText.Substring(0, mCurrentOffset) + "[00]" + mFullText.Substring(mCurrentOffset); + } + else + { + mLabel.text = mFullText.Substring(0, mCurrentOffset); + } + } + else + { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < mFade.size; i++) + { + FadeEntry fadeEntry = mFade[i]; + if (i == 0) + { + stringBuilder.Append(mFullText.Substring(0, fadeEntry.index)); + } + stringBuilder.Append('['); + stringBuilder.Append(NGUIText.EncodeAlpha(fadeEntry.alpha)); + stringBuilder.Append(']'); + stringBuilder.Append(fadeEntry.text); + } + if (keepFullDimensions) + { + stringBuilder.Append("[00]"); + stringBuilder.Append(mFullText.Substring(mCurrentOffset)); + } + mLabel.text = stringBuilder.ToString(); + } + } + else if (mCurrentOffset == mFullText.Length) + { + current = this; + EventDelegate.Execute(onFinished); + current = null; + mActive = false; + } + } + } +} diff --git a/UI2DSprite.cs b/UI2DSprite.cs new file mode 100644 index 00000000..ba502dfa --- /dev/null +++ b/UI2DSprite.cs @@ -0,0 +1,332 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Unity2D Sprite")] +[ExecuteInEditMode] +public class UI2DSprite : UIBasicSprite +{ + [HideInInspector] + [SerializeField] + private Sprite mSprite; + + [HideInInspector] + [SerializeField] + private Material mMat; + + [HideInInspector] + [SerializeField] + private Shader mShader; + + [HideInInspector] + [SerializeField] + private Vector4 mBorder = Vector4.zero; + + [HideInInspector] + [SerializeField] + private bool mFixedAspect; + + [HideInInspector] + [SerializeField] + private float mPixelSize = 1f; + + public Sprite nextSprite; + + [NonSerialized] + private int mPMA = -1; + + public Sprite sprite2D + { + get + { + return mSprite; + } + set + { + if (mSprite != value) + { + RemoveFromPanel(); + mSprite = value; + nextSprite = null; + CreatePanel(); + } + } + } + + public override Material material + { + get + { + return mMat; + } + set + { + if (mMat != value) + { + RemoveFromPanel(); + mMat = value; + mPMA = -1; + MarkAsChanged(); + } + } + } + + public override Shader shader + { + get + { + if (mMat != null) + { + return mMat.shader; + } + if (mShader == null) + { + mShader = Shader.Find("Unlit/Transparent Colored"); + } + return mShader; + } + set + { + if (mShader != value) + { + RemoveFromPanel(); + mShader = value; + if (mMat == null) + { + mPMA = -1; + MarkAsChanged(); + } + } + } + } + + public override Texture mainTexture + { + get + { + if (mSprite != null) + { + return mSprite.texture; + } + if (mMat != null) + { + return mMat.mainTexture; + } + return null; + } + } + + public override bool premultipliedAlpha + { + get + { + if (mPMA == -1) + { + Shader shader = this.shader; + mPMA = ((shader != null && shader.name.Contains("Premultiplied")) ? 1 : 0); + } + return mPMA == 1; + } + } + + public override float pixelSize => mPixelSize; + + public override Vector4 drawingDimensions + { + get + { + Vector2 pivotOffset = base.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float num3 = num + (float)mWidth; + float num4 = num2 + (float)mHeight; + if (mSprite != null && mType != Type.Tiled) + { + int num5 = Mathf.RoundToInt(mSprite.rect.width); + int num6 = Mathf.RoundToInt(mSprite.rect.height); + Vector2 textureRectOffset = mSprite.textureRectOffset; + int num7 = Mathf.RoundToInt(textureRectOffset.x); + Vector2 textureRectOffset2 = mSprite.textureRectOffset; + int num8 = Mathf.RoundToInt(textureRectOffset2.y); + float num9 = mSprite.rect.width - mSprite.textureRect.width; + Vector2 textureRectOffset3 = mSprite.textureRectOffset; + int num10 = Mathf.RoundToInt(num9 - textureRectOffset3.x); + float num11 = mSprite.rect.height - mSprite.textureRect.height; + Vector2 textureRectOffset4 = mSprite.textureRectOffset; + int num12 = Mathf.RoundToInt(num11 - textureRectOffset4.y); + float num13 = 1f; + float num14 = 1f; + if (num5 > 0 && num6 > 0 && (mType == Type.Simple || mType == Type.Filled)) + { + if ((num5 & 1) != 0) + { + num10++; + } + if ((num6 & 1) != 0) + { + num12++; + } + num13 = 1f / (float)num5 * (float)mWidth; + num14 = 1f / (float)num6 * (float)mHeight; + } + if (mFlip == Flip.Horizontally || mFlip == Flip.Both) + { + num += (float)num10 * num13; + num3 -= (float)num7 * num13; + } + else + { + num += (float)num7 * num13; + num3 -= (float)num10 * num13; + } + if (mFlip == Flip.Vertically || mFlip == Flip.Both) + { + num2 += (float)num12 * num14; + num4 -= (float)num8 * num14; + } + else + { + num2 += (float)num8 * num14; + num4 -= (float)num12 * num14; + } + } + float num15; + float num16; + if (mFixedAspect) + { + num15 = 0f; + num16 = 0f; + } + else + { + Vector4 vector = border * pixelSize; + num15 = vector.x + vector.z; + num16 = vector.y + vector.w; + } + float x = Mathf.Lerp(num, num3 - num15, mDrawRegion.x); + float y = Mathf.Lerp(num2, num4 - num16, mDrawRegion.y); + float z = Mathf.Lerp(num + num15, num3, mDrawRegion.z); + float w = Mathf.Lerp(num2 + num16, num4, mDrawRegion.w); + return new Vector4(x, y, z, w); + } + } + + public override Vector4 border + { + get + { + return mBorder; + } + set + { + if (mBorder != value) + { + mBorder = value; + MarkAsChanged(); + } + } + } + + protected override void OnUpdate() + { + if (nextSprite != null) + { + if (nextSprite != mSprite) + { + sprite2D = nextSprite; + } + nextSprite = null; + } + base.OnUpdate(); + if (mFixedAspect) + { + Texture mainTexture = this.mainTexture; + if (mainTexture != null) + { + int num = Mathf.RoundToInt(mSprite.rect.width); + int num2 = Mathf.RoundToInt(mSprite.rect.height); + Vector2 textureRectOffset = mSprite.textureRectOffset; + int num3 = Mathf.RoundToInt(textureRectOffset.x); + Vector2 textureRectOffset2 = mSprite.textureRectOffset; + int num4 = Mathf.RoundToInt(textureRectOffset2.y); + float num5 = mSprite.rect.width - mSprite.textureRect.width; + Vector2 textureRectOffset3 = mSprite.textureRectOffset; + int num6 = Mathf.RoundToInt(num5 - textureRectOffset3.x); + float num7 = mSprite.rect.height - mSprite.textureRect.height; + Vector2 textureRectOffset4 = mSprite.textureRectOffset; + int num8 = Mathf.RoundToInt(num7 - textureRectOffset4.y); + num += num3 + num6; + num2 += num8 + num4; + float num9 = (float)mWidth; + float num10 = (float)mHeight; + float num11 = num9 / num10; + float num12 = (float)num / (float)num2; + if (num12 < num11) + { + float num13 = (num9 - num10 * num12) / num9 * 0.5f; + base.drawRegion = new Vector4(num13, 0f, 1f - num13, 1f); + } + else + { + float num14 = (num10 - num9 / num12) / num10 * 0.5f; + base.drawRegion = new Vector4(0f, num14, 1f, 1f - num14); + } + } + } + } + + public override void MakePixelPerfect() + { + base.MakePixelPerfect(); + if (mType != Type.Tiled) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null) && (mType == Type.Simple || mType == Type.Filled || !base.hasBorder) && mainTexture != null) + { + Rect rect = mSprite.rect; + int num = Mathf.RoundToInt(rect.width); + int num2 = Mathf.RoundToInt(rect.height); + if ((num & 1) == 1) + { + num++; + } + if ((num2 & 1) == 1) + { + num2++; + } + base.width = num; + base.height = num2; + } + } + } + + public override void OnFill(BetterList verts, BetterList uvs, BetterList cols) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null)) + { + Rect rect = (!(mSprite != null)) ? new Rect(0f, 0f, (float)mainTexture.width, (float)mainTexture.height) : mSprite.textureRect; + Rect inner = rect; + Vector4 border = this.border; + inner.xMin += border.x; + inner.yMin += border.y; + inner.xMax -= border.z; + inner.yMax -= border.w; + float num = 1f / (float)mainTexture.width; + float num2 = 1f / (float)mainTexture.height; + rect.xMin *= num; + rect.xMax *= num; + rect.yMin *= num2; + rect.yMax *= num2; + inner.xMin *= num; + inner.xMax *= num; + inner.yMin *= num2; + inner.yMax *= num2; + int size = verts.size; + Fill(verts, uvs, cols, rect, inner); + if (onPostFill != null) + { + onPostFill(this, size, verts, uvs, cols); + } + } + } +} diff --git a/UI2DSpriteAnimation.cs b/UI2DSpriteAnimation.cs new file mode 100644 index 00000000..1fb98f82 --- /dev/null +++ b/UI2DSpriteAnimation.cs @@ -0,0 +1,121 @@ +using UnityEngine; + +public class UI2DSpriteAnimation : MonoBehaviour +{ + [SerializeField] + protected int framerate = 20; + + public bool ignoreTimeScale = true; + + public bool loop = true; + + public Sprite[] frames; + + private SpriteRenderer mUnitySprite; + + private UI2DSprite mNguiSprite; + + private int mIndex; + + private float mUpdate; + + public bool isPlaying => base.enabled; + + public int framesPerSecond + { + get + { + return framerate; + } + set + { + framerate = value; + } + } + + public void Play() + { + if (frames != null && frames.Length > 0) + { + if (!base.enabled && !loop) + { + int num = (framerate <= 0) ? (mIndex - 1) : (mIndex + 1); + if (num < 0 || num >= frames.Length) + { + mIndex = ((framerate < 0) ? (frames.Length - 1) : 0); + } + } + base.enabled = true; + UpdateSprite(); + } + } + + public void Pause() + { + base.enabled = false; + } + + public void ResetToBeginning() + { + mIndex = ((framerate < 0) ? (frames.Length - 1) : 0); + UpdateSprite(); + } + + private void Start() + { + Play(); + } + + private void Update() + { + if (frames == null || frames.Length == 0) + { + base.enabled = false; + } + else if (framerate != 0) + { + float num = (!ignoreTimeScale) ? Time.time : RealTime.time; + if (mUpdate < num) + { + mUpdate = num; + int num2 = (framerate <= 0) ? (mIndex - 1) : (mIndex + 1); + if (!loop && (num2 < 0 || num2 >= frames.Length)) + { + base.enabled = false; + } + else + { + mIndex = NGUIMath.RepeatIndex(num2, frames.Length); + UpdateSprite(); + } + } + } + } + + private void UpdateSprite() + { + if (mUnitySprite == null && mNguiSprite == null) + { + mUnitySprite = GetComponent(); + mNguiSprite = GetComponent(); + if (mUnitySprite == null && mNguiSprite == null) + { + base.enabled = false; + return; + } + } + float num = (!ignoreTimeScale) ? Time.time : RealTime.time; + if (framerate != 0) + { + mUpdate = num + Mathf.Abs(1f / (float)framerate); + } + if (mUnitySprite != null) + { + mUnitySprite.sprite = frames[mIndex]; + } + else if (mNguiSprite != null) + { + mNguiSprite.nextSprite = frames[mIndex]; + } + } +} diff --git a/UIAnchor.cs b/UIAnchor.cs new file mode 100644 index 00000000..f02e6141 --- /dev/null +++ b/UIAnchor.cs @@ -0,0 +1,225 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Anchor")] +[ExecuteInEditMode] +public class UIAnchor : MonoBehaviour +{ + public enum Side + { + BottomLeft, + Left, + TopLeft, + Top, + TopRight, + Right, + BottomRight, + Bottom, + Center + } + + public Camera uiCamera; + + public GameObject container; + + public Side side = Side.Center; + + public bool runOnlyOnce = true; + + public Vector2 relativeOffset = Vector2.zero; + + public Vector2 pixelOffset = Vector2.zero; + + [HideInInspector] + [SerializeField] + private UIWidget widgetContainer; + + private Transform mTrans; + + private Animation mAnim; + + private Rect mRect = default(Rect); + + private UIRoot mRoot; + + private bool mStarted; + + private void Awake() + { + mTrans = base.transform; + mAnim = GetComponent(); + UICamera.onScreenResize = (UICamera.OnScreenResize)Delegate.Combine(UICamera.onScreenResize, new UICamera.OnScreenResize(ScreenSizeChanged)); + } + + private void OnDestroy() + { + UICamera.onScreenResize = (UICamera.OnScreenResize)Delegate.Remove(UICamera.onScreenResize, new UICamera.OnScreenResize(ScreenSizeChanged)); + } + + private void ScreenSizeChanged() + { + if (mStarted && runOnlyOnce) + { + Update(); + } + } + + private void Start() + { + if (container == null && widgetContainer != null) + { + container = widgetContainer.gameObject; + widgetContainer = null; + } + mRoot = NGUITools.FindInParents(base.gameObject); + if (uiCamera == null) + { + uiCamera = NGUITools.FindCameraForLayer(base.gameObject.layer); + } + Update(); + mStarted = true; + } + + private void Update() + { + if (!(mAnim != null) || !mAnim.enabled || !mAnim.isPlaying) + { + bool flag = false; + UIWidget uIWidget = (!(container == null)) ? container.GetComponent() : null; + UIPanel uIPanel = (!(container == null) || !(uIWidget == null)) ? container.GetComponent() : null; + if (uIWidget != null) + { + Bounds bounds = uIWidget.CalculateBounds(container.transform.parent); + ref Rect reference = ref mRect; + Vector3 min = bounds.min; + reference.x = min.x; + ref Rect reference2 = ref mRect; + Vector3 min2 = bounds.min; + reference2.y = min2.y; + ref Rect reference3 = ref mRect; + Vector3 size = bounds.size; + reference3.width = size.x; + ref Rect reference4 = ref mRect; + Vector3 size2 = bounds.size; + reference4.height = size2.y; + } + else if (uIPanel != null) + { + if (uIPanel.clipping == UIDrawCall.Clipping.None) + { + float num = (!(mRoot != null)) ? 0.5f : ((float)mRoot.activeHeight / (float)Screen.height * 0.5f); + mRect.xMin = (float)(-Screen.width) * num; + mRect.yMin = (float)(-Screen.height) * num; + mRect.xMax = 0f - mRect.xMin; + mRect.yMax = 0f - mRect.yMin; + } + else + { + Vector4 finalClipRegion = uIPanel.finalClipRegion; + mRect.x = finalClipRegion.x - finalClipRegion.z * 0.5f; + mRect.y = finalClipRegion.y - finalClipRegion.w * 0.5f; + mRect.width = finalClipRegion.z; + mRect.height = finalClipRegion.w; + } + } + else if (container != null) + { + Transform parent = container.transform.parent; + Bounds bounds2 = (!(parent != null)) ? NGUIMath.CalculateRelativeWidgetBounds(container.transform) : NGUIMath.CalculateRelativeWidgetBounds(parent, container.transform); + ref Rect reference5 = ref mRect; + Vector3 min3 = bounds2.min; + reference5.x = min3.x; + ref Rect reference6 = ref mRect; + Vector3 min4 = bounds2.min; + reference6.y = min4.y; + ref Rect reference7 = ref mRect; + Vector3 size3 = bounds2.size; + reference7.width = size3.x; + ref Rect reference8 = ref mRect; + Vector3 size4 = bounds2.size; + reference8.height = size4.y; + } + else + { + if (!(uiCamera != null)) + { + return; + } + flag = true; + mRect = uiCamera.pixelRect; + } + float x = (mRect.xMin + mRect.xMax) * 0.5f; + float y = (mRect.yMin + mRect.yMax) * 0.5f; + Vector3 vector = new Vector3(x, y, 0f); + if (side != Side.Center) + { + if (side == Side.Right || side == Side.TopRight || side == Side.BottomRight) + { + vector.x = mRect.xMax; + } + else if (side == Side.Top || side == Side.Center || side == Side.Bottom) + { + vector.x = x; + } + else + { + vector.x = mRect.xMin; + } + if (side == Side.Top || side == Side.TopRight || side == Side.TopLeft) + { + vector.y = mRect.yMax; + } + else if (side == Side.Left || side == Side.Center || side == Side.Right) + { + vector.y = y; + } + else + { + vector.y = mRect.yMin; + } + } + float width = mRect.width; + float height = mRect.height; + vector.x += pixelOffset.x + relativeOffset.x * width; + vector.y += pixelOffset.y + relativeOffset.y * height; + if (flag) + { + if (uiCamera.orthographic) + { + vector.x = Mathf.Round(vector.x); + vector.y = Mathf.Round(vector.y); + } + Vector3 vector2 = uiCamera.WorldToScreenPoint(mTrans.position); + vector.z = vector2.z; + vector = uiCamera.ScreenToWorldPoint(vector); + } + else + { + vector.x = Mathf.Round(vector.x); + vector.y = Mathf.Round(vector.y); + if (uIPanel != null) + { + vector = uIPanel.cachedTransform.TransformPoint(vector); + } + else if (container != null) + { + Transform parent2 = container.transform.parent; + if (parent2 != null) + { + vector = parent2.TransformPoint(vector); + } + } + Vector3 position = mTrans.position; + vector.z = position.z; + } + if (mTrans.position != vector) + { + mTrans.position = vector; + } + if (runOnlyOnce && Application.isPlaying) + { + base.enabled = false; + } + } + } +} diff --git a/UIAtlas.cs b/UIAtlas.cs new file mode 100644 index 00000000..cfe84838 --- /dev/null +++ b/UIAtlas.cs @@ -0,0 +1,440 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Atlas")] +public class UIAtlas : MonoBehaviour +{ + [Serializable] + private class Sprite + { + public string name = "Unity Bug"; + + public Rect outer = new Rect(0f, 0f, 1f, 1f); + + public Rect inner = new Rect(0f, 0f, 1f, 1f); + + public bool rotated; + + public float paddingLeft; + + public float paddingRight; + + public float paddingTop; + + public float paddingBottom; + + public bool hasPadding => paddingLeft != 0f || paddingRight != 0f || paddingTop != 0f || paddingBottom != 0f; + } + + private enum Coordinates + { + Pixels, + TexCoords + } + + [HideInInspector] + [SerializeField] + private Material material; + + [HideInInspector] + [SerializeField] + private List mSprites = new List(); + + [HideInInspector] + [SerializeField] + private float mPixelSize = 1f; + + [HideInInspector] + [SerializeField] + private UIAtlas mReplacement; + + [HideInInspector] + [SerializeField] + private Coordinates mCoordinates; + + [HideInInspector] + [SerializeField] + private List sprites = new List(); + + private int mPMA = -1; + + private Dictionary mSpriteIndices = new Dictionary(); + + public Material spriteMaterial + { + get + { + return (!(mReplacement != null)) ? material : mReplacement.spriteMaterial; + } + set + { + if (mReplacement != null) + { + mReplacement.spriteMaterial = value; + } + else if (material == null) + { + mPMA = 0; + material = value; + } + else + { + MarkAsChanged(); + mPMA = -1; + material = value; + MarkAsChanged(); + } + } + } + + public bool premultipliedAlpha + { + get + { + if (mReplacement != null) + { + return mReplacement.premultipliedAlpha; + } + if (mPMA == -1) + { + Material spriteMaterial = this.spriteMaterial; + mPMA = ((spriteMaterial != null && spriteMaterial.shader != null && spriteMaterial.shader.name.Contains("Premultiplied")) ? 1 : 0); + } + return mPMA == 1; + } + } + + public List spriteList + { + get + { + if (mReplacement != null) + { + return mReplacement.spriteList; + } + if (mSprites.Count == 0) + { + Upgrade(); + } + return mSprites; + } + set + { + if (mReplacement != null) + { + mReplacement.spriteList = value; + } + else + { + mSprites = value; + } + } + } + + public Texture texture => (mReplacement != null) ? mReplacement.texture : ((!(material != null)) ? null : material.mainTexture); + + public float pixelSize + { + get + { + return (!(mReplacement != null)) ? mPixelSize : mReplacement.pixelSize; + } + set + { + if (mReplacement != null) + { + mReplacement.pixelSize = value; + } + else + { + float num = Mathf.Clamp(value, 0.25f, 4f); + if (mPixelSize != num) + { + mPixelSize = num; + MarkAsChanged(); + } + } + } + } + + public UIAtlas replacement + { + get + { + return mReplacement; + } + set + { + UIAtlas uIAtlas = value; + if (uIAtlas == this) + { + uIAtlas = null; + } + if (mReplacement != uIAtlas) + { + if (uIAtlas != null && uIAtlas.replacement == this) + { + uIAtlas.replacement = null; + } + if (mReplacement != null) + { + MarkAsChanged(); + } + mReplacement = uIAtlas; + if (uIAtlas != null) + { + material = null; + } + MarkAsChanged(); + } + } + } + + public UISpriteData GetSprite(string name) + { + if (mReplacement != null) + { + return mReplacement.GetSprite(name); + } + if (!string.IsNullOrEmpty(name)) + { + if (mSprites.Count == 0) + { + Upgrade(); + } + if (mSprites.Count == 0) + { + return null; + } + if (mSpriteIndices.Count != mSprites.Count) + { + MarkSpriteListAsChanged(); + } + if (mSpriteIndices.TryGetValue(name, out int value)) + { + if (value > -1 && value < mSprites.Count) + { + return mSprites[value]; + } + MarkSpriteListAsChanged(); + return (!mSpriteIndices.TryGetValue(name, out value)) ? null : mSprites[value]; + } + int i = 0; + for (int count = mSprites.Count; i < count; i++) + { + UISpriteData uISpriteData = mSprites[i]; + if (!string.IsNullOrEmpty(uISpriteData.name) && name == uISpriteData.name) + { + MarkSpriteListAsChanged(); + return uISpriteData; + } + } + } + return null; + } + + public void MarkSpriteListAsChanged() + { + mSpriteIndices.Clear(); + int i = 0; + for (int count = mSprites.Count; i < count; i++) + { + mSpriteIndices[mSprites[i].name] = i; + } + } + + public void SortAlphabetically() + { + mSprites.Sort((UISpriteData s1, UISpriteData s2) => s1.name.CompareTo(s2.name)); + } + + public BetterList GetListOfSprites() + { + if (mReplacement != null) + { + return mReplacement.GetListOfSprites(); + } + if (mSprites.Count == 0) + { + Upgrade(); + } + BetterList betterList = new BetterList(); + int i = 0; + for (int count = mSprites.Count; i < count; i++) + { + UISpriteData uISpriteData = mSprites[i]; + if (uISpriteData != null && !string.IsNullOrEmpty(uISpriteData.name)) + { + betterList.Add(uISpriteData.name); + } + } + return betterList; + } + + public BetterList GetListOfSprites(string match) + { + if ((bool)mReplacement) + { + return mReplacement.GetListOfSprites(match); + } + if (string.IsNullOrEmpty(match)) + { + return GetListOfSprites(); + } + if (mSprites.Count == 0) + { + Upgrade(); + } + BetterList betterList = new BetterList(); + int i = 0; + for (int count = mSprites.Count; i < count; i++) + { + UISpriteData uISpriteData = mSprites[i]; + if (uISpriteData != null && !string.IsNullOrEmpty(uISpriteData.name) && string.Equals(match, uISpriteData.name, StringComparison.OrdinalIgnoreCase)) + { + betterList.Add(uISpriteData.name); + return betterList; + } + } + string[] array = match.Split(new char[1] + { + ' ' + }, StringSplitOptions.RemoveEmptyEntries); + for (int j = 0; j < array.Length; j++) + { + array[j] = array[j].ToLower(); + } + int k = 0; + for (int count2 = mSprites.Count; k < count2; k++) + { + UISpriteData uISpriteData2 = mSprites[k]; + if (uISpriteData2 != null && !string.IsNullOrEmpty(uISpriteData2.name)) + { + string text = uISpriteData2.name.ToLower(); + int num = 0; + for (int l = 0; l < array.Length; l++) + { + if (text.Contains(array[l])) + { + num++; + } + } + if (num == array.Length) + { + betterList.Add(uISpriteData2.name); + } + } + } + return betterList; + } + + private bool References(UIAtlas atlas) + { + if (atlas == null) + { + return false; + } + if (atlas == this) + { + return true; + } + return mReplacement != null && mReplacement.References(atlas); + } + + public static bool CheckIfRelated(UIAtlas a, UIAtlas b) + { + if (a == null || b == null) + { + return false; + } + return a == b || a.References(b) || b.References(a); + } + + public void MarkAsChanged() + { + if (mReplacement != null) + { + mReplacement.MarkAsChanged(); + } + UISprite[] array = NGUITools.FindActive(); + int i = 0; + for (int num = array.Length; i < num; i++) + { + UISprite uISprite = array[i]; + if (CheckIfRelated(this, uISprite.atlas)) + { + UIAtlas atlas = uISprite.atlas; + uISprite.atlas = null; + uISprite.atlas = atlas; + } + } + UIFont[] array2 = Resources.FindObjectsOfTypeAll(typeof(UIFont)) as UIFont[]; + int j = 0; + for (int num2 = array2.Length; j < num2; j++) + { + UIFont uIFont = array2[j]; + if (CheckIfRelated(this, uIFont.atlas)) + { + UIAtlas atlas2 = uIFont.atlas; + uIFont.atlas = null; + uIFont.atlas = atlas2; + } + } + UILabel[] array3 = NGUITools.FindActive(); + int k = 0; + for (int num3 = array3.Length; k < num3; k++) + { + UILabel uILabel = array3[k]; + if (uILabel.bitmapFont != null && CheckIfRelated(this, uILabel.bitmapFont.atlas)) + { + UIFont bitmapFont = uILabel.bitmapFont; + uILabel.bitmapFont = null; + uILabel.bitmapFont = bitmapFont; + } + } + } + + private bool Upgrade() + { + if ((bool)mReplacement) + { + return mReplacement.Upgrade(); + } + if (mSprites.Count == 0 && sprites.Count > 0 && (bool)material) + { + Texture mainTexture = material.mainTexture; + int width = (!(mainTexture != null)) ? 512 : mainTexture.width; + int height = (!(mainTexture != null)) ? 512 : mainTexture.height; + for (int i = 0; i < sprites.Count; i++) + { + Sprite sprite = sprites[i]; + Rect outer = sprite.outer; + Rect inner = sprite.inner; + if (mCoordinates == Coordinates.TexCoords) + { + NGUIMath.ConvertToPixels(outer, width, height, round: true); + NGUIMath.ConvertToPixels(inner, width, height, round: true); + } + UISpriteData uISpriteData = new UISpriteData(); + uISpriteData.name = sprite.name; + uISpriteData.x = Mathf.RoundToInt(outer.xMin); + uISpriteData.y = Mathf.RoundToInt(outer.yMin); + uISpriteData.width = Mathf.RoundToInt(outer.width); + uISpriteData.height = Mathf.RoundToInt(outer.height); + uISpriteData.paddingLeft = Mathf.RoundToInt(sprite.paddingLeft * outer.width); + uISpriteData.paddingRight = Mathf.RoundToInt(sprite.paddingRight * outer.width); + uISpriteData.paddingBottom = Mathf.RoundToInt(sprite.paddingBottom * outer.height); + uISpriteData.paddingTop = Mathf.RoundToInt(sprite.paddingTop * outer.height); + uISpriteData.borderLeft = Mathf.RoundToInt(inner.xMin - outer.xMin); + uISpriteData.borderRight = Mathf.RoundToInt(outer.xMax - inner.xMax); + uISpriteData.borderBottom = Mathf.RoundToInt(outer.yMax - inner.yMax); + uISpriteData.borderTop = Mathf.RoundToInt(inner.yMin - outer.yMin); + mSprites.Add(uISpriteData); + } + sprites.Clear(); + return true; + } + return false; + } +} diff --git a/UIBasicSprite.cs b/UIBasicSprite.cs new file mode 100644 index 00000000..ab90f84a --- /dev/null +++ b/UIBasicSprite.cs @@ -0,0 +1,906 @@ +using System; +using UnityEngine; + +public abstract class UIBasicSprite : UIWidget +{ + public enum Type + { + Simple, + Sliced, + Tiled, + Filled, + Advanced + } + + public enum FillDirection + { + Horizontal, + Vertical, + Radial90, + Radial180, + Radial360 + } + + public enum AdvancedType + { + Invisible, + Sliced, + Tiled + } + + public enum Flip + { + Nothing, + Horizontally, + Vertically, + Both + } + + [HideInInspector] + [SerializeField] + protected Type mType; + + [HideInInspector] + [SerializeField] + protected FillDirection mFillDirection = FillDirection.Radial360; + + [HideInInspector] + [Range(0f, 1f)] + [SerializeField] + protected float mFillAmount = 1f; + + [HideInInspector] + [SerializeField] + protected bool mInvert; + + [HideInInspector] + [SerializeField] + protected Flip mFlip; + + [NonSerialized] + private Rect mInnerUV = default(Rect); + + [NonSerialized] + private Rect mOuterUV = default(Rect); + + public AdvancedType centerType = AdvancedType.Sliced; + + public AdvancedType leftType = AdvancedType.Sliced; + + public AdvancedType rightType = AdvancedType.Sliced; + + public AdvancedType bottomType = AdvancedType.Sliced; + + public AdvancedType topType = AdvancedType.Sliced; + + protected static Vector2[] mTempPos = new Vector2[4]; + + protected static Vector2[] mTempUVs = new Vector2[4]; + + public virtual Type type + { + get + { + return mType; + } + set + { + if (mType != value) + { + mType = value; + MarkAsChanged(); + } + } + } + + public Flip flip + { + get + { + return mFlip; + } + set + { + if (mFlip != value) + { + mFlip = value; + MarkAsChanged(); + } + } + } + + public FillDirection fillDirection + { + get + { + return mFillDirection; + } + set + { + if (mFillDirection != value) + { + mFillDirection = value; + mChanged = true; + } + } + } + + public float fillAmount + { + get + { + return mFillAmount; + } + set + { + float num = Mathf.Clamp01(value); + if (mFillAmount != num) + { + mFillAmount = num; + mChanged = true; + } + } + } + + public override int minWidth + { + get + { + if (type == Type.Sliced || type == Type.Advanced) + { + Vector4 vector = border * pixelSize; + int num = Mathf.RoundToInt(vector.x + vector.z); + return Mathf.Max(base.minWidth, ((num & 1) != 1) ? num : (num + 1)); + } + return base.minWidth; + } + } + + public override int minHeight + { + get + { + if (type == Type.Sliced || type == Type.Advanced) + { + Vector4 vector = border * pixelSize; + int num = Mathf.RoundToInt(vector.y + vector.w); + return Mathf.Max(base.minHeight, ((num & 1) != 1) ? num : (num + 1)); + } + return base.minHeight; + } + } + + public bool invert + { + get + { + return mInvert; + } + set + { + if (mInvert != value) + { + mInvert = value; + mChanged = true; + } + } + } + + public bool hasBorder + { + get + { + Vector4 border = this.border; + return border.x != 0f || border.y != 0f || border.z != 0f || border.w != 0f; + } + } + + public virtual bool premultipliedAlpha => false; + + public virtual float pixelSize => 1f; + + private Vector4 drawingUVs + { + get + { + switch (mFlip) + { + case Flip.Horizontally: + return new Vector4(mOuterUV.xMax, mOuterUV.yMin, mOuterUV.xMin, mOuterUV.yMax); + case Flip.Vertically: + return new Vector4(mOuterUV.xMin, mOuterUV.yMax, mOuterUV.xMax, mOuterUV.yMin); + case Flip.Both: + return new Vector4(mOuterUV.xMax, mOuterUV.yMax, mOuterUV.xMin, mOuterUV.yMin); + default: + return new Vector4(mOuterUV.xMin, mOuterUV.yMin, mOuterUV.xMax, mOuterUV.yMax); + } + } + } + + private Color32 drawingColor + { + get + { + Color c = base.color; + c.a = finalAlpha; + if (premultipliedAlpha) + { + c = NGUITools.ApplyPMA(c); + } + if (QualitySettings.activeColorSpace == ColorSpace.Linear) + { + c.r = Mathf.Pow(c.r, 2.2f); + c.g = Mathf.Pow(c.g, 2.2f); + c.b = Mathf.Pow(c.b, 2.2f); + } + return c; + } + } + + protected void Fill(BetterList verts, BetterList uvs, BetterList cols, Rect outer, Rect inner) + { + mOuterUV = outer; + mInnerUV = inner; + switch (type) + { + case Type.Simple: + SimpleFill(verts, uvs, cols); + break; + case Type.Sliced: + SlicedFill(verts, uvs, cols); + break; + case Type.Filled: + FilledFill(verts, uvs, cols); + break; + case Type.Tiled: + TiledFill(verts, uvs, cols); + break; + case Type.Advanced: + AdvancedFill(verts, uvs, cols); + break; + } + } + + private void SimpleFill(BetterList verts, BetterList uvs, BetterList cols) + { + Vector4 drawingDimensions = this.drawingDimensions; + Vector4 drawingUVs = this.drawingUVs; + Color32 drawingColor = this.drawingColor; + verts.Add(new Vector3(drawingDimensions.x, drawingDimensions.y)); + verts.Add(new Vector3(drawingDimensions.x, drawingDimensions.w)); + verts.Add(new Vector3(drawingDimensions.z, drawingDimensions.w)); + verts.Add(new Vector3(drawingDimensions.z, drawingDimensions.y)); + uvs.Add(new Vector2(drawingUVs.x, drawingUVs.y)); + uvs.Add(new Vector2(drawingUVs.x, drawingUVs.w)); + uvs.Add(new Vector2(drawingUVs.z, drawingUVs.w)); + uvs.Add(new Vector2(drawingUVs.z, drawingUVs.y)); + cols.Add(drawingColor); + cols.Add(drawingColor); + cols.Add(drawingColor); + cols.Add(drawingColor); + } + + private void SlicedFill(BetterList verts, BetterList uvs, BetterList cols) + { + Vector4 vector = border * pixelSize; + if (vector.x == 0f && vector.y == 0f && vector.z == 0f && vector.w == 0f) + { + SimpleFill(verts, uvs, cols); + } + else + { + Color32 drawingColor = this.drawingColor; + Vector4 drawingDimensions = this.drawingDimensions; + mTempPos[0].x = drawingDimensions.x; + mTempPos[0].y = drawingDimensions.y; + mTempPos[3].x = drawingDimensions.z; + mTempPos[3].y = drawingDimensions.w; + if (mFlip == Flip.Horizontally || mFlip == Flip.Both) + { + mTempPos[1].x = mTempPos[0].x + vector.z; + mTempPos[2].x = mTempPos[3].x - vector.x; + mTempUVs[3].x = mOuterUV.xMin; + mTempUVs[2].x = mInnerUV.xMin; + mTempUVs[1].x = mInnerUV.xMax; + mTempUVs[0].x = mOuterUV.xMax; + } + else + { + mTempPos[1].x = mTempPos[0].x + vector.x; + mTempPos[2].x = mTempPos[3].x - vector.z; + mTempUVs[0].x = mOuterUV.xMin; + mTempUVs[1].x = mInnerUV.xMin; + mTempUVs[2].x = mInnerUV.xMax; + mTempUVs[3].x = mOuterUV.xMax; + } + if (mFlip == Flip.Vertically || mFlip == Flip.Both) + { + mTempPos[1].y = mTempPos[0].y + vector.w; + mTempPos[2].y = mTempPos[3].y - vector.y; + mTempUVs[3].y = mOuterUV.yMin; + mTempUVs[2].y = mInnerUV.yMin; + mTempUVs[1].y = mInnerUV.yMax; + mTempUVs[0].y = mOuterUV.yMax; + } + else + { + mTempPos[1].y = mTempPos[0].y + vector.y; + mTempPos[2].y = mTempPos[3].y - vector.w; + mTempUVs[0].y = mOuterUV.yMin; + mTempUVs[1].y = mInnerUV.yMin; + mTempUVs[2].y = mInnerUV.yMax; + mTempUVs[3].y = mOuterUV.yMax; + } + for (int i = 0; i < 3; i++) + { + int num = i + 1; + for (int j = 0; j < 3; j++) + { + if (centerType != 0 || i != 1 || j != 1) + { + int num2 = j + 1; + verts.Add(new Vector3(mTempPos[i].x, mTempPos[j].y)); + verts.Add(new Vector3(mTempPos[i].x, mTempPos[num2].y)); + verts.Add(new Vector3(mTempPos[num].x, mTempPos[num2].y)); + verts.Add(new Vector3(mTempPos[num].x, mTempPos[j].y)); + uvs.Add(new Vector2(mTempUVs[i].x, mTempUVs[j].y)); + uvs.Add(new Vector2(mTempUVs[i].x, mTempUVs[num2].y)); + uvs.Add(new Vector2(mTempUVs[num].x, mTempUVs[num2].y)); + uvs.Add(new Vector2(mTempUVs[num].x, mTempUVs[j].y)); + cols.Add(drawingColor); + cols.Add(drawingColor); + cols.Add(drawingColor); + cols.Add(drawingColor); + } + } + } + } + } + + private void TiledFill(BetterList verts, BetterList uvs, BetterList cols) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null)) + { + Vector2 a = new Vector2(mInnerUV.width * (float)mainTexture.width, mInnerUV.height * (float)mainTexture.height); + a *= pixelSize; + if (!(mainTexture == null) && !(a.x < 2f) && !(a.y < 2f)) + { + Color32 drawingColor = this.drawingColor; + Vector4 drawingDimensions = this.drawingDimensions; + Vector4 vector = default(Vector4); + if (mFlip == Flip.Horizontally || mFlip == Flip.Both) + { + vector.x = mInnerUV.xMax; + vector.z = mInnerUV.xMin; + } + else + { + vector.x = mInnerUV.xMin; + vector.z = mInnerUV.xMax; + } + if (mFlip == Flip.Vertically || mFlip == Flip.Both) + { + vector.y = mInnerUV.yMax; + vector.w = mInnerUV.yMin; + } + else + { + vector.y = mInnerUV.yMin; + vector.w = mInnerUV.yMax; + } + float x = drawingDimensions.x; + float num = drawingDimensions.y; + float x2 = vector.x; + float y = vector.y; + for (; num < drawingDimensions.w; num += a.y) + { + x = drawingDimensions.x; + float num2 = num + a.y; + float y2 = vector.w; + if (num2 > drawingDimensions.w) + { + y2 = Mathf.Lerp(vector.y, vector.w, (drawingDimensions.w - num) / a.y); + num2 = drawingDimensions.w; + } + for (; x < drawingDimensions.z; x += a.x) + { + float num3 = x + a.x; + float x3 = vector.z; + if (num3 > drawingDimensions.z) + { + x3 = Mathf.Lerp(vector.x, vector.z, (drawingDimensions.z - x) / a.x); + num3 = drawingDimensions.z; + } + verts.Add(new Vector3(x, num)); + verts.Add(new Vector3(x, num2)); + verts.Add(new Vector3(num3, num2)); + verts.Add(new Vector3(num3, num)); + uvs.Add(new Vector2(x2, y)); + uvs.Add(new Vector2(x2, y2)); + uvs.Add(new Vector2(x3, y2)); + uvs.Add(new Vector2(x3, y)); + cols.Add(drawingColor); + cols.Add(drawingColor); + cols.Add(drawingColor); + cols.Add(drawingColor); + } + } + } + } + } + + private void FilledFill(BetterList verts, BetterList uvs, BetterList cols) + { + if (!(mFillAmount < 0.001f)) + { + Vector4 drawingDimensions = this.drawingDimensions; + Vector4 drawingUVs = this.drawingUVs; + Color32 drawingColor = this.drawingColor; + if (mFillDirection == FillDirection.Horizontal || mFillDirection == FillDirection.Vertical) + { + if (mFillDirection == FillDirection.Horizontal) + { + float num = (drawingUVs.z - drawingUVs.x) * mFillAmount; + if (mInvert) + { + drawingDimensions.x = drawingDimensions.z - (drawingDimensions.z - drawingDimensions.x) * mFillAmount; + drawingUVs.x = drawingUVs.z - num; + } + else + { + drawingDimensions.z = drawingDimensions.x + (drawingDimensions.z - drawingDimensions.x) * mFillAmount; + drawingUVs.z = drawingUVs.x + num; + } + } + else if (mFillDirection == FillDirection.Vertical) + { + float num2 = (drawingUVs.w - drawingUVs.y) * mFillAmount; + if (mInvert) + { + drawingDimensions.y = drawingDimensions.w - (drawingDimensions.w - drawingDimensions.y) * mFillAmount; + drawingUVs.y = drawingUVs.w - num2; + } + else + { + drawingDimensions.w = drawingDimensions.y + (drawingDimensions.w - drawingDimensions.y) * mFillAmount; + drawingUVs.w = drawingUVs.y + num2; + } + } + } + mTempPos[0] = new Vector2(drawingDimensions.x, drawingDimensions.y); + mTempPos[1] = new Vector2(drawingDimensions.x, drawingDimensions.w); + mTempPos[2] = new Vector2(drawingDimensions.z, drawingDimensions.w); + mTempPos[3] = new Vector2(drawingDimensions.z, drawingDimensions.y); + mTempUVs[0] = new Vector2(drawingUVs.x, drawingUVs.y); + mTempUVs[1] = new Vector2(drawingUVs.x, drawingUVs.w); + mTempUVs[2] = new Vector2(drawingUVs.z, drawingUVs.w); + mTempUVs[3] = new Vector2(drawingUVs.z, drawingUVs.y); + if (mFillAmount < 1f) + { + if (mFillDirection == FillDirection.Radial90) + { + if (RadialCut(mTempPos, mTempUVs, mFillAmount, mInvert, 0)) + { + for (int i = 0; i < 4; i++) + { + verts.Add(mTempPos[i]); + uvs.Add(mTempUVs[i]); + cols.Add(drawingColor); + } + } + return; + } + if (mFillDirection == FillDirection.Radial180) + { + for (int j = 0; j < 2; j++) + { + float t = 0f; + float t2 = 1f; + float t3; + float t4; + if (j == 0) + { + t3 = 0f; + t4 = 0.5f; + } + else + { + t3 = 0.5f; + t4 = 1f; + } + mTempPos[0].x = Mathf.Lerp(drawingDimensions.x, drawingDimensions.z, t3); + mTempPos[1].x = mTempPos[0].x; + mTempPos[2].x = Mathf.Lerp(drawingDimensions.x, drawingDimensions.z, t4); + mTempPos[3].x = mTempPos[2].x; + mTempPos[0].y = Mathf.Lerp(drawingDimensions.y, drawingDimensions.w, t); + mTempPos[1].y = Mathf.Lerp(drawingDimensions.y, drawingDimensions.w, t2); + mTempPos[2].y = mTempPos[1].y; + mTempPos[3].y = mTempPos[0].y; + mTempUVs[0].x = Mathf.Lerp(drawingUVs.x, drawingUVs.z, t3); + mTempUVs[1].x = mTempUVs[0].x; + mTempUVs[2].x = Mathf.Lerp(drawingUVs.x, drawingUVs.z, t4); + mTempUVs[3].x = mTempUVs[2].x; + mTempUVs[0].y = Mathf.Lerp(drawingUVs.y, drawingUVs.w, t); + mTempUVs[1].y = Mathf.Lerp(drawingUVs.y, drawingUVs.w, t2); + mTempUVs[2].y = mTempUVs[1].y; + mTempUVs[3].y = mTempUVs[0].y; + float value = mInvert ? (mFillAmount * 2f - (float)(1 - j)) : (fillAmount * 2f - (float)j); + if (RadialCut(mTempPos, mTempUVs, Mathf.Clamp01(value), !mInvert, NGUIMath.RepeatIndex(j + 3, 4))) + { + for (int k = 0; k < 4; k++) + { + verts.Add(mTempPos[k]); + uvs.Add(mTempUVs[k]); + cols.Add(drawingColor); + } + } + } + return; + } + if (mFillDirection == FillDirection.Radial360) + { + for (int l = 0; l < 4; l++) + { + float t5; + float t6; + if (l < 2) + { + t5 = 0f; + t6 = 0.5f; + } + else + { + t5 = 0.5f; + t6 = 1f; + } + float t7; + float t8; + if (l == 0 || l == 3) + { + t7 = 0f; + t8 = 0.5f; + } + else + { + t7 = 0.5f; + t8 = 1f; + } + mTempPos[0].x = Mathf.Lerp(drawingDimensions.x, drawingDimensions.z, t5); + mTempPos[1].x = mTempPos[0].x; + mTempPos[2].x = Mathf.Lerp(drawingDimensions.x, drawingDimensions.z, t6); + mTempPos[3].x = mTempPos[2].x; + mTempPos[0].y = Mathf.Lerp(drawingDimensions.y, drawingDimensions.w, t7); + mTempPos[1].y = Mathf.Lerp(drawingDimensions.y, drawingDimensions.w, t8); + mTempPos[2].y = mTempPos[1].y; + mTempPos[3].y = mTempPos[0].y; + mTempUVs[0].x = Mathf.Lerp(drawingUVs.x, drawingUVs.z, t5); + mTempUVs[1].x = mTempUVs[0].x; + mTempUVs[2].x = Mathf.Lerp(drawingUVs.x, drawingUVs.z, t6); + mTempUVs[3].x = mTempUVs[2].x; + mTempUVs[0].y = Mathf.Lerp(drawingUVs.y, drawingUVs.w, t7); + mTempUVs[1].y = Mathf.Lerp(drawingUVs.y, drawingUVs.w, t8); + mTempUVs[2].y = mTempUVs[1].y; + mTempUVs[3].y = mTempUVs[0].y; + float value2 = (!mInvert) ? (mFillAmount * 4f - (float)(3 - NGUIMath.RepeatIndex(l + 2, 4))) : (mFillAmount * 4f - (float)NGUIMath.RepeatIndex(l + 2, 4)); + if (RadialCut(mTempPos, mTempUVs, Mathf.Clamp01(value2), mInvert, NGUIMath.RepeatIndex(l + 2, 4))) + { + for (int m = 0; m < 4; m++) + { + verts.Add(mTempPos[m]); + uvs.Add(mTempUVs[m]); + cols.Add(drawingColor); + } + } + } + return; + } + } + for (int n = 0; n < 4; n++) + { + verts.Add(mTempPos[n]); + uvs.Add(mTempUVs[n]); + cols.Add(drawingColor); + } + } + } + + private void AdvancedFill(BetterList verts, BetterList uvs, BetterList cols) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null)) + { + Vector4 vector = border * pixelSize; + if (vector.x == 0f && vector.y == 0f && vector.z == 0f && vector.w == 0f) + { + SimpleFill(verts, uvs, cols); + } + else + { + Color32 drawingColor = this.drawingColor; + Vector4 drawingDimensions = this.drawingDimensions; + Vector2 a = new Vector2(mInnerUV.width * (float)mainTexture.width, mInnerUV.height * (float)mainTexture.height); + a *= pixelSize; + if (a.x < 1f) + { + a.x = 1f; + } + if (a.y < 1f) + { + a.y = 1f; + } + mTempPos[0].x = drawingDimensions.x; + mTempPos[0].y = drawingDimensions.y; + mTempPos[3].x = drawingDimensions.z; + mTempPos[3].y = drawingDimensions.w; + if (mFlip == Flip.Horizontally || mFlip == Flip.Both) + { + mTempPos[1].x = mTempPos[0].x + vector.z; + mTempPos[2].x = mTempPos[3].x - vector.x; + mTempUVs[3].x = mOuterUV.xMin; + mTempUVs[2].x = mInnerUV.xMin; + mTempUVs[1].x = mInnerUV.xMax; + mTempUVs[0].x = mOuterUV.xMax; + } + else + { + mTempPos[1].x = mTempPos[0].x + vector.x; + mTempPos[2].x = mTempPos[3].x - vector.z; + mTempUVs[0].x = mOuterUV.xMin; + mTempUVs[1].x = mInnerUV.xMin; + mTempUVs[2].x = mInnerUV.xMax; + mTempUVs[3].x = mOuterUV.xMax; + } + if (mFlip == Flip.Vertically || mFlip == Flip.Both) + { + mTempPos[1].y = mTempPos[0].y + vector.w; + mTempPos[2].y = mTempPos[3].y - vector.y; + mTempUVs[3].y = mOuterUV.yMin; + mTempUVs[2].y = mInnerUV.yMin; + mTempUVs[1].y = mInnerUV.yMax; + mTempUVs[0].y = mOuterUV.yMax; + } + else + { + mTempPos[1].y = mTempPos[0].y + vector.y; + mTempPos[2].y = mTempPos[3].y - vector.w; + mTempUVs[0].y = mOuterUV.yMin; + mTempUVs[1].y = mInnerUV.yMin; + mTempUVs[2].y = mInnerUV.yMax; + mTempUVs[3].y = mOuterUV.yMax; + } + for (int i = 0; i < 3; i++) + { + int num = i + 1; + for (int j = 0; j < 3; j++) + { + if (centerType != 0 || i != 1 || j != 1) + { + int num2 = j + 1; + if (i == 1 && j == 1) + { + if (centerType == AdvancedType.Tiled) + { + float x = mTempPos[i].x; + float x2 = mTempPos[num].x; + float y = mTempPos[j].y; + float y2 = mTempPos[num2].y; + float x3 = mTempUVs[i].x; + float y3 = mTempUVs[j].y; + for (float num3 = y; num3 < y2; num3 += a.y) + { + float num4 = x; + float num5 = mTempUVs[num2].y; + float num6 = num3 + a.y; + if (num6 > y2) + { + num5 = Mathf.Lerp(y3, num5, (y2 - num3) / a.y); + num6 = y2; + } + for (; num4 < x2; num4 += a.x) + { + float num7 = num4 + a.x; + float num8 = mTempUVs[num].x; + if (num7 > x2) + { + num8 = Mathf.Lerp(x3, num8, (x2 - num4) / a.x); + num7 = x2; + } + Fill(verts, uvs, cols, num4, num7, num3, num6, x3, num8, y3, num5, drawingColor); + } + } + } + else if (centerType == AdvancedType.Sliced) + { + Fill(verts, uvs, cols, mTempPos[i].x, mTempPos[num].x, mTempPos[j].y, mTempPos[num2].y, mTempUVs[i].x, mTempUVs[num].x, mTempUVs[j].y, mTempUVs[num2].y, drawingColor); + } + } + else if (i == 1) + { + if ((j == 0 && bottomType == AdvancedType.Tiled) || (j == 2 && topType == AdvancedType.Tiled)) + { + float x4 = mTempPos[i].x; + float x5 = mTempPos[num].x; + float y4 = mTempPos[j].y; + float y5 = mTempPos[num2].y; + float x6 = mTempUVs[i].x; + float y6 = mTempUVs[j].y; + float y7 = mTempUVs[num2].y; + for (float num9 = x4; num9 < x5; num9 += a.x) + { + float num10 = num9 + a.x; + float num11 = mTempUVs[num].x; + if (num10 > x5) + { + num11 = Mathf.Lerp(x6, num11, (x5 - num9) / a.x); + num10 = x5; + } + Fill(verts, uvs, cols, num9, num10, y4, y5, x6, num11, y6, y7, drawingColor); + } + } + else if ((j == 0 && bottomType == AdvancedType.Sliced) || (j == 2 && topType == AdvancedType.Sliced)) + { + Fill(verts, uvs, cols, mTempPos[i].x, mTempPos[num].x, mTempPos[j].y, mTempPos[num2].y, mTempUVs[i].x, mTempUVs[num].x, mTempUVs[j].y, mTempUVs[num2].y, drawingColor); + } + } + else if (j == 1) + { + if ((i == 0 && leftType == AdvancedType.Tiled) || (i == 2 && rightType == AdvancedType.Tiled)) + { + float x7 = mTempPos[i].x; + float x8 = mTempPos[num].x; + float y8 = mTempPos[j].y; + float y9 = mTempPos[num2].y; + float x9 = mTempUVs[i].x; + float x10 = mTempUVs[num].x; + float y10 = mTempUVs[j].y; + for (float num12 = y8; num12 < y9; num12 += a.y) + { + float num13 = mTempUVs[num2].y; + float num14 = num12 + a.y; + if (num14 > y9) + { + num13 = Mathf.Lerp(y10, num13, (y9 - num12) / a.y); + num14 = y9; + } + Fill(verts, uvs, cols, x7, x8, num12, num14, x9, x10, y10, num13, drawingColor); + } + } + else if ((i == 0 && leftType == AdvancedType.Sliced) || (i == 2 && rightType == AdvancedType.Sliced)) + { + Fill(verts, uvs, cols, mTempPos[i].x, mTempPos[num].x, mTempPos[j].y, mTempPos[num2].y, mTempUVs[i].x, mTempUVs[num].x, mTempUVs[j].y, mTempUVs[num2].y, drawingColor); + } + } + else + { + Fill(verts, uvs, cols, mTempPos[i].x, mTempPos[num].x, mTempPos[j].y, mTempPos[num2].y, mTempUVs[i].x, mTempUVs[num].x, mTempUVs[j].y, mTempUVs[num2].y, drawingColor); + } + } + } + } + } + } + } + + private static bool RadialCut(Vector2[] xy, Vector2[] uv, float fill, bool invert, int corner) + { + if (fill < 0.001f) + { + return false; + } + if ((corner & 1) == 1) + { + invert = !invert; + } + if (!invert && fill > 0.999f) + { + return true; + } + float num = Mathf.Clamp01(fill); + if (invert) + { + num = 1f - num; + } + num *= 1.57079637f; + float cos = Mathf.Cos(num); + float sin = Mathf.Sin(num); + RadialCut(xy, cos, sin, invert, corner); + RadialCut(uv, cos, sin, invert, corner); + return true; + } + + private static void RadialCut(Vector2[] xy, float cos, float sin, bool invert, int corner) + { + int num = NGUIMath.RepeatIndex(corner + 1, 4); + int num2 = NGUIMath.RepeatIndex(corner + 2, 4); + int num3 = NGUIMath.RepeatIndex(corner + 3, 4); + if ((corner & 1) == 1) + { + if (sin > cos) + { + cos /= sin; + sin = 1f; + if (invert) + { + xy[num].x = Mathf.Lerp(xy[corner].x, xy[num2].x, cos); + xy[num2].x = xy[num].x; + } + } + else if (cos > sin) + { + sin /= cos; + cos = 1f; + if (!invert) + { + xy[num2].y = Mathf.Lerp(xy[corner].y, xy[num2].y, sin); + xy[num3].y = xy[num2].y; + } + } + else + { + cos = 1f; + sin = 1f; + } + if (!invert) + { + xy[num3].x = Mathf.Lerp(xy[corner].x, xy[num2].x, cos); + } + else + { + xy[num].y = Mathf.Lerp(xy[corner].y, xy[num2].y, sin); + } + } + else + { + if (cos > sin) + { + sin /= cos; + cos = 1f; + if (!invert) + { + xy[num].y = Mathf.Lerp(xy[corner].y, xy[num2].y, sin); + xy[num2].y = xy[num].y; + } + } + else if (sin > cos) + { + cos /= sin; + sin = 1f; + if (invert) + { + xy[num2].x = Mathf.Lerp(xy[corner].x, xy[num2].x, cos); + xy[num3].x = xy[num2].x; + } + } + else + { + cos = 1f; + sin = 1f; + } + if (invert) + { + xy[num3].y = Mathf.Lerp(xy[corner].y, xy[num2].y, sin); + } + else + { + xy[num].x = Mathf.Lerp(xy[corner].x, xy[num2].x, cos); + } + } + } + + private static void Fill(BetterList verts, BetterList uvs, BetterList cols, float v0x, float v1x, float v0y, float v1y, float u0x, float u1x, float u0y, float u1y, Color col) + { + verts.Add(new Vector3(v0x, v0y)); + verts.Add(new Vector3(v0x, v1y)); + verts.Add(new Vector3(v1x, v1y)); + verts.Add(new Vector3(v1x, v0y)); + uvs.Add(new Vector2(u0x, u0y)); + uvs.Add(new Vector2(u0x, u1y)); + uvs.Add(new Vector2(u1x, u1y)); + uvs.Add(new Vector2(u1x, u0y)); + cols.Add(col); + cols.Add(col); + cols.Add(col); + cols.Add(col); + } +} diff --git a/UIButton.cs b/UIButton.cs new file mode 100644 index 00000000..8c65671d --- /dev/null +++ b/UIButton.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button")] +public class UIButton : UIButtonColor +{ + public static UIButton current; + + public bool dragHighlight; + + public string hoverSprite; + + public string pressedSprite; + + public string disabledSprite; + + public Sprite hoverSprite2D; + + public Sprite pressedSprite2D; + + public Sprite disabledSprite2D; + + public bool pixelSnap; + + public List onClick = new List(); + + [NonSerialized] + private UISprite mSprite; + + [NonSerialized] + private UI2DSprite mSprite2D; + + [NonSerialized] + private string mNormalSprite; + + [NonSerialized] + private Sprite mNormalSprite2D; + + public override bool isEnabled + { + get + { + if (!base.enabled) + { + return false; + } + Collider component = GetComponent(); + if ((bool)component && component.enabled) + { + return true; + } + Collider2D component2 = GetComponent(); + return (bool)component2 && component2.enabled; + } + set + { + if (isEnabled != value) + { + Collider component = GetComponent(); + if (component != null) + { + component.enabled = value; + SetState((!value) ? State.Disabled : State.Normal, immediate: false); + } + else + { + Collider2D component2 = GetComponent(); + if (component2 != null) + { + component2.enabled = value; + SetState((!value) ? State.Disabled : State.Normal, immediate: false); + } + else + { + base.enabled = value; + } + } + } + } + } + + public string normalSprite + { + get + { + if (!mInitDone) + { + OnInit(); + } + return mNormalSprite; + } + set + { + if (mSprite != null && !string.IsNullOrEmpty(mNormalSprite) && mNormalSprite == mSprite.spriteName) + { + mNormalSprite = value; + SetSprite(value); + NGUITools.SetDirty(mSprite); + } + else + { + mNormalSprite = value; + if (mState == State.Normal) + { + SetSprite(value); + } + } + } + } + + public Sprite normalSprite2D + { + get + { + if (!mInitDone) + { + OnInit(); + } + return mNormalSprite2D; + } + set + { + if (mSprite2D != null && mNormalSprite2D == mSprite2D.sprite2D) + { + mNormalSprite2D = value; + SetSprite(value); + NGUITools.SetDirty(mSprite); + } + else + { + mNormalSprite2D = value; + if (mState == State.Normal) + { + SetSprite(value); + } + } + } + } + + protected override void OnInit() + { + base.OnInit(); + mSprite = (mWidget as UISprite); + mSprite2D = (mWidget as UI2DSprite); + if (mSprite != null) + { + mNormalSprite = mSprite.spriteName; + } + if (mSprite2D != null) + { + mNormalSprite2D = mSprite2D.sprite2D; + } + } + + protected override void OnEnable() + { + if (isEnabled) + { + if (mInitDone) + { + if (UICamera.currentScheme == UICamera.ControlScheme.Controller) + { + OnHover(UICamera.selectedObject == base.gameObject); + } + else if (UICamera.currentScheme == UICamera.ControlScheme.Mouse) + { + OnHover(UICamera.hoveredObject == base.gameObject); + } + else + { + SetState(State.Normal, immediate: false); + } + } + } + else + { + SetState(State.Disabled, immediate: true); + } + } + + protected override void OnDragOver() + { + if (isEnabled && (dragHighlight || UICamera.currentTouch.pressed == base.gameObject)) + { + base.OnDragOver(); + } + } + + protected override void OnDragOut() + { + if (isEnabled && (dragHighlight || UICamera.currentTouch.pressed == base.gameObject)) + { + base.OnDragOut(); + } + } + + protected virtual void OnClick() + { + if (current == null && isEnabled) + { + current = this; + EventDelegate.Execute(onClick); + current = null; + } + } + + public override void SetState(State state, bool immediate) + { + base.SetState(state, immediate); + if (mSprite != null) + { + switch (state) + { + case State.Normal: + SetSprite(mNormalSprite); + break; + case State.Hover: + SetSprite((!string.IsNullOrEmpty(hoverSprite)) ? hoverSprite : mNormalSprite); + break; + case State.Pressed: + SetSprite(pressedSprite); + break; + case State.Disabled: + SetSprite(disabledSprite); + break; + } + } + else if (mSprite2D != null) + { + switch (state) + { + case State.Normal: + SetSprite(mNormalSprite2D); + break; + case State.Hover: + SetSprite((!(hoverSprite2D == null)) ? hoverSprite2D : mNormalSprite2D); + break; + case State.Pressed: + SetSprite(pressedSprite2D); + break; + case State.Disabled: + SetSprite(disabledSprite2D); + break; + } + } + } + + protected void SetSprite(string sp) + { + if (mSprite != null && !string.IsNullOrEmpty(sp) && mSprite.spriteName != sp) + { + mSprite.spriteName = sp; + if (pixelSnap) + { + mSprite.MakePixelPerfect(); + } + } + } + + protected void SetSprite(Sprite sp) + { + if (sp != null && mSprite2D != null && mSprite2D.sprite2D != sp) + { + mSprite2D.sprite2D = sp; + if (pixelSnap) + { + mSprite2D.MakePixelPerfect(); + } + } + } +} diff --git a/UIButtonActivate.cs b/UIButtonActivate.cs new file mode 100644 index 00000000..a4a3b67b --- /dev/null +++ b/UIButtonActivate.cs @@ -0,0 +1,17 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button Activate")] +public class UIButtonActivate : MonoBehaviour +{ + public GameObject target; + + public bool state = true; + + private void OnClick() + { + if (target != null) + { + NGUITools.SetActive(target, state); + } + } +} diff --git a/UIButtonColor.cs b/UIButtonColor.cs new file mode 100644 index 00000000..a9979c07 --- /dev/null +++ b/UIButtonColor.cs @@ -0,0 +1,315 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button Color")] +[ExecuteInEditMode] +public class UIButtonColor : UIWidgetContainer +{ + public enum State + { + Normal, + Hover, + Pressed, + Disabled + } + + public GameObject tweenTarget; + + public Color hover = new Color(0.882352948f, 0.784313738f, 0.5882353f, 1f); + + public Color pressed = new Color(0.7176471f, 0.6392157f, 0.482352942f, 1f); + + public Color disabledColor = Color.grey; + + public float duration = 0.2f; + + [NonSerialized] + protected Color mStartingColor; + + [NonSerialized] + protected Color mDefaultColor; + + [NonSerialized] + protected bool mInitDone; + + [NonSerialized] + protected UIWidget mWidget; + + [NonSerialized] + protected State mState; + + public State state + { + get + { + return mState; + } + set + { + SetState(value, instant: false); + } + } + + public Color defaultColor + { + get + { + if (!mInitDone) + { + OnInit(); + } + return mDefaultColor; + } + set + { + if (!mInitDone) + { + OnInit(); + } + mDefaultColor = value; + State state = mState; + mState = State.Disabled; + SetState(state, instant: false); + } + } + + public virtual bool isEnabled + { + get + { + return base.enabled; + } + set + { + base.enabled = value; + } + } + + public void ResetDefaultColor() + { + defaultColor = mStartingColor; + } + + private void Awake() + { + if (!mInitDone) + { + OnInit(); + } + } + + private void Start() + { + if (!isEnabled) + { + SetState(State.Disabled, instant: true); + } + } + + protected virtual void OnInit() + { + mInitDone = true; + if (tweenTarget == null) + { + tweenTarget = base.gameObject; + } + mWidget = tweenTarget.GetComponent(); + if (mWidget != null) + { + mDefaultColor = mWidget.color; + mStartingColor = mDefaultColor; + } + else + { + Renderer component = tweenTarget.GetComponent(); + if (component != null) + { + mDefaultColor = ((!Application.isPlaying) ? component.sharedMaterial.color : component.material.color); + mStartingColor = mDefaultColor; + } + else + { + Light component2 = tweenTarget.GetComponent(); + if (component2 != null) + { + mDefaultColor = component2.color; + mStartingColor = mDefaultColor; + } + else + { + tweenTarget = null; + mInitDone = false; + } + } + } + } + + protected virtual void OnEnable() + { + if (mInitDone) + { + OnHover(UICamera.IsHighlighted(base.gameObject)); + } + if (UICamera.currentTouch != null) + { + if (UICamera.currentTouch.pressed == base.gameObject) + { + OnPress(isPressed: true); + } + else if (UICamera.currentTouch.current == base.gameObject) + { + OnHover(isOver: true); + } + } + } + + protected virtual void OnDisable() + { + if (mInitDone && tweenTarget != null) + { + SetState(State.Normal, instant: true); + TweenColor component = tweenTarget.GetComponent(); + if (component != null) + { + component.value = mDefaultColor; + component.enabled = false; + } + } + } + + protected virtual void OnHover(bool isOver) + { + if (isEnabled) + { + if (!mInitDone) + { + OnInit(); + } + if (tweenTarget != null) + { + SetState(isOver ? State.Hover : State.Normal, instant: false); + } + } + } + + protected virtual void OnPress(bool isPressed) + { + if (isEnabled && UICamera.currentTouch != null) + { + if (!mInitDone) + { + OnInit(); + } + if (tweenTarget != null) + { + if (isPressed) + { + SetState(State.Pressed, instant: false); + } + else if (UICamera.currentTouch.current == base.gameObject) + { + if (UICamera.currentScheme == UICamera.ControlScheme.Controller) + { + SetState(State.Hover, instant: false); + } + else if (UICamera.currentScheme == UICamera.ControlScheme.Mouse && UICamera.hoveredObject == base.gameObject) + { + SetState(State.Hover, instant: false); + } + else + { + SetState(State.Normal, instant: false); + } + } + else + { + SetState(State.Normal, instant: false); + } + } + } + } + + protected virtual void OnDragOver() + { + if (isEnabled) + { + if (!mInitDone) + { + OnInit(); + } + if (tweenTarget != null) + { + SetState(State.Pressed, instant: false); + } + } + } + + protected virtual void OnDragOut() + { + if (isEnabled) + { + if (!mInitDone) + { + OnInit(); + } + if (tweenTarget != null) + { + SetState(State.Normal, instant: false); + } + } + } + + protected virtual void OnSelect(bool isSelected) + { + if (isEnabled && tweenTarget != null) + { + if (UICamera.currentScheme == UICamera.ControlScheme.Controller) + { + OnHover(isSelected); + } + else if (!isSelected && UICamera.touchCount < 2) + { + OnHover(isSelected); + } + } + } + + public virtual void SetState(State state, bool instant) + { + if (!mInitDone) + { + mInitDone = true; + OnInit(); + } + if (mState != state) + { + mState = state; + UpdateColor(instant); + } + } + + public void UpdateColor(bool instant) + { + TweenColor tweenColor; + switch (mState) + { + case State.Hover: + tweenColor = TweenColor.Begin(tweenTarget, duration, hover); + break; + case State.Pressed: + tweenColor = TweenColor.Begin(tweenTarget, duration, pressed); + break; + case State.Disabled: + tweenColor = TweenColor.Begin(tweenTarget, duration, disabledColor); + break; + default: + tweenColor = TweenColor.Begin(tweenTarget, duration, mDefaultColor); + break; + } + if (instant && tweenColor != null) + { + tweenColor.value = tweenColor.to; + tweenColor.enabled = false; + } + } +} diff --git a/UIButtonKeys.cs b/UIButtonKeys.cs new file mode 100644 index 00000000..850e39d1 --- /dev/null +++ b/UIButtonKeys.cs @@ -0,0 +1,56 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button Keys (Legacy)")] +[ExecuteInEditMode] +public class UIButtonKeys : UIKeyNavigation +{ + public UIButtonKeys selectOnClick; + + public UIButtonKeys selectOnUp; + + public UIButtonKeys selectOnDown; + + public UIButtonKeys selectOnLeft; + + public UIButtonKeys selectOnRight; + + protected override void OnEnable() + { + Upgrade(); + base.OnEnable(); + } + + public void Upgrade() + { + if (onClick == null && selectOnClick != null) + { + onClick = selectOnClick.gameObject; + selectOnClick = null; + NGUITools.SetDirty(this); + } + if (onLeft == null && selectOnLeft != null) + { + onLeft = selectOnLeft.gameObject; + selectOnLeft = null; + NGUITools.SetDirty(this); + } + if (onRight == null && selectOnRight != null) + { + onRight = selectOnRight.gameObject; + selectOnRight = null; + NGUITools.SetDirty(this); + } + if (onUp == null && selectOnUp != null) + { + onUp = selectOnUp.gameObject; + selectOnUp = null; + NGUITools.SetDirty(this); + } + if (onDown == null && selectOnDown != null) + { + onDown = selectOnDown.gameObject; + selectOnDown = null; + NGUITools.SetDirty(this); + } + } +} diff --git a/UIButtonMessage.cs b/UIButtonMessage.cs new file mode 100644 index 00000000..9c31e724 --- /dev/null +++ b/UIButtonMessage.cs @@ -0,0 +1,103 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button Message (Legacy)")] +public class UIButtonMessage : MonoBehaviour +{ + public enum Trigger + { + OnClick, + OnMouseOver, + OnMouseOut, + OnPress, + OnRelease, + OnDoubleClick + } + + public GameObject target; + + public string functionName; + + public Trigger trigger; + + public bool includeChildren; + + private bool mStarted; + + private void Start() + { + mStarted = true; + } + + private void OnEnable() + { + if (mStarted) + { + OnHover(UICamera.IsHighlighted(base.gameObject)); + } + } + + private void OnHover(bool isOver) + { + if (base.enabled && ((isOver && trigger == Trigger.OnMouseOver) || (!isOver && trigger == Trigger.OnMouseOut))) + { + Send(); + } + } + + private void OnPress(bool isPressed) + { + if (base.enabled && ((isPressed && trigger == Trigger.OnPress) || (!isPressed && trigger == Trigger.OnRelease))) + { + Send(); + } + } + + private void OnSelect(bool isSelected) + { + if (base.enabled && (!isSelected || UICamera.currentScheme == UICamera.ControlScheme.Controller)) + { + OnHover(isSelected); + } + } + + private void OnClick() + { + if (base.enabled && trigger == Trigger.OnClick) + { + Send(); + } + } + + private void OnDoubleClick() + { + if (base.enabled && trigger == Trigger.OnDoubleClick) + { + Send(); + } + } + + private void Send() + { + if (!string.IsNullOrEmpty(functionName)) + { + if (target == null) + { + target = base.gameObject; + } + if (includeChildren) + { + Transform[] componentsInChildren = target.GetComponentsInChildren(); + int i = 0; + for (int num = componentsInChildren.Length; i < num; i++) + { + Transform transform = componentsInChildren[i]; + transform.gameObject.SendMessage(functionName, base.gameObject, SendMessageOptions.DontRequireReceiver); + } + } + else + { + target.SendMessage(functionName, base.gameObject, SendMessageOptions.DontRequireReceiver); + } + } + } +} diff --git a/UIButtonOffset.cs b/UIButtonOffset.cs new file mode 100644 index 00000000..327e2192 --- /dev/null +++ b/UIButtonOffset.cs @@ -0,0 +1,83 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button Offset")] +public class UIButtonOffset : MonoBehaviour +{ + public Transform tweenTarget; + + public Vector3 hover = Vector3.zero; + + public Vector3 pressed = new Vector3(2f, -2f); + + public float duration = 0.2f; + + private Vector3 mPos; + + private bool mStarted; + + private void Start() + { + if (!mStarted) + { + mStarted = true; + if (tweenTarget == null) + { + tweenTarget = base.transform; + } + mPos = tweenTarget.localPosition; + } + } + + private void OnEnable() + { + if (mStarted) + { + OnHover(UICamera.IsHighlighted(base.gameObject)); + } + } + + private void OnDisable() + { + if (mStarted && tweenTarget != null) + { + TweenPosition component = tweenTarget.GetComponent(); + if (component != null) + { + component.value = mPos; + component.enabled = false; + } + } + } + + private void OnPress(bool isPressed) + { + if (base.enabled) + { + if (!mStarted) + { + Start(); + } + TweenPosition.Begin(tweenTarget.gameObject, duration, isPressed ? (mPos + pressed) : ((!UICamera.IsHighlighted(base.gameObject)) ? mPos : (mPos + hover))).method = UITweener.Method.EaseInOut; + } + } + + private void OnHover(bool isOver) + { + if (base.enabled) + { + if (!mStarted) + { + Start(); + } + TweenPosition.Begin(tweenTarget.gameObject, duration, (!isOver) ? mPos : (mPos + hover)).method = UITweener.Method.EaseInOut; + } + } + + private void OnSelect(bool isSelected) + { + if (base.enabled && (!isSelected || UICamera.currentScheme == UICamera.ControlScheme.Controller)) + { + OnHover(isSelected); + } + } +} diff --git a/UIButtonRotation.cs b/UIButtonRotation.cs new file mode 100644 index 00000000..43714e40 --- /dev/null +++ b/UIButtonRotation.cs @@ -0,0 +1,83 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button Rotation")] +public class UIButtonRotation : MonoBehaviour +{ + public Transform tweenTarget; + + public Vector3 hover = Vector3.zero; + + public Vector3 pressed = Vector3.zero; + + public float duration = 0.2f; + + private Quaternion mRot; + + private bool mStarted; + + private void Start() + { + if (!mStarted) + { + mStarted = true; + if (tweenTarget == null) + { + tweenTarget = base.transform; + } + mRot = tweenTarget.localRotation; + } + } + + private void OnEnable() + { + if (mStarted) + { + OnHover(UICamera.IsHighlighted(base.gameObject)); + } + } + + private void OnDisable() + { + if (mStarted && tweenTarget != null) + { + TweenRotation component = tweenTarget.GetComponent(); + if (component != null) + { + component.value = mRot; + component.enabled = false; + } + } + } + + private void OnPress(bool isPressed) + { + if (base.enabled) + { + if (!mStarted) + { + Start(); + } + TweenRotation.Begin(tweenTarget.gameObject, duration, isPressed ? (mRot * Quaternion.Euler(pressed)) : ((!UICamera.IsHighlighted(base.gameObject)) ? mRot : (mRot * Quaternion.Euler(hover)))).method = UITweener.Method.EaseInOut; + } + } + + private void OnHover(bool isOver) + { + if (base.enabled) + { + if (!mStarted) + { + Start(); + } + TweenRotation.Begin(tweenTarget.gameObject, duration, (!isOver) ? mRot : (mRot * Quaternion.Euler(hover))).method = UITweener.Method.EaseInOut; + } + } + + private void OnSelect(bool isSelected) + { + if (base.enabled && (!isSelected || UICamera.currentScheme == UICamera.ControlScheme.Controller)) + { + OnHover(isSelected); + } + } +} diff --git a/UIButtonScale.cs b/UIButtonScale.cs new file mode 100644 index 00000000..b549aa02 --- /dev/null +++ b/UIButtonScale.cs @@ -0,0 +1,83 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Button Scale")] +public class UIButtonScale : MonoBehaviour +{ + public Transform tweenTarget; + + public Vector3 hover = new Vector3(1.1f, 1.1f, 1.1f); + + public Vector3 pressed = new Vector3(1.05f, 1.05f, 1.05f); + + public float duration = 0.2f; + + private Vector3 mScale; + + private bool mStarted; + + private void Start() + { + if (!mStarted) + { + mStarted = true; + if (tweenTarget == null) + { + tweenTarget = base.transform; + } + mScale = tweenTarget.localScale; + } + } + + private void OnEnable() + { + if (mStarted) + { + OnHover(UICamera.IsHighlighted(base.gameObject)); + } + } + + private void OnDisable() + { + if (mStarted && tweenTarget != null) + { + TweenScale component = tweenTarget.GetComponent(); + if (component != null) + { + component.value = mScale; + component.enabled = false; + } + } + } + + private void OnPress(bool isPressed) + { + if (base.enabled) + { + if (!mStarted) + { + Start(); + } + TweenScale.Begin(tweenTarget.gameObject, duration, isPressed ? Vector3.Scale(mScale, pressed) : ((!UICamera.IsHighlighted(base.gameObject)) ? mScale : Vector3.Scale(mScale, hover))).method = UITweener.Method.EaseInOut; + } + } + + private void OnHover(bool isOver) + { + if (base.enabled) + { + if (!mStarted) + { + Start(); + } + TweenScale.Begin(tweenTarget.gameObject, duration, (!isOver) ? mScale : Vector3.Scale(mScale, hover)).method = UITweener.Method.EaseInOut; + } + } + + private void OnSelect(bool isSelected) + { + if (base.enabled && (!isSelected || UICamera.currentScheme == UICamera.ControlScheme.Controller)) + { + OnHover(isSelected); + } + } +} diff --git a/UICamera.cs b/UICamera.cs new file mode 100644 index 00000000..c425fef7 --- /dev/null +++ b/UICamera.cs @@ -0,0 +1,1650 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Event System (UICamera)")] +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +public class UICamera : MonoBehaviour +{ + public enum ControlScheme + { + Mouse, + Touch, + Controller + } + + public enum ClickNotification + { + None, + Always, + BasedOnDelta + } + + public class MouseOrTouch + { + public Vector2 pos; + + public Vector2 lastPos; + + public Vector2 delta; + + public Vector2 totalDelta; + + public Camera pressedCam; + + public GameObject last; + + public GameObject current; + + public GameObject pressed; + + public GameObject dragged; + + public float pressTime; + + public float clickTime; + + public ClickNotification clickNotification = ClickNotification.Always; + + public bool touchBegan = true; + + public bool pressStarted; + + public bool dragStarted; + + public float deltaTime => (!touchBegan) ? 0f : (RealTime.time - pressTime); + + public bool isOverUI => current != null && current != fallThrough && NGUITools.FindInParents(current) != null; + } + + public enum EventType + { + World_3D, + UI_3D, + World_2D, + UI_2D + } + + private struct DepthEntry + { + public int depth; + + public RaycastHit hit; + + public Vector3 point; + + public GameObject go; + } + + public delegate bool GetKeyStateFunc(KeyCode key); + + public delegate float GetAxisFunc(string name); + + public delegate void OnScreenResize(); + + public delegate void OnCustomInput(); + + public delegate void MoveDelegate(Vector2 delta); + + public delegate void VoidDelegate(GameObject go); + + public delegate void BoolDelegate(GameObject go, bool state); + + public delegate void FloatDelegate(GameObject go, float delta); + + public delegate void VectorDelegate(GameObject go, Vector2 delta); + + public delegate void ObjectDelegate(GameObject go, GameObject obj); + + public delegate void KeyCodeDelegate(GameObject go, KeyCode key); + + public static BetterList list = new BetterList(); + + public static GetKeyStateFunc GetKeyDown = Input.GetKeyDown; + + public static GetKeyStateFunc GetKeyUp = Input.GetKeyUp; + + public static GetKeyStateFunc GetKey = Input.GetKey; + + public static GetAxisFunc GetAxis = Input.GetAxis; + + public static OnScreenResize onScreenResize; + + public EventType eventType = EventType.UI_3D; + + public bool eventsGoToColliders; + + public LayerMask eventReceiverMask = -1; + + public bool debug; + + public bool useMouse = true; + + public bool useTouch = true; + + public bool allowMultiTouch = true; + + public bool useKeyboard = true; + + public bool useController = true; + + public bool stickyTooltip = true; + + public float tooltipDelay = 1f; + + public float mouseDragThreshold = 4f; + + public float mouseClickThreshold = 10f; + + public float touchDragThreshold = 40f; + + public float touchClickThreshold = 40f; + + public float rangeDistance = -1f; + + public string scrollAxisName = "Mouse ScrollWheel"; + + public string verticalAxisName = "Vertical"; + + public string horizontalAxisName = "Horizontal"; + + public KeyCode submitKey0 = KeyCode.Return; + + public KeyCode submitKey1 = KeyCode.JoystickButton0; + + public KeyCode cancelKey0 = KeyCode.Escape; + + public KeyCode cancelKey1 = KeyCode.JoystickButton1; + + public static OnCustomInput onCustomInput; + + public static bool showTooltips = true; + + public static Vector2 lastTouchPosition = Vector2.zero; + + public static Vector3 lastWorldPosition = Vector3.zero; + + public static RaycastHit lastHit; + + public static UICamera current = null; + + public static Camera currentCamera = null; + + public static ControlScheme currentScheme = ControlScheme.Mouse; + + public static int currentTouchID = -1; + + public static KeyCode currentKey = KeyCode.None; + + public static MouseOrTouch currentTouch = null; + + public static bool inputHasFocus = false; + + private static GameObject mGenericHandler; + + public static GameObject fallThrough; + + public static VoidDelegate onClick; + + public static VoidDelegate onDoubleClick; + + public static BoolDelegate onHover; + + public static BoolDelegate onPress; + + public static BoolDelegate onSelect; + + public static FloatDelegate onScroll; + + public static VectorDelegate onDrag; + + public static VoidDelegate onDragStart; + + public static ObjectDelegate onDragOver; + + public static ObjectDelegate onDragOut; + + public static VoidDelegate onDragEnd; + + public static ObjectDelegate onDrop; + + public static KeyCodeDelegate onKey; + + public static BoolDelegate onTooltip; + + public static MoveDelegate onMouseMove; + + private static GameObject mCurrentSelection = null; + + private static GameObject mNextSelection = null; + + private static ControlScheme mNextScheme = ControlScheme.Controller; + + private static MouseOrTouch[] mMouse = new MouseOrTouch[3] + { + new MouseOrTouch(), + new MouseOrTouch(), + new MouseOrTouch() + }; + + private static GameObject mHover; + + public static MouseOrTouch controller = new MouseOrTouch(); + + private static float mNextEvent = 0f; + + private static Dictionary mTouches = new Dictionary(); + + private static int mWidth = 0; + + private static int mHeight = 0; + + private GameObject mTooltip; + + private Camera mCam; + + private float mTooltipTime; + + private float mNextRaycast; + + public static bool isDragging = false; + + public static GameObject hoveredObject; + + private static DepthEntry mHit = default(DepthEntry); + + private static BetterList mHits = new BetterList(); + + private static Plane m2DPlane = new Plane(Vector3.back, 0f); + + private static bool mNotifying = false; + + [Obsolete("Use new OnDragStart / OnDragOver / OnDragOut / OnDragEnd events instead")] + public bool stickyPress + { + get + { + return true; + } + } + + public static Ray currentRay => (!(currentCamera != null) || currentTouch == null) ? default(Ray) : currentCamera.ScreenPointToRay(currentTouch.pos); + + [Obsolete("Use delegates instead such as UICamera.onClick, UICamera.onHover, etc.")] + public static GameObject genericEventHandler + { + get + { + return mGenericHandler; + } + set + { + mGenericHandler = value; + } + } + + private bool handlesEvents => eventHandler == this; + + public Camera cachedCamera + { + get + { + if (mCam == null) + { + mCam = GetComponent(); + } + return mCam; + } + } + + public static bool isOverUI + { + get + { + if (currentTouch != null) + { + return currentTouch.isOverUI; + } + if (hoveredObject == null) + { + return false; + } + if (hoveredObject == fallThrough) + { + return false; + } + return NGUITools.FindInParents(hoveredObject) != null; + } + } + + public static GameObject selectedObject + { + get + { + return mCurrentSelection; + } + set + { + SetSelection(value, currentScheme); + } + } + + public static int touchCount + { + get + { + int num = 0; + foreach (KeyValuePair mTouch in mTouches) + { + if (mTouch.Value.pressed != null) + { + num++; + } + } + for (int i = 0; i < mMouse.Length; i++) + { + if (mMouse[i].pressed != null) + { + num++; + } + } + if (controller.pressed != null) + { + num++; + } + return num; + } + } + + public static int dragCount + { + get + { + int num = 0; + foreach (KeyValuePair mTouch in mTouches) + { + if (mTouch.Value.dragged != null) + { + num++; + } + } + for (int i = 0; i < mMouse.Length; i++) + { + if (mMouse[i].dragged != null) + { + num++; + } + } + if (controller.dragged != null) + { + num++; + } + return num; + } + } + + public static Camera mainCamera + { + get + { + UICamera eventHandler = UICamera.eventHandler; + return (!(eventHandler != null)) ? null : eventHandler.cachedCamera; + } + } + + public static UICamera eventHandler + { + get + { + for (int i = 0; i < list.size; i++) + { + UICamera uICamera = list.buffer[i]; + if (!(uICamera == null) && uICamera.enabled && NGUITools.GetActive(uICamera.gameObject)) + { + return uICamera; + } + } + return null; + } + } + + public static bool IsPressed(GameObject go) + { + for (int i = 0; i < 3; i++) + { + if (mMouse[i].pressed == go) + { + return true; + } + } + foreach (KeyValuePair mTouch in mTouches) + { + if (mTouch.Value.pressed == go) + { + return true; + } + } + if (controller.pressed == go) + { + return true; + } + return false; + } + + protected static void SetSelection(GameObject go, ControlScheme scheme) + { + if (mNextSelection != null) + { + mNextSelection = go; + } + else if (mCurrentSelection != go) + { + mNextSelection = go; + mNextScheme = scheme; + if (list.size > 0) + { + UICamera uICamera = (!(mNextSelection != null)) ? list[0] : FindCameraForLayer(mNextSelection.layer); + if (uICamera != null) + { + uICamera.StartCoroutine(uICamera.ChangeSelection()); + } + } + } + } + + private IEnumerator ChangeSelection() + { + yield return (object)new WaitForEndOfFrame(); + if (onSelect != null) + { + onSelect(mCurrentSelection, state: false); + } + Notify(mCurrentSelection, "OnSelect", false); + mCurrentSelection = mNextSelection; + mNextSelection = null; + if (mCurrentSelection != null) + { + current = this; + currentCamera = mCam; + currentScheme = mNextScheme; + inputHasFocus = (mCurrentSelection.GetComponent() != null); + if (onSelect != null) + { + onSelect(mCurrentSelection, state: true); + } + Notify(mCurrentSelection, "OnSelect", true); + current = null; + } + else + { + inputHasFocus = false; + } + } + + private static int CompareFunc(UICamera a, UICamera b) + { + if (a.cachedCamera.depth < b.cachedCamera.depth) + { + return 1; + } + if (a.cachedCamera.depth > b.cachedCamera.depth) + { + return -1; + } + return 0; + } + + private static Rigidbody FindRootRigidbody(Transform trans) + { + while (trans != null) + { + if (trans.GetComponent() != null) + { + return null; + } + Rigidbody component = trans.GetComponent(); + if (component != null) + { + return component; + } + trans = trans.parent; + } + return null; + } + + private static Rigidbody2D FindRootRigidbody2D(Transform trans) + { + while (trans != null) + { + if (trans.GetComponent() != null) + { + return null; + } + Rigidbody2D component = trans.GetComponent(); + if (component != null) + { + return component; + } + trans = trans.parent; + } + return null; + } + + public static bool Raycast(Vector3 inPos) + { + for (int i = 0; i < list.size; i++) + { + UICamera uICamera = list.buffer[i]; + if (uICamera.enabled && NGUITools.GetActive(uICamera.gameObject)) + { + currentCamera = uICamera.cachedCamera; + Vector3 vector = currentCamera.ScreenToViewportPoint(inPos); + if (!float.IsNaN(vector.x) && !float.IsNaN(vector.y) && !(vector.x < 0f) && !(vector.x > 1f) && !(vector.y < 0f) && !(vector.y > 1f)) + { + Ray ray = currentCamera.ScreenPointToRay(inPos); + int layerMask = currentCamera.cullingMask & (int)uICamera.eventReceiverMask; + float enter = (!(uICamera.rangeDistance > 0f)) ? (currentCamera.farClipPlane - currentCamera.nearClipPlane) : uICamera.rangeDistance; + if (uICamera.eventType == EventType.World_3D) + { + if (Physics.Raycast(ray, out lastHit, enter, layerMask)) + { + lastWorldPosition = lastHit.point; + hoveredObject = lastHit.collider.gameObject; + if (!uICamera.eventsGoToColliders) + { + Rigidbody rigidbody = FindRootRigidbody(hoveredObject.transform); + if (rigidbody != null) + { + hoveredObject = rigidbody.gameObject; + } + } + return true; + } + } + else if (uICamera.eventType == EventType.UI_3D) + { + RaycastHit[] array = Physics.RaycastAll(ray, enter, layerMask); + if (array.Length > 1) + { + for (int j = 0; j < array.Length; j++) + { + GameObject gameObject = array[j].collider.gameObject; + UIWidget component = gameObject.GetComponent(); + if (component != null) + { + if (!component.isVisible || (component.hitCheck != null && !component.hitCheck(array[j].point))) + { + continue; + } + } + else + { + UIRect uIRect = NGUITools.FindInParents(gameObject); + if (uIRect != null && uIRect.finalAlpha < 0.001f) + { + continue; + } + } + mHit.depth = NGUITools.CalculateRaycastDepth(gameObject); + if (mHit.depth != 2147483647) + { + mHit.hit = array[j]; + mHit.point = array[j].point; + mHit.go = array[j].collider.gameObject; + mHits.Add(mHit); + } + } + mHits.Sort((DepthEntry r1, DepthEntry r2) => r2.depth.CompareTo(r1.depth)); + for (int k = 0; k < mHits.size; k++) + { + if (IsVisible(ref mHits.buffer[k])) + { + DepthEntry depthEntry = mHits[k]; + lastHit = depthEntry.hit; + DepthEntry depthEntry2 = mHits[k]; + hoveredObject = depthEntry2.go; + DepthEntry depthEntry3 = mHits[k]; + lastWorldPosition = depthEntry3.point; + mHits.Clear(); + return true; + } + } + mHits.Clear(); + } + else if (array.Length == 1) + { + GameObject gameObject2 = array[0].collider.gameObject; + UIWidget component2 = gameObject2.GetComponent(); + if (component2 != null) + { + if (!component2.isVisible || (component2.hitCheck != null && !component2.hitCheck(array[0].point))) + { + continue; + } + } + else + { + UIRect uIRect2 = NGUITools.FindInParents(gameObject2); + if (uIRect2 != null && uIRect2.finalAlpha < 0.001f) + { + continue; + } + } + if (IsVisible(array[0].point, array[0].collider.gameObject)) + { + lastHit = array[0]; + lastWorldPosition = array[0].point; + hoveredObject = lastHit.collider.gameObject; + return true; + } + } + } + else if (uICamera.eventType == EventType.World_2D) + { + if (m2DPlane.Raycast(ray, out enter)) + { + Vector3 point = ray.GetPoint(enter); + Collider2D collider2D = Physics2D.OverlapPoint(point, layerMask); + if ((bool)collider2D) + { + lastWorldPosition = point; + hoveredObject = collider2D.gameObject; + if (!uICamera.eventsGoToColliders) + { + Rigidbody2D rigidbody2D = FindRootRigidbody2D(hoveredObject.transform); + if (rigidbody2D != null) + { + hoveredObject = rigidbody2D.gameObject; + } + } + return true; + } + } + } + else if (uICamera.eventType == EventType.UI_2D && m2DPlane.Raycast(ray, out enter)) + { + lastWorldPosition = ray.GetPoint(enter); + Collider2D[] array2 = Physics2D.OverlapPointAll(lastWorldPosition, layerMask); + if (array2.Length > 1) + { + for (int l = 0; l < array2.Length; l++) + { + GameObject gameObject3 = array2[l].gameObject; + UIWidget component3 = gameObject3.GetComponent(); + if (component3 != null) + { + if (!component3.isVisible || (component3.hitCheck != null && !component3.hitCheck(lastWorldPosition))) + { + continue; + } + } + else + { + UIRect uIRect3 = NGUITools.FindInParents(gameObject3); + if (uIRect3 != null && uIRect3.finalAlpha < 0.001f) + { + continue; + } + } + mHit.depth = NGUITools.CalculateRaycastDepth(gameObject3); + if (mHit.depth != 2147483647) + { + mHit.go = gameObject3; + mHit.point = lastWorldPosition; + mHits.Add(mHit); + } + } + mHits.Sort((DepthEntry r1, DepthEntry r2) => r2.depth.CompareTo(r1.depth)); + for (int m = 0; m < mHits.size; m++) + { + if (IsVisible(ref mHits.buffer[m])) + { + DepthEntry depthEntry4 = mHits[m]; + hoveredObject = depthEntry4.go; + mHits.Clear(); + return true; + } + } + mHits.Clear(); + } + else if (array2.Length == 1) + { + GameObject gameObject4 = array2[0].gameObject; + UIWidget component4 = gameObject4.GetComponent(); + if (component4 != null) + { + if (!component4.isVisible || (component4.hitCheck != null && !component4.hitCheck(lastWorldPosition))) + { + continue; + } + } + else + { + UIRect uIRect4 = NGUITools.FindInParents(gameObject4); + if (uIRect4 != null && uIRect4.finalAlpha < 0.001f) + { + continue; + } + } + if (IsVisible(lastWorldPosition, gameObject4)) + { + hoveredObject = gameObject4; + return true; + } + } + } + } + } + } + return false; + } + + private static bool IsVisible(Vector3 worldPoint, GameObject go) + { + UIPanel uIPanel = NGUITools.FindInParents(go); + while (uIPanel != null) + { + if (!uIPanel.IsVisible(worldPoint)) + { + return false; + } + uIPanel = uIPanel.parentPanel; + } + return true; + } + + private static bool IsVisible(ref DepthEntry de) + { + UIPanel uIPanel = NGUITools.FindInParents(de.go); + while (uIPanel != null) + { + if (!uIPanel.IsVisible(de.point)) + { + return false; + } + uIPanel = uIPanel.parentPanel; + } + return true; + } + + public static bool IsHighlighted(GameObject go) + { + if (currentScheme == ControlScheme.Mouse) + { + return hoveredObject == go; + } + if (currentScheme == ControlScheme.Controller) + { + return selectedObject == go; + } + return false; + } + + public static UICamera FindCameraForLayer(int layer) + { + int num = 1 << layer; + for (int i = 0; i < list.size; i++) + { + UICamera uICamera = list.buffer[i]; + Camera cachedCamera = uICamera.cachedCamera; + if (cachedCamera != null && (cachedCamera.cullingMask & num) != 0) + { + return uICamera; + } + } + return null; + } + + private static int GetDirection(KeyCode up, KeyCode down) + { + if (GetKeyDown(up)) + { + return 1; + } + if (GetKeyDown(down)) + { + return -1; + } + return 0; + } + + private static int GetDirection(KeyCode up0, KeyCode up1, KeyCode down0, KeyCode down1) + { + if (GetKeyDown(up0) || GetKeyDown(up1)) + { + return 1; + } + if (GetKeyDown(down0) || GetKeyDown(down1)) + { + return -1; + } + return 0; + } + + private static int GetDirection(string axis) + { + float time = RealTime.time; + if (mNextEvent < time && !string.IsNullOrEmpty(axis)) + { + float num = GetAxis(axis); + if (num > 0.75f) + { + mNextEvent = time + 0.25f; + return 1; + } + if (num < -0.75f) + { + mNextEvent = time + 0.25f; + return -1; + } + } + return 0; + } + + public static void Notify(GameObject go, string funcName, object obj) + { + if (!mNotifying) + { + mNotifying = true; + if (NGUITools.GetActive(go)) + { + go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver); + if (mGenericHandler != null && mGenericHandler != go) + { + mGenericHandler.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver); + } + } + mNotifying = false; + } + } + + public static MouseOrTouch GetMouse(int button) + { + return mMouse[button]; + } + + public static MouseOrTouch GetTouch(int id) + { + MouseOrTouch value = null; + if (id < 0) + { + return GetMouse(-id - 1); + } + if (!mTouches.TryGetValue(id, out value)) + { + value = new MouseOrTouch(); + value.pressTime = RealTime.time; + value.touchBegan = true; + mTouches.Add(id, value); + } + return value; + } + + public static void RemoveTouch(int id) + { + mTouches.Remove(id); + } + + private void Awake() + { + mWidth = Screen.width; + mHeight = Screen.height; + if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.WP8Player || Application.platform == RuntimePlatform.BlackBerryPlayer) + { + useTouch = true; + if (Application.platform == RuntimePlatform.IPhonePlayer) + { + useMouse = false; + useKeyboard = false; + useController = false; + } + } + else if (Application.platform == RuntimePlatform.PS3 || Application.platform == RuntimePlatform.XBOX360) + { + useMouse = false; + useTouch = false; + useKeyboard = false; + useController = true; + } + mMouse[0].pos = Input.mousePosition; + for (int i = 1; i < 3; i++) + { + mMouse[i].pos = mMouse[0].pos; + mMouse[i].lastPos = mMouse[0].pos; + } + lastTouchPosition = mMouse[0].pos; + } + + private void OnEnable() + { + list.Add(this); + list.Sort(CompareFunc); + } + + private void OnDisable() + { + list.Remove(this); + } + + private void Start() + { + if (eventType != 0 && cachedCamera.transparencySortMode != TransparencySortMode.Orthographic) + { + cachedCamera.transparencySortMode = TransparencySortMode.Orthographic; + } + if (Application.isPlaying) + { + if (fallThrough == null) + { + UIRoot uIRoot = NGUITools.FindInParents(base.gameObject); + if (uIRoot != null) + { + fallThrough = uIRoot.gameObject; + } + else + { + Transform transform = base.transform; + fallThrough = ((!(transform.parent != null)) ? base.gameObject : transform.parent.gameObject); + } + } + cachedCamera.eventMask = 0; + } + if (handlesEvents) + { + NGUIDebug.debugRaycast = debug; + } + } + + private void Update() + { + if (handlesEvents) + { + current = this; + if (useTouch) + { + ProcessTouches(); + } + else if (useMouse) + { + ProcessMouse(); + } + if (onCustomInput != null) + { + onCustomInput(); + } + if (useMouse && mCurrentSelection != null) + { + if (cancelKey0 != 0 && GetKeyDown(cancelKey0)) + { + currentScheme = ControlScheme.Controller; + currentKey = cancelKey0; + selectedObject = null; + } + else if (cancelKey1 != 0 && GetKeyDown(cancelKey1)) + { + currentScheme = ControlScheme.Controller; + currentKey = cancelKey1; + selectedObject = null; + } + } + if (mCurrentSelection == null) + { + inputHasFocus = false; + } + if (mCurrentSelection != null) + { + ProcessOthers(); + } + if (useMouse && mHover != null) + { + float num = string.IsNullOrEmpty(scrollAxisName) ? 0f : GetAxis(scrollAxisName); + if (num != 0f) + { + if (onScroll != null) + { + onScroll(mHover, num); + } + Notify(mHover, "OnScroll", num); + } + if (showTooltips && mTooltipTime != 0f && (mTooltipTime < RealTime.time || GetKey(KeyCode.LeftShift) || GetKey(KeyCode.RightShift))) + { + mTooltip = mHover; + ShowTooltip(val: true); + } + } + current = null; + } + } + + private void LateUpdate() + { + if (handlesEvents) + { + int width = Screen.width; + int height = Screen.height; + if (width != mWidth || height != mHeight) + { + mWidth = width; + mHeight = height; + UIRoot.Broadcast("UpdateAnchors"); + if (onScreenResize != null) + { + onScreenResize(); + } + } + } + } + + public void ProcessMouse() + { + lastTouchPosition = Input.mousePosition; + mMouse[0].delta = lastTouchPosition - mMouse[0].pos; + mMouse[0].pos = lastTouchPosition; + bool flag = mMouse[0].delta.sqrMagnitude > 0.001f; + for (int i = 1; i < 3; i++) + { + mMouse[i].pos = mMouse[0].pos; + mMouse[i].delta = mMouse[0].delta; + } + bool flag2 = false; + bool flag3 = false; + for (int j = 0; j < 3; j++) + { + if (Input.GetMouseButtonDown(j)) + { + currentScheme = ControlScheme.Mouse; + flag3 = true; + flag2 = true; + } + else if (Input.GetMouseButton(j)) + { + currentScheme = ControlScheme.Mouse; + flag2 = true; + } + } + if (flag2 || flag || mNextRaycast < RealTime.time) + { + mNextRaycast = RealTime.time + 0.02f; + if (!Raycast(Input.mousePosition)) + { + hoveredObject = fallThrough; + } + if (hoveredObject == null) + { + hoveredObject = mGenericHandler; + } + for (int k = 0; k < 3; k++) + { + mMouse[k].current = hoveredObject; + } + } + bool flag4 = mMouse[0].last != mMouse[0].current; + if (flag4) + { + currentScheme = ControlScheme.Mouse; + } + if (flag2) + { + mTooltipTime = 0f; + } + else if (flag && (!stickyTooltip || flag4)) + { + if (mTooltipTime != 0f) + { + mTooltipTime = RealTime.time + tooltipDelay; + } + else if (mTooltip != null) + { + ShowTooltip(val: false); + } + } + if (flag && onMouseMove != null) + { + currentTouch = mMouse[0]; + onMouseMove(currentTouch.delta); + currentTouch = null; + } + if ((flag3 || !flag2) && mHover != null && flag4) + { + currentScheme = ControlScheme.Mouse; + currentTouch = mMouse[0]; + if (mTooltip != null) + { + ShowTooltip(val: false); + } + if (onHover != null) + { + onHover(mHover, state: false); + } + Notify(mHover, "OnHover", false); + mHover = null; + } + for (int l = 0; l < 3; l++) + { + bool mouseButtonDown = Input.GetMouseButtonDown(l); + bool mouseButtonUp = Input.GetMouseButtonUp(l); + if (mouseButtonDown || mouseButtonUp) + { + currentScheme = ControlScheme.Mouse; + } + currentTouch = mMouse[l]; + currentTouchID = -1 - l; + currentKey = (KeyCode)(323 + l); + if (mouseButtonDown) + { + currentTouch.pressedCam = currentCamera; + } + else if (currentTouch.pressed != null) + { + currentCamera = currentTouch.pressedCam; + } + ProcessTouch(mouseButtonDown, mouseButtonUp); + currentKey = KeyCode.None; + } + if (!flag2 && flag4) + { + currentScheme = ControlScheme.Mouse; + mTooltipTime = RealTime.time + tooltipDelay; + mHover = mMouse[0].current; + currentTouch = mMouse[0]; + if (onHover != null) + { + onHover(mHover, state: true); + } + Notify(mHover, "OnHover", true); + } + currentTouch = null; + mMouse[0].last = mMouse[0].current; + for (int m = 1; m < 3; m++) + { + mMouse[m].last = mMouse[0].last; + } + } + + public void ProcessTouches() + { + currentScheme = ControlScheme.Touch; + for (int i = 0; i < Input.touchCount; i++) + { + Touch touch = Input.GetTouch(i); + currentTouchID = ((!allowMultiTouch) ? 1 : touch.fingerId); + currentTouch = GetTouch(currentTouchID); + bool flag = touch.phase == TouchPhase.Began || currentTouch.touchBegan; + bool flag2 = touch.phase == TouchPhase.Canceled || touch.phase == TouchPhase.Ended; + currentTouch.touchBegan = false; + currentTouch.delta = ((!flag) ? (touch.position - currentTouch.pos) : Vector2.zero); + currentTouch.pos = touch.position; + if (!Raycast(currentTouch.pos)) + { + hoveredObject = fallThrough; + } + if (hoveredObject == null) + { + hoveredObject = mGenericHandler; + } + currentTouch.last = currentTouch.current; + currentTouch.current = hoveredObject; + lastTouchPosition = currentTouch.pos; + if (flag) + { + currentTouch.pressedCam = currentCamera; + } + else if (currentTouch.pressed != null) + { + currentCamera = currentTouch.pressedCam; + } + if (touch.tapCount > 1) + { + currentTouch.clickTime = RealTime.time; + } + ProcessTouch(flag, flag2); + if (flag2) + { + RemoveTouch(currentTouchID); + } + currentTouch.last = null; + currentTouch = null; + if (!allowMultiTouch) + { + break; + } + } + if (Input.touchCount == 0 && useMouse) + { + ProcessMouse(); + } + } + + private void ProcessFakeTouches() + { + bool mouseButtonDown = Input.GetMouseButtonDown(0); + bool mouseButtonUp = Input.GetMouseButtonUp(0); + bool mouseButton = Input.GetMouseButton(0); + if (mouseButtonDown || mouseButtonUp || mouseButton) + { + currentTouchID = 1; + currentTouch = mMouse[0]; + currentTouch.touchBegan = mouseButtonDown; + if (mouseButtonDown) + { + currentTouch.pressTime = RealTime.time; + } + Vector2 vector = Input.mousePosition; + currentTouch.delta = ((!mouseButtonDown) ? (vector - currentTouch.pos) : Vector2.zero); + currentTouch.pos = vector; + if (!Raycast(currentTouch.pos)) + { + hoveredObject = fallThrough; + } + if (hoveredObject == null) + { + hoveredObject = mGenericHandler; + } + currentTouch.last = currentTouch.current; + currentTouch.current = hoveredObject; + lastTouchPosition = currentTouch.pos; + if (mouseButtonDown) + { + currentTouch.pressedCam = currentCamera; + } + else if (currentTouch.pressed != null) + { + currentCamera = currentTouch.pressedCam; + } + ProcessTouch(mouseButtonDown, mouseButtonUp); + if (mouseButtonUp) + { + RemoveTouch(currentTouchID); + } + currentTouch.last = null; + currentTouch = null; + } + } + + public void ProcessOthers() + { + currentTouchID = -100; + currentTouch = controller; + bool flag = false; + bool flag2 = false; + if (submitKey0 != 0 && GetKeyDown(submitKey0)) + { + currentKey = submitKey0; + flag = true; + } + if (submitKey1 != 0 && GetKeyDown(submitKey1)) + { + currentKey = submitKey1; + flag = true; + } + if (submitKey0 != 0 && GetKeyUp(submitKey0)) + { + currentKey = submitKey0; + flag2 = true; + } + if (submitKey1 != 0 && GetKeyUp(submitKey1)) + { + currentKey = submitKey1; + flag2 = true; + } + if (flag || flag2) + { + currentScheme = ControlScheme.Controller; + currentTouch.last = currentTouch.current; + currentTouch.current = mCurrentSelection; + ProcessTouch(flag, flag2); + currentTouch.last = null; + } + int num = 0; + int num2 = 0; + if (useKeyboard) + { + if (inputHasFocus) + { + num += GetDirection(KeyCode.UpArrow, KeyCode.DownArrow); + num2 += GetDirection(KeyCode.RightArrow, KeyCode.LeftArrow); + } + else + { + num += GetDirection(KeyCode.W, KeyCode.UpArrow, KeyCode.S, KeyCode.DownArrow); + num2 += GetDirection(KeyCode.D, KeyCode.RightArrow, KeyCode.A, KeyCode.LeftArrow); + } + } + if (useController) + { + if (!string.IsNullOrEmpty(verticalAxisName)) + { + num += GetDirection(verticalAxisName); + } + if (!string.IsNullOrEmpty(horizontalAxisName)) + { + num2 += GetDirection(horizontalAxisName); + } + } + if (num != 0) + { + currentScheme = ControlScheme.Controller; + KeyCode keyCode = (num <= 0) ? KeyCode.DownArrow : KeyCode.UpArrow; + if (onKey != null) + { + onKey(mCurrentSelection, keyCode); + } + Notify(mCurrentSelection, "OnKey", keyCode); + } + if (num2 != 0) + { + currentScheme = ControlScheme.Controller; + KeyCode keyCode2 = (num2 <= 0) ? KeyCode.LeftArrow : KeyCode.RightArrow; + if (onKey != null) + { + onKey(mCurrentSelection, keyCode2); + } + Notify(mCurrentSelection, "OnKey", keyCode2); + } + if (useKeyboard && GetKeyDown(KeyCode.Tab)) + { + currentKey = KeyCode.Tab; + currentScheme = ControlScheme.Controller; + if (onKey != null) + { + onKey(mCurrentSelection, KeyCode.Tab); + } + Notify(mCurrentSelection, "OnKey", KeyCode.Tab); + } + if (cancelKey0 != 0 && GetKeyDown(cancelKey0)) + { + currentKey = cancelKey0; + currentScheme = ControlScheme.Controller; + if (onKey != null) + { + onKey(mCurrentSelection, KeyCode.Escape); + } + Notify(mCurrentSelection, "OnKey", KeyCode.Escape); + } + if (cancelKey1 != 0 && GetKeyDown(cancelKey1)) + { + currentKey = cancelKey1; + currentScheme = ControlScheme.Controller; + if (onKey != null) + { + onKey(mCurrentSelection, KeyCode.Escape); + } + Notify(mCurrentSelection, "OnKey", KeyCode.Escape); + } + currentTouch = null; + currentKey = KeyCode.None; + } + + public void ProcessTouch(bool pressed, bool unpressed) + { + bool flag = currentScheme == ControlScheme.Mouse; + float num = (!flag) ? touchDragThreshold : mouseDragThreshold; + float num2 = (!flag) ? touchClickThreshold : mouseClickThreshold; + num *= num; + num2 *= num2; + if (pressed) + { + if (mTooltip != null) + { + ShowTooltip(val: false); + } + currentTouch.pressStarted = true; + if (onPress != null) + { + onPress(currentTouch.pressed, state: false); + } + Notify(currentTouch.pressed, "OnPress", false); + currentTouch.pressed = currentTouch.current; + currentTouch.dragged = currentTouch.current; + currentTouch.clickNotification = ClickNotification.BasedOnDelta; + currentTouch.totalDelta = Vector2.zero; + currentTouch.dragStarted = false; + if (onPress != null) + { + onPress(currentTouch.pressed, state: true); + } + Notify(currentTouch.pressed, "OnPress", true); + if (currentTouch.pressed != mCurrentSelection) + { + if (mTooltip != null) + { + ShowTooltip(val: false); + } + currentScheme = ControlScheme.Touch; + selectedObject = currentTouch.pressed; + } + } + else if (currentTouch.pressed != null && (currentTouch.delta.sqrMagnitude != 0f || currentTouch.current != currentTouch.last)) + { + currentTouch.totalDelta += currentTouch.delta; + float sqrMagnitude = currentTouch.totalDelta.sqrMagnitude; + bool flag2 = false; + if (!currentTouch.dragStarted && currentTouch.last != currentTouch.current) + { + currentTouch.dragStarted = true; + currentTouch.delta = currentTouch.totalDelta; + isDragging = true; + if (onDragStart != null) + { + onDragStart(currentTouch.dragged); + } + Notify(currentTouch.dragged, "OnDragStart", null); + if (onDragOver != null) + { + onDragOver(currentTouch.last, currentTouch.dragged); + } + Notify(currentTouch.last, "OnDragOver", currentTouch.dragged); + isDragging = false; + } + else if (!currentTouch.dragStarted && num < sqrMagnitude) + { + flag2 = true; + currentTouch.dragStarted = true; + currentTouch.delta = currentTouch.totalDelta; + } + if (currentTouch.dragStarted) + { + if (mTooltip != null) + { + ShowTooltip(val: false); + } + isDragging = true; + bool flag3 = currentTouch.clickNotification == ClickNotification.None; + if (flag2) + { + if (onDragStart != null) + { + onDragStart(currentTouch.dragged); + } + Notify(currentTouch.dragged, "OnDragStart", null); + if (onDragOver != null) + { + onDragOver(currentTouch.last, currentTouch.dragged); + } + Notify(currentTouch.current, "OnDragOver", currentTouch.dragged); + } + else if (currentTouch.last != currentTouch.current) + { + if (onDragStart != null) + { + onDragStart(currentTouch.dragged); + } + Notify(currentTouch.last, "OnDragOut", currentTouch.dragged); + if (onDragOver != null) + { + onDragOver(currentTouch.last, currentTouch.dragged); + } + Notify(currentTouch.current, "OnDragOver", currentTouch.dragged); + } + if (onDrag != null) + { + onDrag(currentTouch.dragged, currentTouch.delta); + } + Notify(currentTouch.dragged, "OnDrag", currentTouch.delta); + currentTouch.last = currentTouch.current; + isDragging = false; + if (flag3) + { + currentTouch.clickNotification = ClickNotification.None; + } + else if (currentTouch.clickNotification == ClickNotification.BasedOnDelta && num2 < sqrMagnitude) + { + currentTouch.clickNotification = ClickNotification.None; + } + } + } + if (unpressed) + { + currentTouch.pressStarted = false; + if (mTooltip != null) + { + ShowTooltip(val: false); + } + if (currentTouch.pressed != null) + { + if (currentTouch.dragStarted) + { + if (onDragOut != null) + { + onDragOut(currentTouch.last, currentTouch.dragged); + } + Notify(currentTouch.last, "OnDragOut", currentTouch.dragged); + if (onDragEnd != null) + { + onDragEnd(currentTouch.dragged); + } + Notify(currentTouch.dragged, "OnDragEnd", null); + } + if (onPress != null) + { + onPress(currentTouch.pressed, state: false); + } + Notify(currentTouch.pressed, "OnPress", false); + if (flag) + { + if (onHover != null) + { + onHover(currentTouch.current, state: true); + } + Notify(currentTouch.current, "OnHover", true); + } + mHover = currentTouch.current; + if (currentTouch.dragged == currentTouch.current || (currentScheme != ControlScheme.Controller && currentTouch.clickNotification != 0 && currentTouch.totalDelta.sqrMagnitude < num)) + { + if (currentTouch.pressed != mCurrentSelection) + { + mNextSelection = null; + mCurrentSelection = currentTouch.pressed; + if (onSelect != null) + { + onSelect(currentTouch.pressed, state: true); + } + Notify(currentTouch.pressed, "OnSelect", true); + } + else + { + mNextSelection = null; + mCurrentSelection = currentTouch.pressed; + } + if (currentTouch.clickNotification != 0 && currentTouch.pressed == currentTouch.current) + { + float time = RealTime.time; + if (onClick != null) + { + onClick(currentTouch.pressed); + } + Notify(currentTouch.pressed, "OnClick", null); + if (currentTouch.clickTime + 0.35f > time) + { + if (onDoubleClick != null) + { + onDoubleClick(currentTouch.pressed); + } + Notify(currentTouch.pressed, "OnDoubleClick", null); + } + currentTouch.clickTime = time; + } + } + else if (currentTouch.dragStarted) + { + if (onDrop != null) + { + onDrop(currentTouch.current, currentTouch.dragged); + } + Notify(currentTouch.current, "OnDrop", currentTouch.dragged); + } + } + currentTouch.dragStarted = false; + currentTouch.pressed = null; + currentTouch.dragged = null; + } + } + + public void ShowTooltip(bool val) + { + mTooltipTime = 0f; + if (onTooltip != null) + { + onTooltip(mTooltip, val); + } + Notify(mTooltip, "OnTooltip", val); + if (!val) + { + mTooltip = null; + } + } + + private void OnApplicationPause() + { + MouseOrTouch mouseOrTouch = currentTouch; + if (useTouch) + { + BetterList betterList = new BetterList(); + foreach (KeyValuePair mTouch in mTouches) + { + if (mTouch.Value != null && (bool)mTouch.Value.pressed) + { + currentTouch = mTouch.Value; + currentTouchID = mTouch.Key; + currentScheme = ControlScheme.Touch; + currentTouch.clickNotification = ClickNotification.None; + ProcessTouch(pressed: false, unpressed: true); + betterList.Add(currentTouchID); + } + } + for (int i = 0; i < betterList.size; i++) + { + RemoveTouch(betterList[i]); + } + } + if (useMouse) + { + for (int j = 0; j < 3; j++) + { + if ((bool)mMouse[j].pressed) + { + currentTouch = mMouse[j]; + currentTouchID = -1 - j; + currentKey = (KeyCode)(323 + j); + currentScheme = ControlScheme.Mouse; + currentTouch.clickNotification = ClickNotification.None; + ProcessTouch(pressed: false, unpressed: true); + } + } + } + if (useController && (bool)controller.pressed) + { + currentTouch = controller; + currentTouchID = -100; + currentScheme = ControlScheme.Controller; + currentTouch.last = currentTouch.current; + currentTouch.current = mCurrentSelection; + currentTouch.clickNotification = ClickNotification.None; + ProcessTouch(pressed: false, unpressed: true); + currentTouch.last = null; + } + currentTouch = mouseOrTouch; + } +} diff --git a/UICenterOnChild.cs b/UICenterOnChild.cs new file mode 100644 index 00000000..fc577854 --- /dev/null +++ b/UICenterOnChild.cs @@ -0,0 +1,193 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Center Scroll View on Child")] +public class UICenterOnChild : MonoBehaviour +{ + public delegate void OnCenterCallback(GameObject centeredObject); + + public float springStrength = 8f; + + public float nextPageThreshold; + + public SpringPanel.OnFinished onFinished; + + public OnCenterCallback onCenter; + + private UIScrollView mScrollView; + + private GameObject mCenteredObject; + + public GameObject centeredObject => mCenteredObject; + + private void Start() + { + Recenter(); + } + + private void OnEnable() + { + if ((bool)mScrollView) + { + mScrollView.centerOnChild = this; + Recenter(); + } + } + + private void OnDisable() + { + if ((bool)mScrollView) + { + mScrollView.centerOnChild = null; + } + } + + private void OnDragFinished() + { + if (base.enabled) + { + Recenter(); + } + } + + private void OnValidate() + { + nextPageThreshold = Mathf.Abs(nextPageThreshold); + } + + [ContextMenu("Execute")] + public void Recenter() + { + if (mScrollView == null) + { + mScrollView = NGUITools.FindInParents(base.gameObject); + if (mScrollView == null) + { + Debug.LogWarning(GetType() + " requires " + typeof(UIScrollView) + " on a parent object in order to work", this); + base.enabled = false; + return; + } + if ((bool)mScrollView) + { + mScrollView.centerOnChild = this; + mScrollView.onDragFinished = OnDragFinished; + } + if (mScrollView.horizontalScrollBar != null) + { + mScrollView.horizontalScrollBar.onDragFinished = OnDragFinished; + } + if (mScrollView.verticalScrollBar != null) + { + mScrollView.verticalScrollBar.onDragFinished = OnDragFinished; + } + } + if (!(mScrollView.panel == null)) + { + Transform transform = base.transform; + if (transform.childCount != 0) + { + Vector3[] worldCorners = mScrollView.panel.worldCorners; + Vector3 vector = (worldCorners[2] + worldCorners[0]) * 0.5f; + Vector3 velocity = mScrollView.currentMomentum * mScrollView.momentumAmount; + Vector3 a = NGUIMath.SpringDampen(ref velocity, 9f, 2f); + Vector3 b = vector - a * 0.01f; + float num = 3.40282347E+38f; + Transform target = null; + int num2 = 0; + int i = 0; + for (int childCount = transform.childCount; i < childCount; i++) + { + Transform child = transform.GetChild(i); + if (child.gameObject.activeInHierarchy) + { + float num3 = Vector3.SqrMagnitude(child.position - b); + if (num3 < num) + { + num = num3; + target = child; + num2 = i; + } + } + } + if (nextPageThreshold > 0f && UICamera.currentTouch != null && mCenteredObject != null && mCenteredObject.transform == transform.GetChild(num2)) + { + Vector2 totalDelta = UICamera.currentTouch.totalDelta; + float num4 = 0f; + switch (mScrollView.movement) + { + case UIScrollView.Movement.Horizontal: + num4 = totalDelta.x; + break; + case UIScrollView.Movement.Vertical: + num4 = totalDelta.y; + break; + default: + num4 = totalDelta.magnitude; + break; + } + if (Mathf.Abs(num4) > nextPageThreshold) + { + UIGrid component = GetComponent(); + if (component != null && component.sorting != 0) + { + List childList = component.GetChildList(); + if (num4 > nextPageThreshold) + { + target = ((num2 <= 0) ? childList[0] : childList[num2 - 1]); + } + else if (num4 < 0f - nextPageThreshold) + { + target = ((num2 >= childList.Count - 1) ? childList[childList.Count - 1] : childList[num2 + 1]); + } + } + else + { + Debug.LogWarning("Next Page Threshold requires a sorted UIGrid in order to work properly", this); + } + } + } + CenterOn(target, vector); + } + } + } + + private void CenterOn(Transform target, Vector3 panelCenter) + { + if (target != null && mScrollView != null && mScrollView.panel != null) + { + Transform cachedTransform = mScrollView.panel.cachedTransform; + mCenteredObject = target.gameObject; + Vector3 a = cachedTransform.InverseTransformPoint(target.position); + Vector3 b = cachedTransform.InverseTransformPoint(panelCenter); + Vector3 b2 = a - b; + if (!mScrollView.canMoveHorizontally) + { + b2.x = 0f; + } + if (!mScrollView.canMoveVertically) + { + b2.y = 0f; + } + b2.z = 0f; + SpringPanel.Begin(mScrollView.panel.cachedGameObject, cachedTransform.localPosition - b2, springStrength).onFinished = onFinished; + } + else + { + mCenteredObject = null; + } + if (onCenter != null) + { + onCenter(mCenteredObject); + } + } + + public void CenterOn(Transform target) + { + if (mScrollView != null && mScrollView.panel != null) + { + Vector3[] worldCorners = mScrollView.panel.worldCorners; + Vector3 panelCenter = (worldCorners[2] + worldCorners[0]) * 0.5f; + CenterOn(target, panelCenter); + } + } +} diff --git a/UICenterOnClick.cs b/UICenterOnClick.cs new file mode 100644 index 00000000..08c6313a --- /dev/null +++ b/UICenterOnClick.cs @@ -0,0 +1,34 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Center Scroll View on Click")] +public class UICenterOnClick : MonoBehaviour +{ + private void OnClick() + { + UICenterOnChild uICenterOnChild = NGUITools.FindInParents(base.gameObject); + UIPanel uIPanel = NGUITools.FindInParents(base.gameObject); + if (uICenterOnChild != null) + { + if (uICenterOnChild.enabled) + { + uICenterOnChild.CenterOn(base.transform); + } + } + else if (uIPanel != null && uIPanel.clipping != 0) + { + UIScrollView component = uIPanel.GetComponent(); + Vector3 pos = -uIPanel.cachedTransform.InverseTransformPoint(base.transform.position); + if (!component.canMoveHorizontally) + { + Vector3 localPosition = uIPanel.cachedTransform.localPosition; + pos.x = localPosition.x; + } + if (!component.canMoveVertically) + { + Vector3 localPosition2 = uIPanel.cachedTransform.localPosition; + pos.y = localPosition2.y; + } + SpringPanel.Begin(uIPanel.cachedGameObject, pos, 6f); + } + } +} diff --git a/UIDragCamera.cs b/UIDragCamera.cs new file mode 100644 index 00000000..6684149e --- /dev/null +++ b/UIDragCamera.cs @@ -0,0 +1,40 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Drag Camera")] +[ExecuteInEditMode] +public class UIDragCamera : MonoBehaviour +{ + public UIDraggableCamera draggableCamera; + + private void Awake() + { + if (draggableCamera == null) + { + draggableCamera = NGUITools.FindInParents(base.gameObject); + } + } + + private void OnPress(bool isPressed) + { + if (base.enabled && NGUITools.GetActive(base.gameObject) && draggableCamera != null) + { + draggableCamera.Press(isPressed); + } + } + + private void OnDrag(Vector2 delta) + { + if (base.enabled && NGUITools.GetActive(base.gameObject) && draggableCamera != null) + { + draggableCamera.Drag(delta); + } + } + + private void OnScroll(float delta) + { + if (base.enabled && NGUITools.GetActive(base.gameObject) && draggableCamera != null) + { + draggableCamera.Scroll(delta); + } + } +} diff --git a/UIDragDropContainer.cs b/UIDragDropContainer.cs new file mode 100644 index 00000000..ad9b4a01 --- /dev/null +++ b/UIDragDropContainer.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Drag and Drop Container")] +public class UIDragDropContainer : MonoBehaviour +{ + public Transform reparentTarget; + + protected virtual void Start() + { + if (reparentTarget == null) + { + reparentTarget = base.transform; + } + } +} diff --git a/UIDragDropItem.cs b/UIDragDropItem.cs new file mode 100644 index 00000000..e167e42a --- /dev/null +++ b/UIDragDropItem.cs @@ -0,0 +1,284 @@ +using System.Collections; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Drag and Drop Item")] +public class UIDragDropItem : MonoBehaviour +{ + public enum Restriction + { + None, + Horizontal, + Vertical, + PressAndHold + } + + public Restriction restriction; + + public bool cloneOnDrag; + + [HideInInspector] + public float pressAndHoldDelay = 1f; + + protected Transform mTrans; + + protected Transform mParent; + + protected Collider mCollider; + + protected Collider2D mCollider2D; + + protected UIButton mButton; + + protected UIRoot mRoot; + + protected UIGrid mGrid; + + protected UITable mTable; + + protected int mTouchID = -2147483648; + + protected float mDragStartTime; + + protected UIDragScrollView mDragScrollView; + + protected bool mPressed; + + protected bool mDragging; + + protected virtual void Start() + { + mTrans = base.transform; + mCollider = GetComponent(); + mCollider2D = GetComponent(); + mButton = GetComponent(); + mDragScrollView = GetComponent(); + } + + protected void OnPress(bool isPressed) + { + if (isPressed) + { + mDragStartTime = RealTime.time + pressAndHoldDelay; + mPressed = true; + } + else + { + mPressed = false; + } + } + + protected virtual void Update() + { + if (restriction == Restriction.PressAndHold && mPressed && !mDragging && mDragStartTime < RealTime.time) + { + StartDragging(); + } + } + + protected void OnDragStart() + { + if (base.enabled && mTouchID == -2147483648) + { + if (restriction != 0) + { + if (restriction == Restriction.Horizontal) + { + Vector2 totalDelta = UICamera.currentTouch.totalDelta; + if (Mathf.Abs(totalDelta.x) < Mathf.Abs(totalDelta.y)) + { + return; + } + } + else if (restriction == Restriction.Vertical) + { + Vector2 totalDelta2 = UICamera.currentTouch.totalDelta; + if (Mathf.Abs(totalDelta2.x) > Mathf.Abs(totalDelta2.y)) + { + return; + } + } + else if (restriction == Restriction.PressAndHold) + { + return; + } + } + StartDragging(); + } + } + + protected virtual void StartDragging() + { + if (!mDragging) + { + if (cloneOnDrag) + { + GameObject gameObject = NGUITools.AddChild(base.transform.parent.gameObject, base.gameObject); + gameObject.transform.localPosition = base.transform.localPosition; + gameObject.transform.localRotation = base.transform.localRotation; + gameObject.transform.localScale = base.transform.localScale; + UIButtonColor component = gameObject.GetComponent(); + if (component != null) + { + component.defaultColor = GetComponent().defaultColor; + } + UICamera.currentTouch.dragged = gameObject; + UIDragDropItem component2 = gameObject.GetComponent(); + component2.mDragging = true; + component2.Start(); + component2.OnDragDropStart(); + } + else + { + mDragging = true; + OnDragDropStart(); + } + } + } + + protected void OnDrag(Vector2 delta) + { + if (mDragging && base.enabled && mTouchID == UICamera.currentTouchID) + { + OnDragDropMove(delta * mRoot.pixelSizeAdjustment); + } + } + + protected void OnDragEnd() + { + if (base.enabled && mTouchID == UICamera.currentTouchID) + { + StopDragging(UICamera.hoveredObject); + } + } + + public void StopDragging(GameObject go) + { + if (mDragging) + { + mDragging = false; + OnDragDropRelease(go); + } + } + + protected virtual void OnDragDropStart() + { + if (mDragScrollView != null) + { + mDragScrollView.enabled = false; + } + if (mButton != null) + { + mButton.isEnabled = false; + } + else if (mCollider != null) + { + mCollider.enabled = false; + } + else if (mCollider2D != null) + { + mCollider2D.enabled = false; + } + mTouchID = UICamera.currentTouchID; + mParent = mTrans.parent; + mRoot = NGUITools.FindInParents(mParent); + mGrid = NGUITools.FindInParents(mParent); + mTable = NGUITools.FindInParents(mParent); + if (UIDragDropRoot.root != null) + { + mTrans.parent = UIDragDropRoot.root; + } + Vector3 localPosition = mTrans.localPosition; + localPosition.z = 0f; + mTrans.localPosition = localPosition; + TweenPosition component = GetComponent(); + if (component != null) + { + component.enabled = false; + } + SpringPosition component2 = GetComponent(); + if (component2 != null) + { + component2.enabled = false; + } + NGUITools.MarkParentAsChanged(base.gameObject); + if (mTable != null) + { + mTable.repositionNow = true; + } + if (mGrid != null) + { + mGrid.repositionNow = true; + } + } + + protected virtual void OnDragDropMove(Vector2 delta) + { + mTrans.localPosition += (Vector3)delta; + } + + protected virtual void OnDragDropRelease(GameObject surface) + { + if (!cloneOnDrag) + { + mTouchID = -2147483648; + if (mButton != null) + { + mButton.isEnabled = true; + } + else if (mCollider != null) + { + mCollider.enabled = true; + } + else if (mCollider2D != null) + { + mCollider2D.enabled = true; + } + UIDragDropContainer uIDragDropContainer = (!(bool)surface) ? null : NGUITools.FindInParents(surface); + if (uIDragDropContainer != null) + { + mTrans.parent = ((!(uIDragDropContainer.reparentTarget != null)) ? uIDragDropContainer.transform : uIDragDropContainer.reparentTarget); + Vector3 localPosition = mTrans.localPosition; + localPosition.z = 0f; + mTrans.localPosition = localPosition; + } + else + { + mTrans.parent = mParent; + } + mParent = mTrans.parent; + mGrid = NGUITools.FindInParents(mParent); + mTable = NGUITools.FindInParents(mParent); + if (mDragScrollView != null) + { + StartCoroutine(EnableDragScrollView()); + } + NGUITools.MarkParentAsChanged(base.gameObject); + if (mTable != null) + { + mTable.repositionNow = true; + } + if (mGrid != null) + { + mGrid.repositionNow = true; + } + OnDragDropEnd(); + } + else + { + NGUITools.Destroy(base.gameObject); + } + } + + protected virtual void OnDragDropEnd() + { + } + + protected IEnumerator EnableDragScrollView() + { + yield return (object)new WaitForEndOfFrame(); + if (mDragScrollView != null) + { + mDragScrollView.enabled = true; + } + } +} diff --git a/UIDragDropRoot.cs b/UIDragDropRoot.cs new file mode 100644 index 00000000..a7ab49df --- /dev/null +++ b/UIDragDropRoot.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Drag and Drop Root")] +public class UIDragDropRoot : MonoBehaviour +{ + public static Transform root; + + private void OnEnable() + { + root = base.transform; + } + + private void OnDisable() + { + if (root == base.transform) + { + root = null; + } + } +} diff --git a/UIDragObject.cs b/UIDragObject.cs new file mode 100644 index 00000000..d14d4d9c --- /dev/null +++ b/UIDragObject.cs @@ -0,0 +1,291 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Drag Object")] +[ExecuteInEditMode] +public class UIDragObject : MonoBehaviour +{ + public enum DragEffect + { + None, + Momentum, + MomentumAndSpring + } + + public Transform target; + + public UIPanel panelRegion; + + public Vector3 scrollMomentum = Vector3.zero; + + public bool restrictWithinPanel; + + public UIRect contentRect; + + public DragEffect dragEffect = DragEffect.MomentumAndSpring; + + public float momentumAmount = 35f; + + [SerializeField] + protected Vector3 scale = new Vector3(1f, 1f, 0f); + + [HideInInspector] + [SerializeField] + private float scrollWheelFactor; + + private Plane mPlane; + + private Vector3 mTargetPos; + + private Vector3 mLastPos; + + private Vector3 mMomentum = Vector3.zero; + + private Vector3 mScroll = Vector3.zero; + + private Bounds mBounds; + + private int mTouchID; + + private bool mStarted; + + private bool mPressed; + + public Vector3 dragMovement + { + get + { + return scale; + } + set + { + scale = value; + } + } + + private void OnEnable() + { + if (scrollWheelFactor != 0f) + { + scrollMomentum = scale * scrollWheelFactor; + scrollWheelFactor = 0f; + } + if (contentRect == null && target != null && Application.isPlaying) + { + UIWidget component = target.GetComponent(); + if (component != null) + { + contentRect = component; + } + } + } + + private void OnDisable() + { + mStarted = false; + } + + private void FindPanel() + { + panelRegion = ((!(target != null)) ? null : UIPanel.Find(target.transform.parent)); + if (panelRegion == null) + { + restrictWithinPanel = false; + } + } + + private void UpdateBounds() + { + if ((bool)contentRect) + { + Transform cachedTransform = panelRegion.cachedTransform; + Matrix4x4 worldToLocalMatrix = cachedTransform.worldToLocalMatrix; + Vector3[] worldCorners = contentRect.worldCorners; + for (int i = 0; i < 4; i++) + { + worldCorners[i] = worldToLocalMatrix.MultiplyPoint3x4(worldCorners[i]); + } + mBounds = new Bounds(worldCorners[0], Vector3.zero); + for (int j = 1; j < 4; j++) + { + mBounds.Encapsulate(worldCorners[j]); + } + } + else + { + mBounds = NGUIMath.CalculateRelativeWidgetBounds(panelRegion.cachedTransform, target); + } + } + + private void OnPress(bool pressed) + { + if (base.enabled && NGUITools.GetActive(base.gameObject) && target != null) + { + if (pressed) + { + if (!mPressed) + { + mTouchID = UICamera.currentTouchID; + mPressed = true; + mStarted = false; + CancelMovement(); + if (restrictWithinPanel && panelRegion == null) + { + FindPanel(); + } + if (restrictWithinPanel) + { + UpdateBounds(); + } + CancelSpring(); + Transform transform = UICamera.currentCamera.transform; + mPlane = new Plane(((!(panelRegion != null)) ? transform.rotation : panelRegion.cachedTransform.rotation) * Vector3.back, UICamera.lastWorldPosition); + } + } + else if (mPressed && mTouchID == UICamera.currentTouchID) + { + mPressed = false; + if (restrictWithinPanel && dragEffect == DragEffect.MomentumAndSpring && panelRegion.ConstrainTargetToBounds(target, ref mBounds, immediate: false)) + { + CancelMovement(); + } + } + } + } + + private void OnDrag(Vector2 delta) + { + if (mPressed && mTouchID == UICamera.currentTouchID && base.enabled && NGUITools.GetActive(base.gameObject) && target != null) + { + UICamera.currentTouch.clickNotification = UICamera.ClickNotification.BasedOnDelta; + Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos); + float enter = 0f; + if (mPlane.Raycast(ray, out enter)) + { + Vector3 point = ray.GetPoint(enter); + Vector3 vector = point - mLastPos; + mLastPos = point; + if (!mStarted) + { + mStarted = true; + vector = Vector3.zero; + } + if (vector.x != 0f || vector.y != 0f) + { + vector = target.InverseTransformDirection(vector); + vector.Scale(scale); + vector = target.TransformDirection(vector); + } + if (dragEffect != 0) + { + mMomentum = Vector3.Lerp(mMomentum, mMomentum + vector * (0.01f * momentumAmount), 0.67f); + } + Vector3 localPosition = target.localPosition; + Move(vector); + if (restrictWithinPanel) + { + mBounds.center += target.localPosition - localPosition; + if (dragEffect != DragEffect.MomentumAndSpring && panelRegion.ConstrainTargetToBounds(target, ref mBounds, immediate: true)) + { + CancelMovement(); + } + } + } + } + } + + private void Move(Vector3 worldDelta) + { + if (panelRegion != null) + { + mTargetPos += worldDelta; + target.position = mTargetPos; + Vector3 localPosition = target.localPosition; + localPosition.x = Mathf.Round(localPosition.x); + localPosition.y = Mathf.Round(localPosition.y); + target.localPosition = localPosition; + UIScrollView component = panelRegion.GetComponent(); + if (component != null) + { + component.UpdateScrollbars(recalculateBounds: true); + } + } + else + { + target.position += worldDelta; + } + } + + private void LateUpdate() + { + if (!(target == null)) + { + float deltaTime = RealTime.deltaTime; + mMomentum -= mScroll; + mScroll = NGUIMath.SpringLerp(mScroll, Vector3.zero, 20f, deltaTime); + if (!(mMomentum.magnitude < 0.0001f)) + { + if (!mPressed) + { + if (panelRegion == null) + { + FindPanel(); + } + Move(NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime)); + if (restrictWithinPanel && panelRegion != null) + { + UpdateBounds(); + if (panelRegion.ConstrainTargetToBounds(target, ref mBounds, dragEffect == DragEffect.None)) + { + CancelMovement(); + } + else + { + CancelSpring(); + } + } + NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime); + if (mMomentum.magnitude < 0.0001f) + { + CancelMovement(); + } + } + else + { + NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime); + } + } + } + } + + public void CancelMovement() + { + if (target != null) + { + Vector3 localPosition = target.localPosition; + localPosition.x = (float)Mathf.RoundToInt(localPosition.x); + localPosition.y = (float)Mathf.RoundToInt(localPosition.y); + localPosition.z = (float)Mathf.RoundToInt(localPosition.z); + target.localPosition = localPosition; + } + mTargetPos = ((!(target != null)) ? Vector3.zero : target.position); + mMomentum = Vector3.zero; + mScroll = Vector3.zero; + } + + public void CancelSpring() + { + SpringPosition component = target.GetComponent(); + if (component != null) + { + component.enabled = false; + } + } + + private void OnScroll(float delta) + { + if (base.enabled && NGUITools.GetActive(base.gameObject)) + { + mScroll -= scrollMomentum * (delta * 0.05f); + } + } +} diff --git a/UIDragResize.cs b/UIDragResize.cs new file mode 100644 index 00000000..acd7fe04 --- /dev/null +++ b/UIDragResize.cs @@ -0,0 +1,72 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Drag-Resize Widget")] +public class UIDragResize : MonoBehaviour +{ + public UIWidget target; + + public UIWidget.Pivot pivot = UIWidget.Pivot.BottomRight; + + public int minWidth = 100; + + public int minHeight = 100; + + public int maxWidth = 100000; + + public int maxHeight = 100000; + + private Plane mPlane; + + private Vector3 mRayPos; + + private Vector3 mLocalPos; + + private int mWidth; + + private int mHeight; + + private bool mDragging; + + private void OnDragStart() + { + if (target != null) + { + Vector3[] worldCorners = target.worldCorners; + mPlane = new Plane(worldCorners[0], worldCorners[1], worldCorners[3]); + Ray currentRay = UICamera.currentRay; + if (mPlane.Raycast(currentRay, out float enter)) + { + mRayPos = currentRay.GetPoint(enter); + mLocalPos = target.cachedTransform.localPosition; + mWidth = target.width; + mHeight = target.height; + mDragging = true; + } + } + } + + private void OnDrag(Vector2 delta) + { + if (mDragging && target != null) + { + Ray currentRay = UICamera.currentRay; + if (mPlane.Raycast(currentRay, out float enter)) + { + Transform cachedTransform = target.cachedTransform; + cachedTransform.localPosition = mLocalPos; + target.width = mWidth; + target.height = mHeight; + Vector3 vector = currentRay.GetPoint(enter) - mRayPos; + cachedTransform.position += vector; + Vector3 vector2 = Quaternion.Inverse(cachedTransform.localRotation) * (cachedTransform.localPosition - mLocalPos); + cachedTransform.localPosition = mLocalPos; + NGUIMath.ResizeWidget(target, pivot, vector2.x, vector2.y, minWidth, minHeight, maxWidth, maxHeight); + } + } + } + + private void OnDragEnd() + { + mDragging = false; + } +} diff --git a/UIDragScrollView.cs b/UIDragScrollView.cs new file mode 100644 index 00000000..3098459f --- /dev/null +++ b/UIDragScrollView.cs @@ -0,0 +1,88 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Drag Scroll View")] +public class UIDragScrollView : MonoBehaviour +{ + public UIScrollView scrollView; + + [HideInInspector] + [SerializeField] + private UIScrollView draggablePanel; + + private Transform mTrans; + + private UIScrollView mScroll; + + private bool mAutoFind; + + private bool mStarted; + + private void OnEnable() + { + mTrans = base.transform; + if (scrollView == null && draggablePanel != null) + { + scrollView = draggablePanel; + draggablePanel = null; + } + if (mStarted && (mAutoFind || mScroll == null)) + { + FindScrollView(); + } + } + + private void Start() + { + mStarted = true; + FindScrollView(); + } + + private void FindScrollView() + { + UIScrollView y = NGUITools.FindInParents(mTrans); + if (scrollView == null) + { + scrollView = y; + mAutoFind = true; + } + else if (scrollView == y) + { + mAutoFind = true; + } + mScroll = scrollView; + } + + private void OnPress(bool pressed) + { + if (mAutoFind && mScroll != scrollView) + { + mScroll = scrollView; + mAutoFind = false; + } + if ((bool)scrollView && base.enabled && NGUITools.GetActive(base.gameObject)) + { + scrollView.Press(pressed); + if (!pressed && mAutoFind) + { + scrollView = NGUITools.FindInParents(mTrans); + mScroll = scrollView; + } + } + } + + private void OnDrag(Vector2 delta) + { + if ((bool)scrollView && NGUITools.GetActive(this)) + { + scrollView.Drag(); + } + } + + private void OnScroll(float delta) + { + if ((bool)scrollView && NGUITools.GetActive(this)) + { + scrollView.Scroll(delta); + } + } +} diff --git a/UIDraggableCamera.cs b/UIDraggableCamera.cs new file mode 100644 index 00000000..0def53ce --- /dev/null +++ b/UIDraggableCamera.cs @@ -0,0 +1,200 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Draggable Camera")] +[RequireComponent(typeof(Camera))] +public class UIDraggableCamera : MonoBehaviour +{ + public Transform rootForBounds; + + public Vector2 scale = Vector2.one; + + public float scrollWheelFactor; + + public UIDragObject.DragEffect dragEffect = UIDragObject.DragEffect.MomentumAndSpring; + + public bool smoothDragStart = true; + + public float momentumAmount = 35f; + + private Camera mCam; + + private Transform mTrans; + + private bool mPressed; + + private Vector2 mMomentum = Vector2.zero; + + private Bounds mBounds; + + private float mScroll; + + private UIRoot mRoot; + + private bool mDragStarted; + + public Vector2 currentMomentum + { + get + { + return mMomentum; + } + set + { + mMomentum = value; + } + } + + private void Start() + { + mCam = GetComponent(); + mTrans = base.transform; + mRoot = NGUITools.FindInParents(base.gameObject); + if (rootForBounds == null) + { + Debug.LogError(NGUITools.GetHierarchy(base.gameObject) + " needs the 'Root For Bounds' parameter to be set", this); + base.enabled = false; + } + } + + private Vector3 CalculateConstrainOffset() + { + if (rootForBounds == null || rootForBounds.childCount == 0) + { + return Vector3.zero; + } + Vector3 position = new Vector3(mCam.rect.xMin * (float)Screen.width, mCam.rect.yMin * (float)Screen.height, 0f); + Vector3 position2 = new Vector3(mCam.rect.xMax * (float)Screen.width, mCam.rect.yMax * (float)Screen.height, 0f); + position = mCam.ScreenToWorldPoint(position); + position2 = mCam.ScreenToWorldPoint(position2); + Vector3 min = mBounds.min; + float x = min.x; + Vector3 min2 = mBounds.min; + Vector2 minRect = new Vector2(x, min2.y); + Vector3 max = mBounds.max; + float x2 = max.x; + Vector3 max2 = mBounds.max; + Vector2 maxRect = new Vector2(x2, max2.y); + return NGUIMath.ConstrainRect(minRect, maxRect, position, position2); + } + + public bool ConstrainToBounds(bool immediate) + { + if (mTrans != null && rootForBounds != null) + { + Vector3 vector = CalculateConstrainOffset(); + if (vector.sqrMagnitude > 0f) + { + if (immediate) + { + mTrans.position -= vector; + } + else + { + SpringPosition springPosition = SpringPosition.Begin(base.gameObject, mTrans.position - vector, 13f); + springPosition.ignoreTimeScale = true; + springPosition.worldSpace = true; + } + return true; + } + } + return false; + } + + public void Press(bool isPressed) + { + if (isPressed) + { + mDragStarted = false; + } + if (rootForBounds != null) + { + mPressed = isPressed; + if (isPressed) + { + mBounds = NGUIMath.CalculateAbsoluteWidgetBounds(rootForBounds); + mMomentum = Vector2.zero; + mScroll = 0f; + SpringPosition component = GetComponent(); + if (component != null) + { + component.enabled = false; + } + } + else if (dragEffect == UIDragObject.DragEffect.MomentumAndSpring) + { + ConstrainToBounds(immediate: false); + } + } + } + + public void Drag(Vector2 delta) + { + if (smoothDragStart && !mDragStarted) + { + mDragStarted = true; + } + else + { + UICamera.currentTouch.clickNotification = UICamera.ClickNotification.BasedOnDelta; + if (mRoot != null) + { + delta *= mRoot.pixelSizeAdjustment; + } + Vector2 vector = Vector2.Scale(delta, -scale); + mTrans.localPosition += (Vector3)vector; + mMomentum = Vector2.Lerp(mMomentum, mMomentum + vector * (0.01f * momentumAmount), 0.67f); + if (dragEffect != UIDragObject.DragEffect.MomentumAndSpring && ConstrainToBounds(immediate: true)) + { + mMomentum = Vector2.zero; + mScroll = 0f; + } + } + } + + public void Scroll(float delta) + { + if (base.enabled && NGUITools.GetActive(base.gameObject)) + { + if (Mathf.Sign(mScroll) != Mathf.Sign(delta)) + { + mScroll = 0f; + } + mScroll += delta * scrollWheelFactor; + } + } + + private void Update() + { + float deltaTime = RealTime.deltaTime; + if (mPressed) + { + SpringPosition component = GetComponent(); + if (component != null) + { + component.enabled = false; + } + mScroll = 0f; + } + else + { + mMomentum += scale * (mScroll * 20f); + mScroll = NGUIMath.SpringLerp(mScroll, 0f, 20f, deltaTime); + if (mMomentum.magnitude > 0.01f) + { + mTrans.localPosition += (Vector3)NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime); + mBounds = NGUIMath.CalculateAbsoluteWidgetBounds(rootForBounds); + if (!ConstrainToBounds(dragEffect == UIDragObject.DragEffect.None)) + { + SpringPosition component2 = GetComponent(); + if (component2 != null) + { + component2.enabled = false; + } + } + return; + } + mScroll = 0f; + } + NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime); + } +} diff --git a/UIDrawCall.cs b/UIDrawCall.cs new file mode 100644 index 00000000..e7e6dbb1 --- /dev/null +++ b/UIDrawCall.cs @@ -0,0 +1,736 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Internal/Draw Call")] +[ExecuteInEditMode] +public class UIDrawCall : MonoBehaviour +{ + public enum Clipping + { + None = 0, + TextureMask = 1, + SoftClip = 3, + ConstrainButDontClip = 4 + } + + public delegate void OnRenderCallback(Material mat); + + private const int maxIndexBufferCache = 10; + + private static BetterList mActiveList = new BetterList(); + + private static BetterList mInactiveList = new BetterList(); + + [HideInInspector] + [NonSerialized] + public int widgetCount; + + [HideInInspector] + [NonSerialized] + public int depthStart = 2147483647; + + [HideInInspector] + [NonSerialized] + public int depthEnd = -2147483648; + + [HideInInspector] + [NonSerialized] + public UIPanel manager; + + [HideInInspector] + [NonSerialized] + public UIPanel panel; + + [HideInInspector] + [NonSerialized] + public Texture2D clipTexture; + + [HideInInspector] + [NonSerialized] + public bool alwaysOnScreen; + + [HideInInspector] + [NonSerialized] + public BetterList verts = new BetterList(); + + [HideInInspector] + [NonSerialized] + public BetterList norms = new BetterList(); + + [HideInInspector] + [NonSerialized] + public BetterList tans = new BetterList(); + + [HideInInspector] + [NonSerialized] + public BetterList uvs = new BetterList(); + + [HideInInspector] + [NonSerialized] + public BetterList cols = new BetterList(); + + private Material mMaterial; + + private Texture mTexture; + + private Shader mShader; + + private int mClipCount; + + private Transform mTrans; + + private Mesh mMesh; + + private MeshFilter mFilter; + + private MeshRenderer mRenderer; + + private Material mDynamicMat; + + private int[] mIndices; + + private bool mRebuildMat = true; + + private bool mLegacyShader; + + private int mRenderQueue = 3000; + + private int mTriangles; + + [NonSerialized] + public bool isDirty; + + [NonSerialized] + private bool mTextureClip; + + public OnRenderCallback onRender; + + private static List mCache = new List(10); + + private static int[] ClipRange = new int[4] + { + Shader.PropertyToID("_ClipRange0"), + Shader.PropertyToID("_ClipRange1"), + Shader.PropertyToID("_ClipRange2"), + Shader.PropertyToID("_ClipRange4") + }; + + private static int[] ClipArgs = new int[4] + { + Shader.PropertyToID("_ClipArgs0"), + Shader.PropertyToID("_ClipArgs1"), + Shader.PropertyToID("_ClipArgs2"), + Shader.PropertyToID("_ClipArgs3") + }; + + [Obsolete("Use UIDrawCall.activeList")] + public static BetterList list + { + get + { + return mActiveList; + } + } + + public static BetterList activeList => mActiveList; + + public static BetterList inactiveList => mInactiveList; + + public int renderQueue + { + get + { + return mRenderQueue; + } + set + { + if (mRenderQueue != value) + { + mRenderQueue = value; + if (mDynamicMat != null) + { + mDynamicMat.renderQueue = value; + } + } + } + } + + public int sortingOrder + { + get + { + return (mRenderer != null) ? mRenderer.sortingOrder : 0; + } + set + { + if (mRenderer != null && mRenderer.sortingOrder != value) + { + mRenderer.sortingOrder = value; + } + } + } + + public int finalRenderQueue => (!(mDynamicMat != null)) ? mRenderQueue : mDynamicMat.renderQueue; + + public Transform cachedTransform + { + get + { + if (mTrans == null) + { + mTrans = base.transform; + } + return mTrans; + } + } + + public Material baseMaterial + { + get + { + return mMaterial; + } + set + { + if (mMaterial != value) + { + mMaterial = value; + mRebuildMat = true; + } + } + } + + public Material dynamicMaterial => mDynamicMat; + + public Texture mainTexture + { + get + { + return mTexture; + } + set + { + mTexture = value; + if (mDynamicMat != null) + { + mDynamicMat.mainTexture = value; + } + } + } + + public Shader shader + { + get + { + return mShader; + } + set + { + if (mShader != value) + { + mShader = value; + mRebuildMat = true; + } + } + } + + public int triangles => (mMesh != null) ? mTriangles : 0; + + public bool isClipped => mClipCount != 0; + + private void CreateMaterial() + { + mTextureClip = false; + mLegacyShader = false; + mClipCount = panel.clipCount; + string text = (mShader != null) ? mShader.name : ((!(mMaterial != null)) ? "Unlit/Transparent Colored" : mMaterial.shader.name); + text = text.Replace("GUI/Text Shader", "Unlit/Text"); + if (text.Length > 2 && text[text.Length - 2] == ' ') + { + int num = text[text.Length - 1]; + if (num > 48 && num <= 57) + { + text = text.Substring(0, text.Length - 2); + } + } + if (text.StartsWith("Hidden/")) + { + text = text.Substring(7); + } + text = text.Replace(" (SoftClip)", string.Empty); + text = text.Replace(" (TextureClip)", string.Empty); + if (panel.clipping == Clipping.TextureMask) + { + mTextureClip = true; + shader = Shader.Find("Hidden/" + text + " (TextureClip)"); + } + else if (mClipCount != 0) + { + shader = Shader.Find("Hidden/" + text + " " + mClipCount); + if (shader == null) + { + shader = Shader.Find(text + " " + mClipCount); + } + if (shader == null && mClipCount == 1) + { + mLegacyShader = true; + shader = Shader.Find(text + " (SoftClip)"); + } + } + else + { + shader = Shader.Find(text); + } + if (mMaterial != null) + { + mDynamicMat = new Material(mMaterial); + mDynamicMat.name = "[NGUI] " + mMaterial.name; + mDynamicMat.hideFlags = (HideFlags.DontSaveInEditor | HideFlags.NotEditable | HideFlags.DontSaveInBuild | HideFlags.DontUnloadUnusedAsset); + mDynamicMat.CopyPropertiesFromMaterial(mMaterial); + string[] shaderKeywords = mMaterial.shaderKeywords; + for (int i = 0; i < shaderKeywords.Length; i++) + { + mDynamicMat.EnableKeyword(shaderKeywords[i]); + } + if (shader != null) + { + mDynamicMat.shader = shader; + } + else if (mClipCount != 0) + { + Debug.LogError(text + " shader doesn't have a clipped shader version for " + mClipCount + " clip regions"); + } + } + else + { + mDynamicMat = new Material(shader); + mDynamicMat.name = "[NGUI] " + shader.name; + mDynamicMat.hideFlags = (HideFlags.DontSaveInEditor | HideFlags.NotEditable | HideFlags.DontSaveInBuild | HideFlags.DontUnloadUnusedAsset); + } + } + + private Material RebuildMaterial() + { + NGUITools.DestroyImmediate(mDynamicMat); + CreateMaterial(); + mDynamicMat.renderQueue = mRenderQueue; + if (mTexture != null) + { + mDynamicMat.mainTexture = mTexture; + } + if (mRenderer != null) + { + mRenderer.sharedMaterials = new Material[1] + { + mDynamicMat + }; + } + return mDynamicMat; + } + + private void UpdateMaterials() + { + if (mRebuildMat || mDynamicMat == null || mClipCount != panel.clipCount || mTextureClip != (panel.clipping == Clipping.TextureMask)) + { + RebuildMaterial(); + mRebuildMat = false; + } + else if (mRenderer.sharedMaterial != mDynamicMat) + { + mRenderer.sharedMaterials = new Material[1] + { + mDynamicMat + }; + } + } + + public void UpdateGeometry(int widgetCount) + { + this.widgetCount = widgetCount; + int size = verts.size; + if (size > 0 && size == uvs.size && size == cols.size && size % 4 == 0) + { + if (mFilter == null) + { + mFilter = base.gameObject.GetComponent(); + } + if (mFilter == null) + { + mFilter = base.gameObject.AddComponent(); + } + if (verts.size < 65000) + { + int num = (size >> 1) * 3; + bool flag = mIndices == null || mIndices.Length != num; + if (mMesh == null) + { + mMesh = new Mesh(); + mMesh.hideFlags = HideFlags.DontSave; + mMesh.name = ((!(mMaterial != null)) ? "[NGUI] Mesh" : ("[NGUI] " + mMaterial.name)); + mMesh.MarkDynamic(); + flag = true; + } + bool flag2 = uvs.buffer.Length != verts.buffer.Length || cols.buffer.Length != verts.buffer.Length || (norms.buffer != null && norms.buffer.Length != verts.buffer.Length) || (tans.buffer != null && tans.buffer.Length != verts.buffer.Length); + if (!flag2 && panel.renderQueue != 0) + { + flag2 = (mMesh == null || mMesh.vertexCount != verts.buffer.Length); + } + if (!flag2 && verts.size << 1 < verts.buffer.Length) + { + flag2 = true; + } + mTriangles = verts.size >> 1; + if (flag2 || verts.buffer.Length > 65000) + { + if (flag2 || mMesh.vertexCount != verts.size) + { + mMesh.Clear(); + flag = true; + } + mMesh.vertices = verts.ToArray(); + mMesh.uv = uvs.ToArray(); + mMesh.colors32 = cols.ToArray(); + if (norms != null) + { + mMesh.normals = norms.ToArray(); + } + if (tans != null) + { + mMesh.tangents = tans.ToArray(); + } + } + else + { + if (mMesh.vertexCount != verts.buffer.Length) + { + mMesh.Clear(); + flag = true; + } + mMesh.vertices = verts.buffer; + mMesh.uv = uvs.buffer; + mMesh.colors32 = cols.buffer; + if (norms != null) + { + mMesh.normals = norms.buffer; + } + if (tans != null) + { + mMesh.tangents = tans.buffer; + } + } + if (flag) + { + mIndices = GenerateCachedIndexBuffer(size, num); + mMesh.triangles = mIndices; + } + if (flag2 || !alwaysOnScreen) + { + mMesh.RecalculateBounds(); + } + mFilter.mesh = mMesh; + } + else + { + mTriangles = 0; + if (mFilter.mesh != null) + { + mFilter.mesh.Clear(); + } + Debug.LogError("Too many vertices on one panel: " + verts.size); + } + if (mRenderer == null) + { + mRenderer = base.gameObject.GetComponent(); + } + if (mRenderer == null) + { + mRenderer = base.gameObject.AddComponent(); + } + UpdateMaterials(); + } + else + { + if (mFilter.mesh != null) + { + mFilter.mesh.Clear(); + } + Debug.LogError("UIWidgets must fill the buffer with 4 vertices per quad. Found " + size); + } + verts.Clear(); + uvs.Clear(); + cols.Clear(); + norms.Clear(); + tans.Clear(); + } + + private int[] GenerateCachedIndexBuffer(int vertexCount, int indexCount) + { + int i = 0; + for (int count = mCache.Count; i < count; i++) + { + int[] array = mCache[i]; + if (array != null && array.Length == indexCount) + { + return array; + } + } + int[] array2 = new int[indexCount]; + int num = 0; + for (int j = 0; j < vertexCount; j += 4) + { + array2[num++] = j; + array2[num++] = j + 1; + array2[num++] = j + 2; + array2[num++] = j + 2; + array2[num++] = j + 3; + array2[num++] = j; + } + if (mCache.Count > 10) + { + mCache.RemoveAt(0); + } + mCache.Add(array2); + return array2; + } + + private void OnWillRenderObject() + { + UpdateMaterials(); + if (onRender != null) + { + onRender(mDynamicMat ?? mMaterial); + } + if (!(mDynamicMat == null) && mClipCount != 0) + { + if (mTextureClip) + { + Vector4 drawCallClipRange = panel.drawCallClipRange; + Vector2 clipSoftness = panel.clipSoftness; + Vector2 vector = new Vector2(1000f, 1000f); + if (clipSoftness.x > 0f) + { + vector.x = drawCallClipRange.z / clipSoftness.x; + } + if (clipSoftness.y > 0f) + { + vector.y = drawCallClipRange.w / clipSoftness.y; + } + mDynamicMat.SetVector(ClipRange[0], new Vector4((0f - drawCallClipRange.x) / drawCallClipRange.z, (0f - drawCallClipRange.y) / drawCallClipRange.w, 1f / drawCallClipRange.z, 1f / drawCallClipRange.w)); + mDynamicMat.SetTexture("_ClipTex", clipTexture); + } + else if (!mLegacyShader) + { + UIPanel parentPanel = panel; + int num = 0; + while (parentPanel != null) + { + if (parentPanel.hasClipping) + { + float angle = 0f; + Vector4 drawCallClipRange2 = parentPanel.drawCallClipRange; + if (parentPanel != panel) + { + Vector3 vector2 = parentPanel.cachedTransform.InverseTransformPoint(panel.cachedTransform.position); + drawCallClipRange2.x -= vector2.x; + drawCallClipRange2.y -= vector2.y; + Vector3 eulerAngles = panel.cachedTransform.rotation.eulerAngles; + Vector3 eulerAngles2 = parentPanel.cachedTransform.rotation.eulerAngles; + Vector3 vector3 = eulerAngles2 - eulerAngles; + vector3.x = NGUIMath.WrapAngle(vector3.x); + vector3.y = NGUIMath.WrapAngle(vector3.y); + vector3.z = NGUIMath.WrapAngle(vector3.z); + if (Mathf.Abs(vector3.x) > 0.001f || Mathf.Abs(vector3.y) > 0.001f) + { + Debug.LogWarning("Panel can only be clipped properly if X and Y rotation is left at 0", panel); + } + angle = vector3.z; + } + SetClipping(num++, drawCallClipRange2, parentPanel.clipSoftness, angle); + } + parentPanel = parentPanel.parentPanel; + } + } + else + { + Vector2 clipSoftness2 = panel.clipSoftness; + Vector4 drawCallClipRange3 = panel.drawCallClipRange; + Vector2 mainTextureOffset = new Vector2((0f - drawCallClipRange3.x) / drawCallClipRange3.z, (0f - drawCallClipRange3.y) / drawCallClipRange3.w); + Vector2 mainTextureScale = new Vector2(1f / drawCallClipRange3.z, 1f / drawCallClipRange3.w); + Vector2 v = new Vector2(1000f, 1000f); + if (clipSoftness2.x > 0f) + { + v.x = drawCallClipRange3.z / clipSoftness2.x; + } + if (clipSoftness2.y > 0f) + { + v.y = drawCallClipRange3.w / clipSoftness2.y; + } + mDynamicMat.mainTextureOffset = mainTextureOffset; + mDynamicMat.mainTextureScale = mainTextureScale; + mDynamicMat.SetVector("_ClipSharpness", v); + } + } + } + + private void SetClipping(int index, Vector4 cr, Vector2 soft, float angle) + { + angle *= -0.0174532924f; + Vector2 vector = new Vector2(1000f, 1000f); + if (soft.x > 0f) + { + vector.x = cr.z / soft.x; + } + if (soft.y > 0f) + { + vector.y = cr.w / soft.y; + } + if (index < ClipRange.Length) + { + mDynamicMat.SetVector(ClipRange[index], new Vector4((0f - cr.x) / cr.z, (0f - cr.y) / cr.w, 1f / cr.z, 1f / cr.w)); + mDynamicMat.SetVector(ClipArgs[index], new Vector4(vector.x, vector.y, Mathf.Sin(angle), Mathf.Cos(angle))); + } + } + + private void OnEnable() + { + mRebuildMat = true; + } + + private void OnDisable() + { + depthStart = 2147483647; + depthEnd = -2147483648; + panel = null; + manager = null; + mMaterial = null; + mTexture = null; + clipTexture = null; + if (mRenderer != null) + { + mRenderer.sharedMaterials = new Material[0]; + } + NGUITools.DestroyImmediate(mDynamicMat); + mDynamicMat = null; + } + + private void OnDestroy() + { + NGUITools.DestroyImmediate(mMesh); + mMesh = null; + } + + public static UIDrawCall Create(UIPanel panel, Material mat, Texture tex, Shader shader) + { + return Create(null, panel, mat, tex, shader); + } + + private static UIDrawCall Create(string name, UIPanel pan, Material mat, Texture tex, Shader shader) + { + UIDrawCall uIDrawCall = Create(name); + uIDrawCall.gameObject.layer = pan.cachedGameObject.layer; + uIDrawCall.baseMaterial = mat; + uIDrawCall.mainTexture = tex; + uIDrawCall.shader = shader; + uIDrawCall.renderQueue = pan.startingRenderQueue; + uIDrawCall.sortingOrder = pan.sortingOrder; + uIDrawCall.manager = pan; + return uIDrawCall; + } + + private static UIDrawCall Create(string name) + { + if (mInactiveList.size > 0) + { + UIDrawCall uIDrawCall = mInactiveList.Pop(); + mActiveList.Add(uIDrawCall); + if (name != null) + { + uIDrawCall.name = name; + } + NGUITools.SetActive(uIDrawCall.gameObject, state: true); + return uIDrawCall; + } + GameObject gameObject = new GameObject(name); + UnityEngine.Object.DontDestroyOnLoad(gameObject); + UIDrawCall uIDrawCall2 = gameObject.AddComponent(); + mActiveList.Add(uIDrawCall2); + return uIDrawCall2; + } + + public static void ClearAll() + { + bool isPlaying = Application.isPlaying; + int num = mActiveList.size; + while (num > 0) + { + UIDrawCall uIDrawCall = mActiveList[--num]; + if ((bool)uIDrawCall) + { + if (isPlaying) + { + NGUITools.SetActive(uIDrawCall.gameObject, state: false); + } + else + { + NGUITools.DestroyImmediate(uIDrawCall.gameObject); + } + } + } + mActiveList.Clear(); + } + + public static void ReleaseAll() + { + ClearAll(); + ReleaseInactive(); + } + + public static void ReleaseInactive() + { + int num = mInactiveList.size; + while (num > 0) + { + UIDrawCall uIDrawCall = mInactiveList[--num]; + if ((bool)uIDrawCall) + { + NGUITools.DestroyImmediate(uIDrawCall.gameObject); + } + } + mInactiveList.Clear(); + } + + public static int Count(UIPanel panel) + { + int num = 0; + for (int i = 0; i < mActiveList.size; i++) + { + if (mActiveList[i].manager == panel) + { + num++; + } + } + return num; + } + + public static void Destroy(UIDrawCall dc) + { + if ((bool)dc) + { + dc.onRender = null; + if (Application.isPlaying) + { + if (mActiveList.Remove(dc)) + { + NGUITools.SetActive(dc.gameObject, state: false); + mInactiveList.Add(dc); + } + } + else + { + mActiveList.Remove(dc); + NGUITools.DestroyImmediate(dc.gameObject); + } + } + } +} diff --git a/UIEventListener.cs b/UIEventListener.cs new file mode 100644 index 00000000..2e2eb389 --- /dev/null +++ b/UIEventListener.cs @@ -0,0 +1,179 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Internal/Event Listener")] +public class UIEventListener : MonoBehaviour +{ + public delegate void VoidDelegate(GameObject go); + + public delegate void BoolDelegate(GameObject go, bool state); + + public delegate void FloatDelegate(GameObject go, float delta); + + public delegate void VectorDelegate(GameObject go, Vector2 delta); + + public delegate void ObjectDelegate(GameObject go, GameObject obj); + + public delegate void KeyCodeDelegate(GameObject go, KeyCode key); + + public object parameter; + + public VoidDelegate onSubmit; + + public VoidDelegate onClick; + + public VoidDelegate onDoubleClick; + + public BoolDelegate onHover; + + public BoolDelegate onPress; + + public BoolDelegate onSelect; + + public FloatDelegate onScroll; + + public VoidDelegate onDragStart; + + public VectorDelegate onDrag; + + public VoidDelegate onDragOver; + + public VoidDelegate onDragOut; + + public VoidDelegate onDragEnd; + + public ObjectDelegate onDrop; + + public KeyCodeDelegate onKey; + + public BoolDelegate onTooltip; + + private void OnSubmit() + { + if (onSubmit != null) + { + onSubmit(base.gameObject); + } + } + + private void OnClick() + { + if (onClick != null) + { + onClick(base.gameObject); + } + } + + private void OnDoubleClick() + { + if (onDoubleClick != null) + { + onDoubleClick(base.gameObject); + } + } + + private void OnHover(bool isOver) + { + if (onHover != null) + { + onHover(base.gameObject, isOver); + } + } + + private void OnPress(bool isPressed) + { + if (onPress != null) + { + onPress(base.gameObject, isPressed); + } + } + + private void OnSelect(bool selected) + { + if (onSelect != null) + { + onSelect(base.gameObject, selected); + } + } + + private void OnScroll(float delta) + { + if (onScroll != null) + { + onScroll(base.gameObject, delta); + } + } + + private void OnDragStart() + { + if (onDragStart != null) + { + onDragStart(base.gameObject); + } + } + + private void OnDrag(Vector2 delta) + { + if (onDrag != null) + { + onDrag(base.gameObject, delta); + } + } + + private void OnDragOver() + { + if (onDragOver != null) + { + onDragOver(base.gameObject); + } + } + + private void OnDragOut() + { + if (onDragOut != null) + { + onDragOut(base.gameObject); + } + } + + private void OnDragEnd() + { + if (onDragEnd != null) + { + onDragEnd(base.gameObject); + } + } + + private void OnDrop(GameObject go) + { + if (onDrop != null) + { + onDrop(base.gameObject, go); + } + } + + private void OnKey(KeyCode key) + { + if (onKey != null) + { + onKey(base.gameObject, key); + } + } + + private void OnTooltip(bool show) + { + if (onTooltip != null) + { + onTooltip(base.gameObject, show); + } + } + + public static UIEventListener Get(GameObject go) + { + UIEventListener uIEventListener = go.GetComponent(); + if (uIEventListener == null) + { + uIEventListener = go.AddComponent(); + } + return uIEventListener; + } +} diff --git a/UIEventTrigger.cs b/UIEventTrigger.cs new file mode 100644 index 00000000..6d7e5161 --- /dev/null +++ b/UIEventTrigger.cs @@ -0,0 +1,155 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Event Trigger")] +public class UIEventTrigger : MonoBehaviour +{ + public static UIEventTrigger current; + + public List onHoverOver = new List(); + + public List onHoverOut = new List(); + + public List onPress = new List(); + + public List onRelease = new List(); + + public List onSelect = new List(); + + public List onDeselect = new List(); + + public List onClick = new List(); + + public List onDoubleClick = new List(); + + public List onDragStart = new List(); + + public List onDragEnd = new List(); + + public List onDragOver = new List(); + + public List onDragOut = new List(); + + public List onDrag = new List(); + + private void OnHover(bool isOver) + { + if (!(current != null)) + { + current = this; + if (isOver) + { + EventDelegate.Execute(onHoverOver); + } + else + { + EventDelegate.Execute(onHoverOut); + } + current = null; + } + } + + private void OnPress(bool pressed) + { + if (!(current != null)) + { + current = this; + if (pressed) + { + EventDelegate.Execute(onPress); + } + else + { + EventDelegate.Execute(onRelease); + } + current = null; + } + } + + private void OnSelect(bool selected) + { + if (!(current != null)) + { + current = this; + if (selected) + { + EventDelegate.Execute(onSelect); + } + else + { + EventDelegate.Execute(onDeselect); + } + current = null; + } + } + + private void OnClick() + { + if (!(current != null)) + { + current = this; + EventDelegate.Execute(onClick); + current = null; + } + } + + private void OnDoubleClick() + { + if (!(current != null)) + { + current = this; + EventDelegate.Execute(onDoubleClick); + current = null; + } + } + + private void OnDragStart() + { + if (!(current != null)) + { + current = this; + EventDelegate.Execute(onDragStart); + current = null; + } + } + + private void OnDragEnd() + { + if (!(current != null)) + { + current = this; + EventDelegate.Execute(onDragEnd); + current = null; + } + } + + private void OnDragOver(GameObject go) + { + if (!(current != null)) + { + current = this; + EventDelegate.Execute(onDragOver); + current = null; + } + } + + private void OnDragOut(GameObject go) + { + if (!(current != null)) + { + current = this; + EventDelegate.Execute(onDragOut); + current = null; + } + } + + private void OnDrag(Vector2 delta) + { + if (!(current != null)) + { + current = this; + EventDelegate.Execute(onDragOut); + current = null; + } + } +} diff --git a/UIFont.cs b/UIFont.cs new file mode 100644 index 00000000..a1129b03 --- /dev/null +++ b/UIFont.cs @@ -0,0 +1,651 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Font")] +[ExecuteInEditMode] +public class UIFont : MonoBehaviour +{ + [HideInInspector] + [SerializeField] + private Material mMat; + + [HideInInspector] + [SerializeField] + private Rect mUVRect = new Rect(0f, 0f, 1f, 1f); + + [HideInInspector] + [SerializeField] + private BMFont mFont = new BMFont(); + + [HideInInspector] + [SerializeField] + private UIAtlas mAtlas; + + [HideInInspector] + [SerializeField] + private UIFont mReplacement; + + [HideInInspector] + [SerializeField] + private List mSymbols = new List(); + + [HideInInspector] + [SerializeField] + private Font mDynamicFont; + + [HideInInspector] + [SerializeField] + private int mDynamicFontSize = 16; + + [HideInInspector] + [SerializeField] + private FontStyle mDynamicFontStyle; + + [NonSerialized] + private UISpriteData mSprite; + + private int mPMA = -1; + + private int mPacked = -1; + + public BMFont bmFont + { + get + { + return (!(mReplacement != null)) ? mFont : mReplacement.bmFont; + } + set + { + if (mReplacement != null) + { + mReplacement.bmFont = value; + } + else + { + mFont = value; + } + } + } + + public int texWidth + { + get + { + return (mReplacement != null) ? mReplacement.texWidth : ((mFont == null) ? 1 : mFont.texWidth); + } + set + { + if (mReplacement != null) + { + mReplacement.texWidth = value; + } + else if (mFont != null) + { + mFont.texWidth = value; + } + } + } + + public int texHeight + { + get + { + return (mReplacement != null) ? mReplacement.texHeight : ((mFont == null) ? 1 : mFont.texHeight); + } + set + { + if (mReplacement != null) + { + mReplacement.texHeight = value; + } + else if (mFont != null) + { + mFont.texHeight = value; + } + } + } + + public bool hasSymbols => (mReplacement != null) ? mReplacement.hasSymbols : (mSymbols != null && mSymbols.Count != 0); + + public List symbols => (!(mReplacement != null)) ? mSymbols : mReplacement.symbols; + + public UIAtlas atlas + { + get + { + return (!(mReplacement != null)) ? mAtlas : mReplacement.atlas; + } + set + { + if (mReplacement != null) + { + mReplacement.atlas = value; + } + else if (mAtlas != value) + { + if (value == null) + { + if (mAtlas != null) + { + mMat = mAtlas.spriteMaterial; + } + if (sprite != null) + { + mUVRect = uvRect; + } + } + mPMA = -1; + mAtlas = value; + MarkAsChanged(); + } + } + } + + public Material material + { + get + { + if (mReplacement != null) + { + return mReplacement.material; + } + if (mAtlas != null) + { + return mAtlas.spriteMaterial; + } + if (mMat != null) + { + if (mDynamicFont != null && mMat != mDynamicFont.material) + { + mMat.mainTexture = mDynamicFont.material.mainTexture; + } + return mMat; + } + if (mDynamicFont != null) + { + return mDynamicFont.material; + } + return null; + } + set + { + if (mReplacement != null) + { + mReplacement.material = value; + } + else if (mMat != value) + { + mPMA = -1; + mMat = value; + MarkAsChanged(); + } + } + } + + [Obsolete("Use UIFont.premultipliedAlphaShader instead")] + public bool premultipliedAlpha + { + get + { + return premultipliedAlphaShader; + } + } + + public bool premultipliedAlphaShader + { + get + { + if (mReplacement != null) + { + return mReplacement.premultipliedAlphaShader; + } + if (mAtlas != null) + { + return mAtlas.premultipliedAlpha; + } + if (mPMA == -1) + { + Material material = this.material; + mPMA = ((material != null && material.shader != null && material.shader.name.Contains("Premultiplied")) ? 1 : 0); + } + return mPMA == 1; + } + } + + public bool packedFontShader + { + get + { + if (mReplacement != null) + { + return mReplacement.packedFontShader; + } + if (mAtlas != null) + { + return false; + } + if (mPacked == -1) + { + Material material = this.material; + mPacked = ((material != null && material.shader != null && material.shader.name.Contains("Packed")) ? 1 : 0); + } + return mPacked == 1; + } + } + + public Texture2D texture + { + get + { + if (mReplacement != null) + { + return mReplacement.texture; + } + Material material = this.material; + return (!(material != null)) ? null : (material.mainTexture as Texture2D); + } + } + + public Rect uvRect + { + get + { + if (mReplacement != null) + { + return mReplacement.uvRect; + } + return (!(mAtlas != null) || sprite == null) ? new Rect(0f, 0f, 1f, 1f) : mUVRect; + } + set + { + if (mReplacement != null) + { + mReplacement.uvRect = value; + } + else if (sprite == null && mUVRect != value) + { + mUVRect = value; + MarkAsChanged(); + } + } + } + + public string spriteName + { + get + { + return (!(mReplacement != null)) ? mFont.spriteName : mReplacement.spriteName; + } + set + { + if (mReplacement != null) + { + mReplacement.spriteName = value; + } + else if (mFont.spriteName != value) + { + mFont.spriteName = value; + MarkAsChanged(); + } + } + } + + public bool isValid => mDynamicFont != null || mFont.isValid; + + [Obsolete("Use UIFont.defaultSize instead")] + public int size + { + get + { + return defaultSize; + } + set + { + defaultSize = value; + } + } + + public int defaultSize + { + get + { + if (mReplacement != null) + { + return mReplacement.defaultSize; + } + if (isDynamic || mFont == null) + { + return mDynamicFontSize; + } + return mFont.charSize; + } + set + { + if (mReplacement != null) + { + mReplacement.defaultSize = value; + } + else + { + mDynamicFontSize = value; + } + } + } + + public UISpriteData sprite + { + get + { + if (mReplacement != null) + { + return mReplacement.sprite; + } + if (mSprite == null && mAtlas != null && !string.IsNullOrEmpty(mFont.spriteName)) + { + mSprite = mAtlas.GetSprite(mFont.spriteName); + if (mSprite == null) + { + mSprite = mAtlas.GetSprite(base.name); + } + if (mSprite == null) + { + mFont.spriteName = null; + } + else + { + UpdateUVRect(); + } + int i = 0; + for (int count = mSymbols.Count; i < count; i++) + { + symbols[i].MarkAsChanged(); + } + } + return mSprite; + } + } + + public UIFont replacement + { + get + { + return mReplacement; + } + set + { + UIFont uIFont = value; + if (uIFont == this) + { + uIFont = null; + } + if (mReplacement != uIFont) + { + if (uIFont != null && uIFont.replacement == this) + { + uIFont.replacement = null; + } + if (mReplacement != null) + { + MarkAsChanged(); + } + mReplacement = uIFont; + if (uIFont != null) + { + mPMA = -1; + mMat = null; + mFont = null; + mDynamicFont = null; + } + MarkAsChanged(); + } + } + } + + public bool isDynamic => (!(mReplacement != null)) ? (mDynamicFont != null) : mReplacement.isDynamic; + + public Font dynamicFont + { + get + { + return (!(mReplacement != null)) ? mDynamicFont : mReplacement.dynamicFont; + } + set + { + if (mReplacement != null) + { + mReplacement.dynamicFont = value; + } + else if (mDynamicFont != value) + { + if (mDynamicFont != null) + { + material = null; + } + mDynamicFont = value; + MarkAsChanged(); + } + } + } + + public FontStyle dynamicFontStyle + { + get + { + return (!(mReplacement != null)) ? mDynamicFontStyle : mReplacement.dynamicFontStyle; + } + set + { + if (mReplacement != null) + { + mReplacement.dynamicFontStyle = value; + } + else if (mDynamicFontStyle != value) + { + mDynamicFontStyle = value; + MarkAsChanged(); + } + } + } + + private Texture dynamicTexture + { + get + { + if ((bool)mReplacement) + { + return mReplacement.dynamicTexture; + } + if (isDynamic) + { + return mDynamicFont.material.mainTexture; + } + return null; + } + } + + private void Trim() + { + Texture texture = mAtlas.texture; + if (texture != null && mSprite != null) + { + Rect rect = NGUIMath.ConvertToPixels(mUVRect, this.texture.width, this.texture.height, round: true); + Rect rect2 = new Rect((float)mSprite.x, (float)mSprite.y, (float)mSprite.width, (float)mSprite.height); + int xMin = Mathf.RoundToInt(rect2.xMin - rect.xMin); + int yMin = Mathf.RoundToInt(rect2.yMin - rect.yMin); + int xMax = Mathf.RoundToInt(rect2.xMax - rect.xMin); + int yMax = Mathf.RoundToInt(rect2.yMax - rect.yMin); + mFont.Trim(xMin, yMin, xMax, yMax); + } + } + + private bool References(UIFont font) + { + if (font == null) + { + return false; + } + if (font == this) + { + return true; + } + return mReplacement != null && mReplacement.References(font); + } + + public static bool CheckIfRelated(UIFont a, UIFont b) + { + if (a == null || b == null) + { + return false; + } + if (a.isDynamic && b.isDynamic && a.dynamicFont.fontNames[0] == b.dynamicFont.fontNames[0]) + { + return true; + } + return a == b || a.References(b) || b.References(a); + } + + public void MarkAsChanged() + { + if (mReplacement != null) + { + mReplacement.MarkAsChanged(); + } + mSprite = null; + UILabel[] array = NGUITools.FindActive(); + int i = 0; + for (int num = array.Length; i < num; i++) + { + UILabel uILabel = array[i]; + if (uILabel.enabled && NGUITools.GetActive(uILabel.gameObject) && CheckIfRelated(this, uILabel.bitmapFont)) + { + UIFont bitmapFont = uILabel.bitmapFont; + uILabel.bitmapFont = null; + uILabel.bitmapFont = bitmapFont; + } + } + int j = 0; + for (int count = symbols.Count; j < count; j++) + { + symbols[j].MarkAsChanged(); + } + } + + public void UpdateUVRect() + { + if (!(mAtlas == null)) + { + Texture texture = mAtlas.texture; + if (texture != null) + { + mUVRect = new Rect((float)(mSprite.x - mSprite.paddingLeft), (float)(mSprite.y - mSprite.paddingTop), (float)(mSprite.width + mSprite.paddingLeft + mSprite.paddingRight), (float)(mSprite.height + mSprite.paddingTop + mSprite.paddingBottom)); + mUVRect = NGUIMath.ConvertToTexCoords(mUVRect, texture.width, texture.height); + if (mSprite.hasPadding) + { + Trim(); + } + } + } + } + + private BMSymbol GetSymbol(string sequence, bool createIfMissing) + { + int i = 0; + for (int count = mSymbols.Count; i < count; i++) + { + BMSymbol bMSymbol = mSymbols[i]; + if (bMSymbol.sequence == sequence) + { + return bMSymbol; + } + } + if (createIfMissing) + { + BMSymbol bMSymbol2 = new BMSymbol(); + bMSymbol2.sequence = sequence; + mSymbols.Add(bMSymbol2); + return bMSymbol2; + } + return null; + } + + public BMSymbol MatchSymbol(string text, int offset, int textLength) + { + int count = mSymbols.Count; + if (count == 0) + { + return null; + } + textLength -= offset; + for (int i = 0; i < count; i++) + { + BMSymbol bMSymbol = mSymbols[i]; + int length = bMSymbol.length; + if (length != 0 && textLength >= length) + { + bool flag = true; + for (int j = 0; j < length; j++) + { + if (text[offset + j] != bMSymbol.sequence[j]) + { + flag = false; + break; + } + } + if (flag && bMSymbol.Validate(atlas)) + { + return bMSymbol; + } + } + } + return null; + } + + public void AddSymbol(string sequence, string spriteName) + { + BMSymbol symbol = GetSymbol(sequence, /*createIfMissing:*/ true); + symbol.spriteName = spriteName; + MarkAsChanged(); + } + + public void RemoveSymbol(string sequence) + { + BMSymbol symbol = GetSymbol(sequence, createIfMissing: false); + if (symbol != null) + { + symbols.Remove(symbol); + } + MarkAsChanged(); + } + + public void RenameSymbol(string before, string after) + { + BMSymbol symbol = GetSymbol(before, createIfMissing: false); + if (symbol != null) + { + symbol.sequence = after; + } + MarkAsChanged(); + } + + public bool UsesSprite(string s) + { + if (!string.IsNullOrEmpty(s)) + { + if (s.Equals(spriteName)) + { + return true; + } + int i = 0; + for (int count = symbols.Count; i < count; i++) + { + BMSymbol bMSymbol = symbols[i]; + if (s.Equals(bMSymbol.spriteName)) + { + return true; + } + } + } + return false; + } +} diff --git a/UIForwardEvents.cs b/UIForwardEvents.cs new file mode 100644 index 00000000..25a439cb --- /dev/null +++ b/UIForwardEvents.cs @@ -0,0 +1,97 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Forward Events (Legacy)")] +public class UIForwardEvents : MonoBehaviour +{ + public GameObject target; + + public bool onHover; + + public bool onPress; + + public bool onClick; + + public bool onDoubleClick; + + public bool onSelect; + + public bool onDrag; + + public bool onDrop; + + public bool onSubmit; + + public bool onScroll; + + private void OnHover(bool isOver) + { + if (onHover && target != null) + { + target.SendMessage("OnHover", isOver, SendMessageOptions.DontRequireReceiver); + } + } + + private void OnPress(bool pressed) + { + if (onPress && target != null) + { + target.SendMessage("OnPress", pressed, SendMessageOptions.DontRequireReceiver); + } + } + + private void OnClick() + { + if (onClick && target != null) + { + target.SendMessage("OnClick", SendMessageOptions.DontRequireReceiver); + } + } + + private void OnDoubleClick() + { + if (onDoubleClick && target != null) + { + target.SendMessage("OnDoubleClick", SendMessageOptions.DontRequireReceiver); + } + } + + private void OnSelect(bool selected) + { + if (onSelect && target != null) + { + target.SendMessage("OnSelect", selected, SendMessageOptions.DontRequireReceiver); + } + } + + private void OnDrag(Vector2 delta) + { + if (onDrag && target != null) + { + target.SendMessage("OnDrag", delta, SendMessageOptions.DontRequireReceiver); + } + } + + private void OnDrop(GameObject go) + { + if (onDrop && target != null) + { + target.SendMessage("OnDrop", go, SendMessageOptions.DontRequireReceiver); + } + } + + private void OnSubmit() + { + if (onSubmit && target != null) + { + target.SendMessage("OnSubmit", SendMessageOptions.DontRequireReceiver); + } + } + + private void OnScroll(float delta) + { + if (onScroll && target != null) + { + target.SendMessage("OnScroll", delta, SendMessageOptions.DontRequireReceiver); + } + } +} diff --git a/UIGeometry.cs b/UIGeometry.cs new file mode 100644 index 00000000..a9cfbb18 --- /dev/null +++ b/UIGeometry.cs @@ -0,0 +1,75 @@ +using UnityEngine; + +public class UIGeometry +{ + public BetterList verts = new BetterList(); + + public BetterList uvs = new BetterList(); + + public BetterList cols = new BetterList(); + + private BetterList mRtpVerts = new BetterList(); + + private Vector3 mRtpNormal; + + private Vector4 mRtpTan; + + public bool hasVertices => verts.size > 0; + + public bool hasTransformed => mRtpVerts != null && mRtpVerts.size > 0 && mRtpVerts.size == verts.size; + + public void Clear() + { + verts.Clear(); + uvs.Clear(); + cols.Clear(); + mRtpVerts.Clear(); + } + + public void ApplyTransform(Matrix4x4 widgetToPanel) + { + if (verts.size > 0) + { + mRtpVerts.Clear(); + int i = 0; + for (int size = verts.size; i < size; i++) + { + mRtpVerts.Add(widgetToPanel.MultiplyPoint3x4(verts[i])); + } + mRtpNormal = widgetToPanel.MultiplyVector(Vector3.back).normalized; + Vector3 normalized = widgetToPanel.MultiplyVector(Vector3.right).normalized; + mRtpTan = new Vector4(normalized.x, normalized.y, normalized.z, -1f); + } + else + { + mRtpVerts.Clear(); + } + } + + public void WriteToBuffers(BetterList v, BetterList u, BetterList c, BetterList n, BetterList t) + { + if (mRtpVerts != null && mRtpVerts.size > 0) + { + if (n == null) + { + for (int i = 0; i < mRtpVerts.size; i++) + { + v.Add(mRtpVerts.buffer[i]); + u.Add(uvs.buffer[i]); + c.Add(cols.buffer[i]); + } + } + else + { + for (int j = 0; j < mRtpVerts.size; j++) + { + v.Add(mRtpVerts.buffer[j]); + u.Add(uvs.buffer[j]); + c.Add(cols.buffer[j]); + n.Add(mRtpNormal); + t.Add(mRtpTan); + } + } + } + } +} diff --git a/UIGrid.cs b/UIGrid.cs new file mode 100644 index 00000000..e563e856 --- /dev/null +++ b/UIGrid.cs @@ -0,0 +1,324 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Grid")] +public class UIGrid : UIWidgetContainer +{ + public enum Arrangement + { + Horizontal, + Vertical, + CellSnap + } + + public enum Sorting + { + None, + Alphabetic, + Horizontal, + Vertical, + Custom + } + + public delegate void OnReposition(); + + public Arrangement arrangement; + + public Sorting sorting; + + public UIWidget.Pivot pivot; + + public int maxPerLine; + + public float cellWidth = 200f; + + public float cellHeight = 200f; + + public bool animateSmoothly; + + public bool hideInactive; + + public bool keepWithinPanel; + + public OnReposition onReposition; + + public Comparison onCustomSort; + + [HideInInspector] + [SerializeField] + private bool sorted; + + protected bool mReposition; + + protected UIPanel mPanel; + + protected bool mInitDone; + + public bool repositionNow + { + set + { + if (value) + { + mReposition = true; + base.enabled = true; + } + } + } + + public List GetChildList() + { + Transform transform = base.transform; + List list = new List(); + for (int i = 0; i < transform.childCount; i++) + { + Transform child = transform.GetChild(i); + if (!hideInactive || ((bool)child && NGUITools.GetActive(child.gameObject))) + { + list.Add(child); + } + } + if (sorting != 0 && arrangement != Arrangement.CellSnap) + { + if (sorting == Sorting.Alphabetic) + { + list.Sort(SortByName); + } + else if (sorting == Sorting.Horizontal) + { + list.Sort(SortHorizontal); + } + else if (sorting == Sorting.Vertical) + { + list.Sort(SortVertical); + } + else if (onCustomSort != null) + { + list.Sort(onCustomSort); + } + else + { + Sort(list); + } + } + return list; + } + + public Transform GetChild(int index) + { + List childList = GetChildList(); + return (index >= childList.Count) ? null : childList[index]; + } + + public int GetIndex(Transform trans) + { + return GetChildList().IndexOf(trans); + } + + public void AddChild(Transform trans) + { + AddChild(trans, sort: true); + } + + public void AddChild(Transform trans, bool sort) + { + if (trans != null) + { + trans.parent = base.transform; + ResetPosition(GetChildList()); + } + } + + public bool RemoveChild(Transform t) + { + List childList = GetChildList(); + if (childList.Remove(t)) + { + ResetPosition(childList); + return true; + } + return false; + } + + protected virtual void Init() + { + mInitDone = true; + mPanel = NGUITools.FindInParents(base.gameObject); + } + + protected virtual void Start() + { + if (!mInitDone) + { + Init(); + } + bool flag = animateSmoothly; + animateSmoothly = false; + Reposition(); + animateSmoothly = flag; + base.enabled = false; + } + + protected virtual void Update() + { + Reposition(); + base.enabled = false; + } + + private void OnValidate() + { + if (!Application.isPlaying && NGUITools.GetActive(this)) + { + Reposition(); + } + } + + public static int SortByName(Transform a, Transform b) + { + return string.Compare(a.name, b.name); + } + + public static int SortHorizontal(Transform a, Transform b) + { + Vector3 localPosition = a.localPosition; + ref float x = ref localPosition.x; + Vector3 localPosition2 = b.localPosition; + return x.CompareTo(localPosition2.x); + } + + public static int SortVertical(Transform a, Transform b) + { + Vector3 localPosition = b.localPosition; + ref float y = ref localPosition.y; + Vector3 localPosition2 = a.localPosition; + return y.CompareTo(localPosition2.y); + } + + protected virtual void Sort(List list) + { + } + + [ContextMenu("Execute")] + public virtual void Reposition() + { + if (Application.isPlaying && !mInitDone && NGUITools.GetActive(base.gameObject)) + { + Init(); + } + if (sorted) + { + sorted = false; + if (sorting == Sorting.None) + { + sorting = Sorting.Alphabetic; + } + NGUITools.SetDirty(this); + } + List childList = GetChildList(); + ResetPosition(childList); + if (keepWithinPanel) + { + ConstrainWithinPanel(); + } + if (onReposition != null) + { + onReposition(); + } + } + + public void ConstrainWithinPanel() + { + if (mPanel != null) + { + mPanel.ConstrainTargetToBounds(base.transform, immediate: true); + UIScrollView component = mPanel.GetComponent(); + if (component != null) + { + component.UpdateScrollbars(recalculateBounds: true); + } + } + } + + protected void ResetPosition(List list) + { + mReposition = false; + int num = 0; + int num2 = 0; + int num3 = 0; + int num4 = 0; + Transform transform = base.transform; + int i = 0; + for (int count = list.Count; i < count; i++) + { + Transform transform2 = list[i]; + Vector3 vector = transform2.localPosition; + float z = vector.z; + if (arrangement == Arrangement.CellSnap) + { + if (cellWidth > 0f) + { + vector.x = Mathf.Round(vector.x / cellWidth) * cellWidth; + } + if (cellHeight > 0f) + { + vector.y = Mathf.Round(vector.y / cellHeight) * cellHeight; + } + } + else + { + vector = ((arrangement != 0) ? new Vector3(cellWidth * (float)num2, (0f - cellHeight) * (float)num, z) : new Vector3(cellWidth * (float)num, (0f - cellHeight) * (float)num2, z)); + } + if (animateSmoothly && Application.isPlaying && Vector3.SqrMagnitude(transform2.localPosition - vector) >= 0.0001f) + { + SpringPosition springPosition = SpringPosition.Begin(transform2.gameObject, vector, 15f); + springPosition.updateScrollView = true; + springPosition.ignoreTimeScale = true; + } + else + { + transform2.localPosition = vector; + } + num3 = Mathf.Max(num3, num); + num4 = Mathf.Max(num4, num2); + if (++num >= maxPerLine && maxPerLine > 0) + { + num = 0; + num2++; + } + } + if (pivot != 0) + { + Vector2 pivotOffset = NGUIMath.GetPivotOffset(pivot); + float num5; + float num6; + if (arrangement == Arrangement.Horizontal) + { + num5 = Mathf.Lerp(0f, (float)num3 * cellWidth, pivotOffset.x); + num6 = Mathf.Lerp((float)(-num4) * cellHeight, 0f, pivotOffset.y); + } + else + { + num5 = Mathf.Lerp(0f, (float)num4 * cellWidth, pivotOffset.x); + num6 = Mathf.Lerp((float)(-num3) * cellHeight, 0f, pivotOffset.y); + } + for (int j = 0; j < transform.childCount; j++) + { + Transform child = transform.GetChild(j); + SpringPosition component = child.GetComponent(); + if (component != null) + { + component.target.x -= num5; + component.target.y -= num6; + } + else + { + Vector3 localPosition = child.localPosition; + localPosition.x -= num5; + localPosition.y -= num6; + child.localPosition = localPosition; + } + } + } + } +} diff --git a/UIImageButton.cs b/UIImageButton.cs new file mode 100644 index 00000000..7f9057db --- /dev/null +++ b/UIImageButton.cs @@ -0,0 +1,114 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Image Button")] +public class UIImageButton : MonoBehaviour +{ + public UISprite target; + + public string normalSprite; + + public string hoverSprite; + + public string pressedSprite; + + public string disabledSprite; + + public bool pixelSnap = true; + + public bool isEnabled + { + get + { + Collider component = GetComponent(); + return (bool)component && component.enabled; + } + set + { + Collider component = GetComponent(); + if ((bool)component && component.enabled != value) + { + component.enabled = value; + UpdateImage(); + } + } + } + + private void OnEnable() + { + if (target == null) + { + target = GetComponentInChildren(); + } + UpdateImage(); + } + + private void OnValidate() + { + if (target != null) + { + if (string.IsNullOrEmpty(normalSprite)) + { + normalSprite = target.spriteName; + } + if (string.IsNullOrEmpty(hoverSprite)) + { + hoverSprite = target.spriteName; + } + if (string.IsNullOrEmpty(pressedSprite)) + { + pressedSprite = target.spriteName; + } + if (string.IsNullOrEmpty(disabledSprite)) + { + disabledSprite = target.spriteName; + } + } + } + + private void UpdateImage() + { + if (target != null) + { + if (isEnabled) + { + SetSprite((!UICamera.IsHighlighted(base.gameObject)) ? normalSprite : hoverSprite); + } + else + { + SetSprite(disabledSprite); + } + } + } + + private void OnHover(bool isOver) + { + if (isEnabled && target != null) + { + SetSprite((!isOver) ? normalSprite : hoverSprite); + } + } + + private void OnPress(bool pressed) + { + if (pressed) + { + SetSprite(pressedSprite); + } + else + { + UpdateImage(); + } + } + + private void SetSprite(string sprite) + { + if (!(target.atlas == null) && target.atlas.GetSprite(sprite) != null) + { + target.spriteName = sprite; + if (pixelSnap) + { + target.MakePixelPerfect(); + } + } + } +} diff --git a/UIInput.cs b/UIInput.cs new file mode 100644 index 00000000..c5b0a07b --- /dev/null +++ b/UIInput.cs @@ -0,0 +1,1196 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Input Field")] +public class UIInput : MonoBehaviour +{ + public enum InputType + { + Standard, + AutoCorrect, + Password + } + + public enum Validation + { + None, + Integer, + Float, + Alphanumeric, + Username, + Name + } + + public enum KeyboardType + { + Default, + ASCIICapable, + NumbersAndPunctuation, + URL, + NumberPad, + PhonePad, + NamePhonePad, + EmailAddress + } + + public enum OnReturnKey + { + Default, + Submit, + NewLine + } + + public delegate char OnValidate(string text, int charIndex, char addedChar); + + public static UIInput current; + + public static UIInput selection; + + public UILabel label; + + public InputType inputType; + + public OnReturnKey onReturnKey; + + public KeyboardType keyboardType; + + public bool hideInput; + + [NonSerialized] + public bool selectAllTextOnFocus = true; + + public Validation validation; + + public int characterLimit; + + public string savedAs; + + [HideInInspector] + [SerializeField] + private GameObject selectOnTab; + + public Color activeTextColor = Color.white; + + public Color caretColor = new Color(1f, 1f, 1f, 0.8f); + + public Color selectionColor = new Color(1f, 0.8745098f, 0.5529412f, 0.5f); + + public List onSubmit = new List(); + + public List onChange = new List(); + + public OnValidate onValidate; + + [HideInInspector] + [SerializeField] + protected string mValue; + + [NonSerialized] + protected string mDefaultText = string.Empty; + + [NonSerialized] + protected Color mDefaultColor = Color.white; + + [NonSerialized] + protected float mPosition; + + [NonSerialized] + protected bool mDoInit = true; + + [NonSerialized] + protected UIWidget.Pivot mPivot; + + [NonSerialized] + protected bool mLoadSavedValue = true; + + protected static int mDrawStart; + + protected static string mLastIME = string.Empty; + + [NonSerialized] + protected int mSelectionStart; + + [NonSerialized] + protected int mSelectionEnd; + + [NonSerialized] + protected UITexture mHighlight; + + [NonSerialized] + protected UITexture mCaret; + + [NonSerialized] + protected Texture2D mBlankTex; + + [NonSerialized] + protected float mNextBlink; + + [NonSerialized] + protected float mLastAlpha; + + [NonSerialized] + protected string mCached = string.Empty; + + [NonSerialized] + protected int mSelectMe = -1; + + [NonSerialized] + private UIInputOnGUI mOnGUI; + + public string defaultText + { + get + { + if (mDoInit) + { + Init(); + } + return mDefaultText; + } + set + { + if (mDoInit) + { + Init(); + } + mDefaultText = value; + UpdateLabel(); + } + } + + public bool inputShouldBeHidden => hideInput && label != null && !label.multiLine && inputType != InputType.Password; + + [Obsolete("Use UIInput.value instead")] + public string text + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public string value + { + get + { + if (mDoInit) + { + Init(); + } + return mValue; + } + set + { + if (mDoInit) + { + Init(); + } + mDrawStart = 0; + if (Application.platform == RuntimePlatform.BlackBerryPlayer) + { + value = value.Replace("\\b", "\b"); + } + value = Validate(value); + if (mValue != value) + { + mValue = value; + mLoadSavedValue = false; + if (isSelected) + { + if (string.IsNullOrEmpty(value)) + { + mSelectionStart = 0; + mSelectionEnd = 0; + } + else + { + mSelectionStart = value.Length; + mSelectionEnd = mSelectionStart; + } + } + else + { + SaveToPlayerPrefs(value); + } + UpdateLabel(); + ExecuteOnChange(); + } + } + } + + [Obsolete("Use UIInput.isSelected instead")] + public bool selected + { + get + { + return isSelected; + } + set + { + isSelected = value; + } + } + + public bool isSelected + { + get + { + return selection == this; + } + set + { + if (!value) + { + if (isSelected) + { + UICamera.selectedObject = null; + } + } + else + { + UICamera.selectedObject = base.gameObject; + } + } + } + + public int cursorPosition + { + get + { + return (!isSelected) ? value.Length : mSelectionEnd; + } + set + { + if (isSelected) + { + mSelectionEnd = value; + UpdateLabel(); + } + } + } + + public int selectionStart + { + get + { + return (!isSelected) ? value.Length : mSelectionStart; + } + set + { + if (isSelected) + { + mSelectionStart = value; + UpdateLabel(); + } + } + } + + public int selectionEnd + { + get + { + return (!isSelected) ? value.Length : mSelectionEnd; + } + set + { + if (isSelected) + { + mSelectionEnd = value; + UpdateLabel(); + } + } + } + + public UITexture caret => mCaret; + + public string Validate(string val) + { + if (string.IsNullOrEmpty(val)) + { + return string.Empty; + } + StringBuilder stringBuilder = new StringBuilder(val.Length); + for (int i = 0; i < val.Length; i++) + { + char c = val[i]; + if (onValidate != null) + { + c = onValidate(stringBuilder.ToString(), stringBuilder.Length, c); + } + else if (validation != 0) + { + c = Validate(stringBuilder.ToString(), stringBuilder.Length, c); + } + if (c != 0) + { + stringBuilder.Append(c); + } + } + if (characterLimit > 0 && stringBuilder.Length > characterLimit) + { + return stringBuilder.ToString(0, characterLimit); + } + return stringBuilder.ToString(); + } + + private void Start() + { + if (selectOnTab != null) + { + UIKeyNavigation component = GetComponent(); + if (component == null) + { + component = base.gameObject.AddComponent(); + component.onDown = selectOnTab; + } + selectOnTab = null; + NGUITools.SetDirty(this); + } + if (mLoadSavedValue && !string.IsNullOrEmpty(savedAs)) + { + LoadValue(); + } + else + { + value = mValue.Replace("\\n", "\n"); + } + } + + protected void Init() + { + if (mDoInit && label != null) + { + mDoInit = false; + mDefaultText = label.text; + mDefaultColor = label.color; + label.supportEncoding = false; + if (label.alignment == NGUIText.Alignment.Justified) + { + label.alignment = NGUIText.Alignment.Left; + Debug.LogWarning("Input fields using labels with justified alignment are not supported at this time", this); + } + mPivot = label.pivot; + Vector3 localPosition = label.cachedTransform.localPosition; + mPosition = localPosition.x; + UpdateLabel(); + } + } + + protected void SaveToPlayerPrefs(string val) + { + if (!string.IsNullOrEmpty(savedAs)) + { + if (string.IsNullOrEmpty(val)) + { + PlayerPrefs.DeleteKey(savedAs); + } + else + { + PlayerPrefs.SetString(savedAs, val); + } + } + } + + protected virtual void OnSelect(bool isSelected) + { + if (isSelected) + { + if (mOnGUI == null) + { + mOnGUI = base.gameObject.AddComponent(); + } + OnSelectEvent(); + } + else + { + if (mOnGUI != null) + { + UnityEngine.Object.Destroy(mOnGUI); + mOnGUI = null; + } + OnDeselectEvent(); + } + } + + protected void OnSelectEvent() + { + selection = this; + if (mDoInit) + { + Init(); + } + if (label != null && NGUITools.GetActive(this)) + { + mSelectMe = Time.frameCount; + } + } + + protected void OnDeselectEvent() + { + if (mDoInit) + { + Init(); + } + if (label != null && NGUITools.GetActive(this)) + { + mValue = value; + if (string.IsNullOrEmpty(mValue)) + { + label.text = mDefaultText; + label.color = mDefaultColor; + } + else + { + label.text = mValue; + } + Input.imeCompositionMode = IMECompositionMode.Auto; + RestoreLabelPivot(); + } + selection = null; + UpdateLabel(); + } + + protected virtual void Update() + { + if (isSelected) + { + if (mDoInit) + { + Init(); + } + if (mSelectMe != -1 && mSelectMe != Time.frameCount) + { + mSelectMe = -1; + mSelectionEnd = ((!string.IsNullOrEmpty(mValue)) ? mValue.Length : 0); + mDrawStart = 0; + mSelectionStart = ((!selectAllTextOnFocus) ? mSelectionEnd : 0); + label.color = activeTextColor; + Vector2 compositionCursorPos = (!(UICamera.current != null) || !(UICamera.current.cachedCamera != null)) ? label.worldCorners[0] : UICamera.current.cachedCamera.WorldToScreenPoint(label.worldCorners[0]); + compositionCursorPos.y = (float)Screen.height - compositionCursorPos.y; + Input.imeCompositionMode = IMECompositionMode.On; + Input.compositionCursorPos = compositionCursorPos; + UpdateLabel(); + if (string.IsNullOrEmpty(Input.inputString)) + { + return; + } + } + string compositionString = Input.compositionString; + if (string.IsNullOrEmpty(compositionString) && !string.IsNullOrEmpty(Input.inputString)) + { + string inputString = Input.inputString; + for (int i = 0; i < inputString.Length; i++) + { + char c = inputString[i]; + if (c >= ' ' && c != '\uf700' && c != '\uf701' && c != '\uf702' && c != '\uf703') + { + Insert(c.ToString()); + } + } + } + if (mLastIME != compositionString) + { + mSelectionEnd = ((!string.IsNullOrEmpty(compositionString)) ? (mValue.Length + compositionString.Length) : mSelectionStart); + mLastIME = compositionString; + UpdateLabel(); + ExecuteOnChange(); + } + if (mCaret != null && mNextBlink < RealTime.time) + { + mNextBlink = RealTime.time + 0.5f; + mCaret.enabled = !mCaret.enabled; + } + if (isSelected && mLastAlpha != label.finalAlpha) + { + UpdateLabel(); + } + } + } + + protected void DoBackspace() + { + if (!string.IsNullOrEmpty(mValue)) + { + if (mSelectionStart == mSelectionEnd) + { + if (mSelectionStart < 1) + { + return; + } + mSelectionEnd--; + } + Insert(string.Empty); + } + } + + public virtual bool ProcessEvent(Event ev) + { + if (!(label == null)) + { + RuntimePlatform platform = Application.platform; + bool flag = (platform != 0 && platform != RuntimePlatform.OSXPlayer && platform != RuntimePlatform.OSXWebPlayer) ? ((ev.modifiers & EventModifiers.Control) != EventModifiers.None) : ((ev.modifiers & EventModifiers.Command) != EventModifiers.None); + if ((ev.modifiers & EventModifiers.Alt) != 0) + { + flag = false; + } + bool flag2 = (ev.modifiers & EventModifiers.Shift) != EventModifiers.None; + switch (ev.keyCode) + { + case KeyCode.Backspace: + ev.Use(); + DoBackspace(); + return true; + case KeyCode.Delete: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + if (mSelectionStart == mSelectionEnd) + { + if (mSelectionStart >= mValue.Length) + { + return true; + } + mSelectionEnd++; + } + Insert(string.Empty); + } + return true; + case KeyCode.LeftArrow: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + mSelectionEnd = Mathf.Max(mSelectionEnd - 1, 0); + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.RightArrow: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + mSelectionEnd = Mathf.Min(mSelectionEnd + 1, mValue.Length); + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.PageUp: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + mSelectionEnd = 0; + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.PageDown: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + mSelectionEnd = mValue.Length; + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.Home: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + if (label.multiLine) + { + mSelectionEnd = label.GetCharacterIndex(mSelectionEnd, KeyCode.Home); + } + else + { + mSelectionEnd = 0; + } + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.End: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + if (label.multiLine) + { + mSelectionEnd = label.GetCharacterIndex(mSelectionEnd, KeyCode.End); + } + else + { + mSelectionEnd = mValue.Length; + } + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.UpArrow: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + mSelectionEnd = label.GetCharacterIndex(mSelectionEnd, KeyCode.UpArrow); + if (mSelectionEnd != 0) + { + mSelectionEnd += mDrawStart; + } + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.DownArrow: + ev.Use(); + if (!string.IsNullOrEmpty(mValue)) + { + mSelectionEnd = label.GetCharacterIndex(mSelectionEnd, KeyCode.DownArrow); + if (mSelectionEnd != label.processedText.Length) + { + mSelectionEnd += mDrawStart; + } + else + { + mSelectionEnd = mValue.Length; + } + if (!flag2) + { + mSelectionStart = mSelectionEnd; + } + UpdateLabel(); + } + return true; + case KeyCode.A: + if (flag) + { + ev.Use(); + mSelectionStart = 0; + mSelectionEnd = mValue.Length; + UpdateLabel(); + } + return true; + case KeyCode.C: + if (flag) + { + ev.Use(); + NGUITools.clipboard = GetSelection(); + } + return true; + case KeyCode.V: + if (flag) + { + ev.Use(); + Insert(NGUITools.clipboard); + } + return true; + case KeyCode.X: + if (flag) + { + ev.Use(); + NGUITools.clipboard = GetSelection(); + Insert(string.Empty); + } + return true; + case KeyCode.Return: + case KeyCode.KeypadEnter: + ev.Use(); + if (onReturnKey == OnReturnKey.NewLine || (onReturnKey == OnReturnKey.Default && label.multiLine && !flag && label.overflowMethod != UILabel.Overflow.ClampContent && validation == Validation.None)) + { + Insert("\n"); + } + else + { + UICamera.currentScheme = UICamera.ControlScheme.Controller; + UICamera.currentKey = ev.keyCode; + Submit(); + UICamera.currentKey = KeyCode.None; + } + return true; + default: + return false; + } + } + return false; + } + + protected virtual void Insert(string text) + { + string leftText = GetLeftText(); + string rightText = GetRightText(); + int length = rightText.Length; + StringBuilder stringBuilder = new StringBuilder(leftText.Length + rightText.Length + text.Length); + stringBuilder.Append(leftText); + int i = 0; + for (int length2 = text.Length; i < length2; i++) + { + char c = text[i]; + if (c == '\b') + { + DoBackspace(); + } + else + { + if (characterLimit > 0 && stringBuilder.Length + length >= characterLimit) + { + break; + } + if (onValidate != null) + { + c = onValidate(stringBuilder.ToString(), stringBuilder.Length, c); + } + else if (validation != 0) + { + c = Validate(stringBuilder.ToString(), stringBuilder.Length, c); + } + if (c != 0) + { + stringBuilder.Append(c); + } + } + } + mSelectionStart = stringBuilder.Length; + mSelectionEnd = mSelectionStart; + int j = 0; + for (int length3 = rightText.Length; j < length3; j++) + { + char c2 = rightText[j]; + if (onValidate != null) + { + c2 = onValidate(stringBuilder.ToString(), stringBuilder.Length, c2); + } + else if (validation != 0) + { + c2 = Validate(stringBuilder.ToString(), stringBuilder.Length, c2); + } + if (c2 != 0) + { + stringBuilder.Append(c2); + } + } + mValue = stringBuilder.ToString(); + UpdateLabel(); + ExecuteOnChange(); + } + + protected string GetLeftText() + { + int num = Mathf.Min(mSelectionStart, mSelectionEnd); + return (!string.IsNullOrEmpty(mValue) && num >= 0) ? mValue.Substring(0, num) : string.Empty; + } + + protected string GetRightText() + { + int num = Mathf.Max(mSelectionStart, mSelectionEnd); + return (!string.IsNullOrEmpty(mValue) && num < mValue.Length) ? mValue.Substring(num) : string.Empty; + } + + protected string GetSelection() + { + if (string.IsNullOrEmpty(mValue) || mSelectionStart == mSelectionEnd) + { + return string.Empty; + } + int num = Mathf.Min(mSelectionStart, mSelectionEnd); + int num2 = Mathf.Max(mSelectionStart, mSelectionEnd); + return mValue.Substring(num, num2 - num); + } + + protected int GetCharUnderMouse() + { + Vector3[] worldCorners = label.worldCorners; + Ray currentRay = UICamera.currentRay; + float enter; + return new Plane(worldCorners[0], worldCorners[1], worldCorners[2]).Raycast(currentRay, out enter) ? (mDrawStart + label.GetCharacterIndexAtPosition(currentRay.GetPoint(enter), precise: false)) : 0; + } + + protected virtual void OnPress(bool isPressed) + { + if (isPressed && isSelected && label != null && (UICamera.currentScheme == UICamera.ControlScheme.Mouse || UICamera.currentScheme == UICamera.ControlScheme.Touch)) + { + selectionEnd = GetCharUnderMouse(); + if (!Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.RightShift)) + { + selectionStart = mSelectionEnd; + } + } + } + + protected virtual void OnDrag(Vector2 delta) + { + if (label != null && (UICamera.currentScheme == UICamera.ControlScheme.Mouse || UICamera.currentScheme == UICamera.ControlScheme.Touch)) + { + selectionEnd = GetCharUnderMouse(); + } + } + + private void OnDisable() + { + Cleanup(); + } + + protected virtual void Cleanup() + { + if ((bool)mHighlight) + { + mHighlight.enabled = false; + } + if ((bool)mCaret) + { + mCaret.enabled = false; + } + if ((bool)mBlankTex) + { + NGUITools.Destroy(mBlankTex); + mBlankTex = null; + } + } + + public void Submit() + { + if (NGUITools.GetActive(this)) + { + mValue = value; + if (current == null) + { + current = this; + EventDelegate.Execute(onSubmit); + current = null; + } + SaveToPlayerPrefs(mValue); + } + } + + public void UpdateLabel() + { + if (label != null) + { + if (mDoInit) + { + Init(); + } + bool isSelected = this.isSelected; + string value = this.value; + bool flag = string.IsNullOrEmpty(value) && string.IsNullOrEmpty(Input.compositionString); + label.color = ((!flag || isSelected) ? activeTextColor : mDefaultColor); + string text; + if (flag) + { + text = ((!isSelected) ? mDefaultText : string.Empty); + RestoreLabelPivot(); + } + else + { + if (inputType == InputType.Password) + { + text = string.Empty; + string str = "*"; + if (label.bitmapFont != null && label.bitmapFont.bmFont != null && label.bitmapFont.bmFont.GetGlyph(42) == null) + { + str = "x"; + } + int i = 0; + for (int length = value.Length; i < length; i++) + { + text += str; + } + } + else + { + text = value; + } + int num = isSelected ? Mathf.Min(text.Length, cursorPosition) : 0; + string str2 = text.Substring(0, num); + if (isSelected) + { + str2 += Input.compositionString; + } + text = str2 + text.Substring(num, text.Length - num); + if (isSelected && label.overflowMethod == UILabel.Overflow.ClampContent && label.maxLineCount == 1) + { + int num2 = label.CalculateOffsetToFit(text); + if (num2 == 0) + { + mDrawStart = 0; + RestoreLabelPivot(); + } + else if (num < mDrawStart) + { + mDrawStart = num; + SetPivotToLeft(); + } + else if (num2 < mDrawStart) + { + mDrawStart = num2; + SetPivotToLeft(); + } + else + { + num2 = label.CalculateOffsetToFit(text.Substring(0, num)); + if (num2 > mDrawStart) + { + mDrawStart = num2; + SetPivotToRight(); + } + } + if (mDrawStart != 0) + { + text = text.Substring(mDrawStart, text.Length - mDrawStart); + } + } + else + { + mDrawStart = 0; + RestoreLabelPivot(); + } + } + label.text = text; + if (isSelected) + { + int num3 = mSelectionStart - mDrawStart; + int num4 = mSelectionEnd - mDrawStart; + if (mBlankTex == null) + { + mBlankTex = new Texture2D(2, 2, TextureFormat.ARGB32, mipmap: false); + for (int j = 0; j < 2; j++) + { + for (int k = 0; k < 2; k++) + { + mBlankTex.SetPixel(k, j, Color.white); + } + } + mBlankTex.Apply(); + } + if (num3 != num4) + { + if (mHighlight == null) + { + mHighlight = NGUITools.AddWidget(label.cachedGameObject); + mHighlight.name = "Input Highlight"; + mHighlight.mainTexture = mBlankTex; + mHighlight.fillGeometry = false; + mHighlight.pivot = label.pivot; + mHighlight.SetAnchor(label.cachedTransform); + } + else + { + mHighlight.pivot = label.pivot; + mHighlight.mainTexture = mBlankTex; + mHighlight.MarkAsChanged(); + mHighlight.enabled = true; + } + } + if (mCaret == null) + { + mCaret = NGUITools.AddWidget(label.cachedGameObject); + mCaret.name = "Input Caret"; + mCaret.mainTexture = mBlankTex; + mCaret.fillGeometry = false; + mCaret.pivot = label.pivot; + mCaret.SetAnchor(label.cachedTransform); + } + else + { + mCaret.pivot = label.pivot; + mCaret.mainTexture = mBlankTex; + mCaret.MarkAsChanged(); + mCaret.enabled = true; + } + if (num3 != num4) + { + label.PrintOverlay(num3, num4, mCaret.geometry, mHighlight.geometry, caretColor, selectionColor); + mHighlight.enabled = mHighlight.geometry.hasVertices; + } + else + { + label.PrintOverlay(num3, num4, mCaret.geometry, null, caretColor, selectionColor); + if (mHighlight != null) + { + mHighlight.enabled = false; + } + } + mNextBlink = RealTime.time + 0.5f; + mLastAlpha = label.finalAlpha; + } + else + { + Cleanup(); + } + } + } + + protected void SetPivotToLeft() + { + Vector2 pivotOffset = NGUIMath.GetPivotOffset(mPivot); + pivotOffset.x = 0f; + label.pivot = NGUIMath.GetPivot(pivotOffset); + } + + protected void SetPivotToRight() + { + Vector2 pivotOffset = NGUIMath.GetPivotOffset(mPivot); + pivotOffset.x = 1f; + label.pivot = NGUIMath.GetPivot(pivotOffset); + } + + protected void RestoreLabelPivot() + { + if (label != null && label.pivot != mPivot) + { + label.pivot = mPivot; + } + } + + protected char Validate(string text, int pos, char ch) + { + if (validation == Validation.None || !base.enabled) + { + return ch; + } + if (validation == Validation.Integer) + { + if (ch >= '0' && ch <= '9') + { + return ch; + } + if (ch == '-' && pos == 0 && !text.Contains("-")) + { + return ch; + } + } + else if (validation == Validation.Float) + { + if (ch >= '0' && ch <= '9') + { + return ch; + } + if (ch == '-' && pos == 0 && !text.Contains("-")) + { + return ch; + } + if (ch == '.' && !text.Contains(".")) + { + return ch; + } + } + else if (validation == Validation.Alphanumeric) + { + if (ch >= 'A' && ch <= 'Z') + { + return ch; + } + if (ch >= 'a' && ch <= 'z') + { + return ch; + } + if (ch >= '0' && ch <= '9') + { + return ch; + } + } + else if (validation == Validation.Username) + { + if (ch >= 'A' && ch <= 'Z') + { + return (char)(ch - 65 + 97); + } + if (ch >= 'a' && ch <= 'z') + { + return ch; + } + if (ch >= '0' && ch <= '9') + { + return ch; + } + } + else if (validation == Validation.Name) + { + char c = (text.Length <= 0) ? ' ' : text[Mathf.Clamp(pos, 0, text.Length - 1)]; + char c2 = (text.Length <= 0) ? '\n' : text[Mathf.Clamp(pos + 1, 0, text.Length - 1)]; + if (ch >= 'a' && ch <= 'z') + { + if (c == ' ') + { + return (char)(ch - 97 + 65); + } + return ch; + } + if (ch >= 'A' && ch <= 'Z') + { + if (c != ' ' && c != '\'') + { + return (char)(ch - 65 + 97); + } + return ch; + } + switch (ch) + { + case '\'': + if (c != ' ' && c != '\'' && c2 != '\'' && !text.Contains("'")) + { + return ch; + } + break; + case ' ': + if (c != ' ' && c != '\'' && c2 != ' ' && c2 != '\'') + { + return ch; + } + break; + } + } + return '\0'; + } + + protected void ExecuteOnChange() + { + if (current == null && EventDelegate.IsValid(onChange)) + { + current = this; + EventDelegate.Execute(onChange); + current = null; + } + } + + public void RemoveFocus() + { + isSelected = false; + } + + public void SaveValue() + { + SaveToPlayerPrefs(mValue); + } + + public void LoadValue() + { + if (!string.IsNullOrEmpty(savedAs)) + { + string text = mValue.Replace("\\n", "\n"); + mValue = string.Empty; + value = ((!PlayerPrefs.HasKey(savedAs)) ? text : PlayerPrefs.GetString(savedAs)); + } + } +} diff --git a/UIInputOnGUI.cs b/UIInputOnGUI.cs new file mode 100644 index 00000000..df202896 --- /dev/null +++ b/UIInputOnGUI.cs @@ -0,0 +1,22 @@ +using System; +using UnityEngine; + +[RequireComponent(typeof(UIInput))] +public class UIInputOnGUI : MonoBehaviour +{ + [NonSerialized] + private UIInput mInput; + + private void Awake() + { + mInput = GetComponent(); + } + + private void OnGUI() + { + if (Event.current.rawType == EventType.KeyDown) + { + mInput.ProcessEvent(Event.current); + } + } +} diff --git a/UIKeyBinding.cs b/UIKeyBinding.cs new file mode 100644 index 00000000..ddefa4c8 --- /dev/null +++ b/UIKeyBinding.cs @@ -0,0 +1,124 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Key Binding")] +public class UIKeyBinding : MonoBehaviour +{ + public enum Action + { + PressAndClick, + Select, + All + } + + public enum Modifier + { + None, + Shift, + Control, + Alt + } + + public KeyCode keyCode; + + public Modifier modifier; + + public Action action; + + private bool mIgnoreUp; + + private bool mIsInput; + + private bool mPress; + + private void Start() + { + UIInput component = GetComponent(); + mIsInput = (component != null); + if (component != null) + { + EventDelegate.Add(component.onSubmit, OnSubmit); + } + } + + private void OnSubmit() + { + if (UICamera.currentKey == keyCode && IsModifierActive()) + { + mIgnoreUp = true; + } + } + + private bool IsModifierActive() + { + if (modifier == Modifier.None) + { + return true; + } + if (modifier == Modifier.Alt) + { + if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) + { + return true; + } + } + else if (modifier == Modifier.Control) + { + if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) + { + return true; + } + } + else if (modifier == Modifier.Shift && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))) + { + return true; + } + return false; + } + + private void Update() + { + if (keyCode != 0 && IsModifierActive()) + { + if (action == Action.PressAndClick || action == Action.All) + { + if (UICamera.inputHasFocus) + { + return; + } + UICamera.currentTouch = UICamera.controller; + UICamera.currentScheme = UICamera.ControlScheme.Mouse; + UICamera.currentTouch.current = base.gameObject; + if (Input.GetKeyDown(keyCode)) + { + mPress = true; + UICamera.Notify(base.gameObject, "OnPress", true); + } + if (Input.GetKeyUp(keyCode)) + { + UICamera.Notify(base.gameObject, "OnPress", false); + if (mPress) + { + UICamera.Notify(base.gameObject, "OnClick", null); + mPress = false; + } + } + UICamera.currentTouch.current = null; + } + if ((action == Action.Select || action == Action.All) && Input.GetKeyUp(keyCode)) + { + if (mIsInput) + { + if (!mIgnoreUp && !UICamera.inputHasFocus) + { + UICamera.selectedObject = base.gameObject; + } + mIgnoreUp = false; + } + else + { + UICamera.selectedObject = base.gameObject; + } + } + } + } +} diff --git a/UIKeyNavigation.cs b/UIKeyNavigation.cs new file mode 100644 index 00000000..3c3cf33a --- /dev/null +++ b/UIKeyNavigation.cs @@ -0,0 +1,217 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Key Navigation")] +public class UIKeyNavigation : MonoBehaviour +{ + public enum Constraint + { + None, + Vertical, + Horizontal, + Explicit + } + + public static BetterList list = new BetterList(); + + public Constraint constraint; + + public GameObject onUp; + + public GameObject onDown; + + public GameObject onLeft; + + public GameObject onRight; + + public GameObject onClick; + + public bool startsSelected; + + protected virtual void OnEnable() + { + list.Add(this); + if (startsSelected && (UICamera.selectedObject == null || !NGUITools.GetActive(UICamera.selectedObject))) + { + UICamera.currentScheme = UICamera.ControlScheme.Controller; + UICamera.selectedObject = base.gameObject; + } + } + + protected virtual void OnDisable() + { + list.Remove(this); + } + + protected GameObject GetLeft() + { + if (NGUITools.GetActive(onLeft)) + { + return onLeft; + } + if (constraint == Constraint.Vertical || constraint == Constraint.Explicit) + { + return null; + } + return Get(Vector3.left, horizontal: true); + } + + private GameObject GetRight() + { + if (NGUITools.GetActive(onRight)) + { + return onRight; + } + if (constraint == Constraint.Vertical || constraint == Constraint.Explicit) + { + return null; + } + return Get(Vector3.right, horizontal: true); + } + + protected GameObject GetUp() + { + if (NGUITools.GetActive(onUp)) + { + return onUp; + } + if (constraint == Constraint.Horizontal || constraint == Constraint.Explicit) + { + return null; + } + return Get(Vector3.up, horizontal: false); + } + + protected GameObject GetDown() + { + if (NGUITools.GetActive(onDown)) + { + return onDown; + } + if (constraint == Constraint.Horizontal || constraint == Constraint.Explicit) + { + return null; + } + return Get(Vector3.down, horizontal: false); + } + + protected GameObject Get(Vector3 myDir, bool horizontal) + { + Transform transform = base.transform; + myDir = transform.TransformDirection(myDir); + Vector3 center = GetCenter(base.gameObject); + float num = 3.40282347E+38f; + GameObject result = null; + for (int i = 0; i < list.size; i++) + { + UIKeyNavigation uIKeyNavigation = list[i]; + if (!(uIKeyNavigation == this)) + { + UIButton component = uIKeyNavigation.GetComponent(); + if (!(component != null) || component.isEnabled) + { + Vector3 direction = GetCenter(uIKeyNavigation.gameObject) - center; + float num2 = Vector3.Dot(myDir, direction.normalized); + if (!(num2 < 0.707f)) + { + direction = transform.InverseTransformDirection(direction); + if (horizontal) + { + direction.y *= 2f; + } + else + { + direction.x *= 2f; + } + float sqrMagnitude = direction.sqrMagnitude; + if (!(sqrMagnitude > num)) + { + result = uIKeyNavigation.gameObject; + num = sqrMagnitude; + } + } + } + } + } + return result; + } + + protected static Vector3 GetCenter(GameObject go) + { + UIWidget component = go.GetComponent(); + if (component != null) + { + Vector3[] worldCorners = component.worldCorners; + return (worldCorners[0] + worldCorners[2]) * 0.5f; + } + return go.transform.position; + } + + protected virtual void OnKey(KeyCode key) + { + if (NGUITools.GetActive(this)) + { + GameObject gameObject = null; + switch (key) + { + case KeyCode.LeftArrow: + gameObject = GetLeft(); + break; + case KeyCode.RightArrow: + gameObject = GetRight(); + break; + case KeyCode.UpArrow: + gameObject = GetUp(); + break; + case KeyCode.DownArrow: + gameObject = GetDown(); + break; + case KeyCode.Tab: + if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) + { + gameObject = GetLeft(); + if (gameObject == null) + { + gameObject = GetUp(); + } + if (gameObject == null) + { + gameObject = GetDown(); + } + if (gameObject == null) + { + gameObject = GetRight(); + } + } + else + { + gameObject = GetRight(); + if (gameObject == null) + { + gameObject = GetDown(); + } + if (gameObject == null) + { + gameObject = GetUp(); + } + if (gameObject == null) + { + gameObject = GetLeft(); + } + } + break; + } + if (gameObject != null) + { + UICamera.selectedObject = gameObject; + } + } + } + + protected virtual void OnClick() + { + if (NGUITools.GetActive(this) && NGUITools.GetActive(onClick)) + { + UICamera.selectedObject = onClick; + } + } +} diff --git a/UILabel.cs b/UILabel.cs new file mode 100644 index 00000000..02dac503 --- /dev/null +++ b/UILabel.cs @@ -0,0 +1,1595 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Label")] +[ExecuteInEditMode] +public class UILabel : UIWidget +{ + public enum Effect + { + None, + Shadow, + Outline + } + + public enum Overflow + { + ShrinkContent, + ClampContent, + ResizeFreely, + ResizeHeight + } + + public enum Crispness + { + Never, + OnDesktop, + Always + } + + public Crispness keepCrispWhenShrunk = Crispness.OnDesktop; + + [HideInInspector] + [SerializeField] + private Font mTrueTypeFont; + + [HideInInspector] + [SerializeField] + private UIFont mFont; + + [HideInInspector] + [Multiline(6)] + [SerializeField] + private string mText = string.Empty; + + [HideInInspector] + [SerializeField] + private int mFontSize = 16; + + [HideInInspector] + [SerializeField] + private FontStyle mFontStyle; + + [HideInInspector] + [SerializeField] + private NGUIText.Alignment mAlignment; + + [HideInInspector] + [SerializeField] + private bool mEncoding = true; + + [HideInInspector] + [SerializeField] + private int mMaxLineCount; + + [HideInInspector] + [SerializeField] + private Effect mEffectStyle; + + [HideInInspector] + [SerializeField] + private Color mEffectColor = Color.black; + + [HideInInspector] + [SerializeField] + private NGUIText.SymbolStyle mSymbols = NGUIText.SymbolStyle.Normal; + + [HideInInspector] + [SerializeField] + private Vector2 mEffectDistance = Vector2.one; + + [HideInInspector] + [SerializeField] + private Overflow mOverflow; + + [HideInInspector] + [SerializeField] + private Material mMaterial; + + [HideInInspector] + [SerializeField] + private bool mApplyGradient; + + [HideInInspector] + [SerializeField] + private Color mGradientTop = Color.white; + + [HideInInspector] + [SerializeField] + private Color mGradientBottom = new Color(0.7f, 0.7f, 0.7f); + + [HideInInspector] + [SerializeField] + private int mSpacingX; + + [HideInInspector] + [SerializeField] + private int mSpacingY; + + [HideInInspector] + [SerializeField] + private bool mShrinkToFit; + + [HideInInspector] + [SerializeField] + private int mMaxLineWidth; + + [HideInInspector] + [SerializeField] + private int mMaxLineHeight; + + [HideInInspector] + [SerializeField] + private float mLineWidth; + + [HideInInspector] + [SerializeField] + private bool mMultiline = true; + + [NonSerialized] + private Font mActiveTTF; + + private float mDensity = 1f; + + private bool mShouldBeProcessed = true; + + private string mProcessedText; + + private bool mPremultiply; + + private Vector2 mCalculatedSize = Vector2.zero; + + private float mScale = 1f; + + private int mPrintedSize; + + private int mLastWidth; + + private int mLastHeight; + + private static BetterList mList = new BetterList(); + + private static Dictionary mFontUsage = new Dictionary(); + + private static BetterList mTempVerts = new BetterList(); + + private static BetterList mTempIndices = new BetterList(); + + private bool shouldBeProcessed + { + get + { + return mShouldBeProcessed; + } + set + { + if (value) + { + mChanged = true; + mShouldBeProcessed = true; + } + else + { + mShouldBeProcessed = false; + } + } + } + + public override bool isAnchoredHorizontally => base.isAnchoredHorizontally || mOverflow == Overflow.ResizeFreely; + + public override bool isAnchoredVertically => base.isAnchoredVertically || mOverflow == Overflow.ResizeFreely || mOverflow == Overflow.ResizeHeight; + + public override Material material + { + get + { + if (mMaterial != null) + { + return mMaterial; + } + if (mFont != null) + { + return mFont.material; + } + if (mTrueTypeFont != null) + { + return mTrueTypeFont.material; + } + return null; + } + set + { + if (mMaterial != value) + { + RemoveFromPanel(); + mMaterial = value; + MarkAsChanged(); + } + } + } + + [Obsolete("Use UILabel.bitmapFont instead")] + public UIFont font + { + get + { + return bitmapFont; + } + set + { + bitmapFont = value; + } + } + + public UIFont bitmapFont + { + get + { + return mFont; + } + set + { + if (mFont != value) + { + RemoveFromPanel(); + mFont = value; + mTrueTypeFont = null; + MarkAsChanged(); + } + } + } + + public Font trueTypeFont + { + get + { + if (mTrueTypeFont != null) + { + return mTrueTypeFont; + } + return (!(mFont != null)) ? null : mFont.dynamicFont; + } + set + { + if (mTrueTypeFont != value) + { + SetActiveFont(null); + RemoveFromPanel(); + mTrueTypeFont = value; + shouldBeProcessed = true; + mFont = null; + SetActiveFont(value); + ProcessAndRequest(); + if (mActiveTTF != null) + { + base.MarkAsChanged(); + } + } + } + } + + public UnityEngine.Object ambigiousFont + { + get + { + return (!(mFont != null)) ? ((UnityEngine.Object)mTrueTypeFont) : ((UnityEngine.Object)mFont); + } + set + { + UIFont uIFont = value as UIFont; + if (uIFont != null) + { + bitmapFont = uIFont; + } + else + { + trueTypeFont = (value as Font); + } + } + } + + public string text + { + get + { + return mText; + } + set + { + if (!(mText == value)) + { + if (string.IsNullOrEmpty(value)) + { + if (!string.IsNullOrEmpty(mText)) + { + mText = string.Empty; + MarkAsChanged(); + ProcessAndRequest(); + } + } + else if (mText != value) + { + mText = value; + MarkAsChanged(); + ProcessAndRequest(); + } + if (autoResizeBoxCollider) + { + ResizeCollider(); + } + } + } + } + + public int defaultFontSize => (trueTypeFont != null) ? mFontSize : ((!(mFont != null)) ? 16 : mFont.defaultSize); + + public int fontSize + { + get + { + return mFontSize; + } + set + { + value = Mathf.Clamp(value, 0, 256); + if (mFontSize != value) + { + mFontSize = value; + shouldBeProcessed = true; + ProcessAndRequest(); + } + } + } + + public FontStyle fontStyle + { + get + { + return mFontStyle; + } + set + { + if (mFontStyle != value) + { + mFontStyle = value; + shouldBeProcessed = true; + ProcessAndRequest(); + } + } + } + + public NGUIText.Alignment alignment + { + get + { + return mAlignment; + } + set + { + if (mAlignment != value) + { + mAlignment = value; + shouldBeProcessed = true; + ProcessAndRequest(); + } + } + } + + public bool applyGradient + { + get + { + return mApplyGradient; + } + set + { + if (mApplyGradient != value) + { + mApplyGradient = value; + MarkAsChanged(); + } + } + } + + public Color gradientTop + { + get + { + return mGradientTop; + } + set + { + if (mGradientTop != value) + { + mGradientTop = value; + if (mApplyGradient) + { + MarkAsChanged(); + } + } + } + } + + public Color gradientBottom + { + get + { + return mGradientBottom; + } + set + { + if (mGradientBottom != value) + { + mGradientBottom = value; + if (mApplyGradient) + { + MarkAsChanged(); + } + } + } + } + + public int spacingX + { + get + { + return mSpacingX; + } + set + { + if (mSpacingX != value) + { + mSpacingX = value; + MarkAsChanged(); + } + } + } + + public int spacingY + { + get + { + return mSpacingY; + } + set + { + if (mSpacingY != value) + { + mSpacingY = value; + MarkAsChanged(); + } + } + } + + private bool keepCrisp + { + get + { + if (trueTypeFont != null && keepCrispWhenShrunk != 0) + { + return true; + } + return false; + } + } + + public bool supportEncoding + { + get + { + return mEncoding; + } + set + { + if (mEncoding != value) + { + mEncoding = value; + shouldBeProcessed = true; + } + } + } + + public NGUIText.SymbolStyle symbolStyle + { + get + { + return mSymbols; + } + set + { + if (mSymbols != value) + { + mSymbols = value; + shouldBeProcessed = true; + } + } + } + + public Overflow overflowMethod + { + get + { + return mOverflow; + } + set + { + if (mOverflow != value) + { + mOverflow = value; + shouldBeProcessed = true; + } + } + } + + [Obsolete("Use 'width' instead")] + public int lineWidth + { + get + { + return base.width; + } + set + { + base.width = value; + } + } + + [Obsolete("Use 'height' instead")] + public int lineHeight + { + get + { + return base.height; + } + set + { + base.height = value; + } + } + + public bool multiLine + { + get + { + return mMaxLineCount != 1; + } + set + { + if (mMaxLineCount != 1 != value) + { + mMaxLineCount = ((!value) ? 1 : 0); + shouldBeProcessed = true; + } + } + } + + public override Vector3[] localCorners + { + get + { + if (shouldBeProcessed) + { + ProcessText(); + } + return base.localCorners; + } + } + + public override Vector3[] worldCorners + { + get + { + if (shouldBeProcessed) + { + ProcessText(); + } + return base.worldCorners; + } + } + + public override Vector4 drawingDimensions + { + get + { + if (shouldBeProcessed) + { + ProcessText(); + } + return base.drawingDimensions; + } + } + + public int maxLineCount + { + get + { + return mMaxLineCount; + } + set + { + if (mMaxLineCount != value) + { + mMaxLineCount = Mathf.Max(value, 0); + shouldBeProcessed = true; + if (overflowMethod == Overflow.ShrinkContent) + { + MakePixelPerfect(); + } + } + } + } + + public Effect effectStyle + { + get + { + return mEffectStyle; + } + set + { + if (mEffectStyle != value) + { + mEffectStyle = value; + shouldBeProcessed = true; + } + } + } + + public Color effectColor + { + get + { + return mEffectColor; + } + set + { + if (mEffectColor != value) + { + mEffectColor = value; + if (mEffectStyle != 0) + { + shouldBeProcessed = true; + } + } + } + } + + public Vector2 effectDistance + { + get + { + return mEffectDistance; + } + set + { + if (mEffectDistance != value) + { + mEffectDistance = value; + shouldBeProcessed = true; + } + } + } + + [Obsolete("Use 'overflowMethod == UILabel.Overflow.ShrinkContent' instead")] + public bool shrinkToFit + { + get + { + return mOverflow == Overflow.ShrinkContent; + } + set + { + if (value) + { + overflowMethod = Overflow.ShrinkContent; + } + } + } + + public string processedText + { + get + { + if (mLastWidth != mWidth || mLastHeight != mHeight) + { + mLastWidth = mWidth; + mLastHeight = mHeight; + mShouldBeProcessed = true; + } + if (shouldBeProcessed) + { + ProcessText(); + } + return mProcessedText; + } + } + + public Vector2 printedSize + { + get + { + if (shouldBeProcessed) + { + ProcessText(); + } + return mCalculatedSize; + } + } + + public override Vector2 localSize + { + get + { + if (shouldBeProcessed) + { + ProcessText(); + } + return base.localSize; + } + } + + private bool isValid => mFont != null || mTrueTypeFont != null; + + protected override void OnInit() + { + base.OnInit(); + mList.Add(this); + SetActiveFont(trueTypeFont); + } + + protected override void OnDisable() + { + SetActiveFont(null); + mList.Remove(this); + base.OnDisable(); + } + + protected void SetActiveFont(Font fnt) + { + if (mActiveTTF != fnt) + { + if (mActiveTTF != null) + { + if (mFontUsage.TryGetValue(mActiveTTF, out int value)) + { + value = Mathf.Max(0, --value); + if (value == 0) + { + mActiveTTF.textureRebuildCallback = null; + mFontUsage.Remove(mActiveTTF); + } + else + { + mFontUsage[mActiveTTF] = value; + } + } + else + { + mActiveTTF.textureRebuildCallback = null; + } + } + mActiveTTF = fnt; + if (mActiveTTF != null) + { + int value2 = 0; + if (!mFontUsage.TryGetValue(mActiveTTF, out value2)) + { + mActiveTTF.textureRebuildCallback = OnFontTextureChanged; + } + value2 = (mFontUsage[mActiveTTF] = value2 + 1); + } + } + } + + private static void OnFontTextureChanged() + { + for (int i = 0; i < mList.size; i++) + { + UILabel uILabel = mList[i]; + if (uILabel != null) + { + Font trueTypeFont = uILabel.trueTypeFont; + if (trueTypeFont != null) + { + trueTypeFont.RequestCharactersInTexture(uILabel.mText, uILabel.mPrintedSize, uILabel.mFontStyle); + } + } + } + for (int j = 0; j < mList.size; j++) + { + UILabel uILabel2 = mList[j]; + if (uILabel2 != null) + { + Font trueTypeFont2 = uILabel2.trueTypeFont; + if (trueTypeFont2 != null) + { + uILabel2.RemoveFromPanel(); + uILabel2.CreatePanel(); + } + } + } + } + + public override Vector3[] GetSides(Transform relativeTo) + { + if (shouldBeProcessed) + { + ProcessText(); + } + return base.GetSides(relativeTo); + } + + protected override void UpgradeFrom265() + { + ProcessText(legacyMode: true, full: true); + if (mShrinkToFit) + { + overflowMethod = Overflow.ShrinkContent; + mMaxLineCount = 0; + } + if (mMaxLineWidth != 0) + { + base.width = mMaxLineWidth; + overflowMethod = ((mMaxLineCount > 0) ? Overflow.ResizeHeight : Overflow.ShrinkContent); + } + else + { + overflowMethod = Overflow.ResizeFreely; + } + if (mMaxLineHeight != 0) + { + base.height = mMaxLineHeight; + } + if (mFont != null) + { + int defaultSize = mFont.defaultSize; + if (base.height < defaultSize) + { + base.height = defaultSize; + } + fontSize = defaultSize; + } + mMaxLineWidth = 0; + mMaxLineHeight = 0; + mShrinkToFit = false; + NGUITools.UpdateWidgetCollider(base.gameObject, considerInactive: true); + } + + protected override void OnAnchor() + { + if (mOverflow == Overflow.ResizeFreely) + { + if (base.isFullyAnchored) + { + mOverflow = Overflow.ShrinkContent; + } + } + else if (mOverflow == Overflow.ResizeHeight && topAnchor.target != null && bottomAnchor.target != null) + { + mOverflow = Overflow.ShrinkContent; + } + base.OnAnchor(); + } + + private void ProcessAndRequest() + { + if (ambigiousFont != null) + { + ProcessText(); + } + } + + protected override void OnStart() + { + base.OnStart(); + if (mLineWidth > 0f) + { + mMaxLineWidth = Mathf.RoundToInt(mLineWidth); + mLineWidth = 0f; + } + if (!mMultiline) + { + mMaxLineCount = 1; + mMultiline = true; + } + mPremultiply = (material != null && material.shader != null && material.shader.name.Contains("Premultiplied")); + ProcessAndRequest(); + } + + public override void MarkAsChanged() + { + shouldBeProcessed = true; + base.MarkAsChanged(); + } + + public void ProcessText() + { + ProcessText(legacyMode: false, full: true); + } + + private void ProcessText(bool legacyMode, bool full) + { + if (isValid) + { + mChanged = true; + shouldBeProcessed = false; + float num = mDrawRegion.z - mDrawRegion.x; + float num2 = mDrawRegion.w - mDrawRegion.y; + NGUIText.rectWidth = ((!legacyMode) ? base.width : ((mMaxLineWidth == 0) ? 1000000 : mMaxLineWidth)); + NGUIText.rectHeight = ((!legacyMode) ? base.height : ((mMaxLineHeight == 0) ? 1000000 : mMaxLineHeight)); + NGUIText.regionWidth = ((num == 1f) ? NGUIText.rectWidth : Mathf.RoundToInt((float)NGUIText.rectWidth * num)); + NGUIText.regionHeight = ((num2 == 1f) ? NGUIText.rectHeight : Mathf.RoundToInt((float)NGUIText.rectHeight * num2)); + int value; + if (legacyMode) + { + Vector3 localScale = base.cachedTransform.localScale; + value = Mathf.RoundToInt(localScale.x); + } + else + { + value = defaultFontSize; + } + mPrintedSize = Mathf.Abs(value); + mScale = 1f; + if (NGUIText.regionWidth < 1 || NGUIText.regionHeight < 0) + { + mProcessedText = string.Empty; + } + else + { + bool flag = trueTypeFont != null; + if (flag && this.keepCrisp) + { + UIRoot root = base.root; + if (root != null) + { + mDensity = ((!(root != null)) ? 1f : root.pixelSizeAdjustment); + } + } + else + { + mDensity = 1f; + } + if (full) + { + UpdateNGUIText(); + } + if (mOverflow == Overflow.ResizeFreely) + { + NGUIText.rectWidth = 1000000; + NGUIText.regionWidth = 1000000; + } + if (mOverflow == Overflow.ResizeFreely || mOverflow == Overflow.ResizeHeight) + { + NGUIText.rectHeight = 1000000; + NGUIText.regionHeight = 1000000; + } + if (mPrintedSize > 0) + { + bool keepCrisp = this.keepCrisp; + int num3; + for (num3 = mPrintedSize; num3 > 0; num3--) + { + if (keepCrisp) + { + mPrintedSize = num3; + NGUIText.fontSize = mPrintedSize; + } + else + { + mScale = (float)num3 / (float)mPrintedSize; + NGUIText.fontScale = ((!flag) ? ((float)mFontSize / (float)mFont.defaultSize * mScale) : mScale); + } + NGUIText.Update(request: false); + bool flag2 = NGUIText.WrapText(mText, out mProcessedText, keepCharCount: true); + if (mOverflow != 0 || flag2) + { + if (mOverflow == Overflow.ResizeFreely) + { + mCalculatedSize = NGUIText.CalculatePrintedSize(mProcessedText); + mWidth = Mathf.Max(minWidth, Mathf.RoundToInt(mCalculatedSize.x)); + if (num != 1f) + { + mWidth = Mathf.RoundToInt((float)mWidth / num); + } + mHeight = Mathf.Max(minHeight, Mathf.RoundToInt(mCalculatedSize.y)); + if (num2 != 1f) + { + mHeight = Mathf.RoundToInt((float)mHeight / num2); + } + if ((mWidth & 1) == 1) + { + mWidth++; + } + if ((mHeight & 1) == 1) + { + mHeight++; + } + } + else if (mOverflow == Overflow.ResizeHeight) + { + mCalculatedSize = NGUIText.CalculatePrintedSize(mProcessedText); + mHeight = Mathf.Max(minHeight, Mathf.RoundToInt(mCalculatedSize.y)); + if (num2 != 1f) + { + mHeight = Mathf.RoundToInt((float)mHeight / num2); + } + if ((mHeight & 1) == 1) + { + mHeight++; + } + } + else + { + mCalculatedSize = NGUIText.CalculatePrintedSize(mProcessedText); + } + if (legacyMode) + { + base.width = Mathf.RoundToInt(mCalculatedSize.x); + base.height = Mathf.RoundToInt(mCalculatedSize.y); + base.cachedTransform.localScale = Vector3.one; + } + break; + } + if (--num3 <= 1) + { + break; + } + } + } + else + { + base.cachedTransform.localScale = Vector3.one; + mProcessedText = string.Empty; + mScale = 1f; + } + if (full) + { + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + } + } + } + } + + public override void MakePixelPerfect() + { + if (ambigiousFont != null) + { + Vector3 localPosition = base.cachedTransform.localPosition; + localPosition.x = (float)Mathf.RoundToInt(localPosition.x); + localPosition.y = (float)Mathf.RoundToInt(localPosition.y); + localPosition.z = (float)Mathf.RoundToInt(localPosition.z); + base.cachedTransform.localPosition = localPosition; + base.cachedTransform.localScale = Vector3.one; + if (mOverflow == Overflow.ResizeFreely) + { + AssumeNaturalSize(); + } + else + { + int width = base.width; + int height = base.height; + Overflow overflow = mOverflow; + if (overflow != Overflow.ResizeHeight) + { + mWidth = 100000; + } + mHeight = 100000; + mOverflow = Overflow.ShrinkContent; + ProcessText(legacyMode: false, full: true); + mOverflow = overflow; + int a = Mathf.RoundToInt(mCalculatedSize.x); + int a2 = Mathf.RoundToInt(mCalculatedSize.y); + a = Mathf.Max(a, base.minWidth); + a2 = Mathf.Max(a2, base.minHeight); + mWidth = Mathf.Max(width, a); + mHeight = Mathf.Max(height, a2); + MarkAsChanged(); + } + } + else + { + base.MakePixelPerfect(); + } + } + + public void AssumeNaturalSize() + { + if (ambigiousFont != null) + { + mWidth = 100000; + mHeight = 100000; + ProcessText(legacyMode: false, full: true); + mWidth = Mathf.RoundToInt(mCalculatedSize.x); + mHeight = Mathf.RoundToInt(mCalculatedSize.y); + if ((mWidth & 1) == 1) + { + mWidth++; + } + if ((mHeight & 1) == 1) + { + mHeight++; + } + MarkAsChanged(); + } + } + + [Obsolete("Use UILabel.GetCharacterAtPosition instead")] + public int GetCharacterIndex(Vector3 worldPos) + { + return GetCharacterIndexAtPosition(worldPos, precise: false); + } + + [Obsolete("Use UILabel.GetCharacterAtPosition instead")] + public int GetCharacterIndex(Vector2 localPos) + { + return GetCharacterIndexAtPosition(localPos, precise: false); + } + + public int GetCharacterIndexAtPosition(Vector3 worldPos, bool precise) + { + Vector2 localPos = base.cachedTransform.InverseTransformPoint(worldPos); + return GetCharacterIndexAtPosition(localPos, precise); + } + + public int GetCharacterIndexAtPosition(Vector2 localPos, bool precise) + { + if (isValid) + { + string processedText = this.processedText; + if (string.IsNullOrEmpty(processedText)) + { + return 0; + } + UpdateNGUIText(); + if (precise) + { + NGUIText.PrintExactCharacterPositions(processedText, mTempVerts, mTempIndices); + } + else + { + NGUIText.PrintApproximateCharacterPositions(processedText, mTempVerts, mTempIndices); + } + if (mTempVerts.size > 0) + { + ApplyOffset(mTempVerts, 0); + int result = (!precise) ? NGUIText.GetApproximateCharacterIndex(mTempVerts, mTempIndices, localPos) : NGUIText.GetExactCharacterIndex(mTempVerts, mTempIndices, localPos); + mTempVerts.Clear(); + mTempIndices.Clear(); + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + return result; + } + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + } + return 0; + } + + public string GetWordAtPosition(Vector3 worldPos) + { + int characterIndexAtPosition = GetCharacterIndexAtPosition(worldPos, precise: true); + return GetWordAtCharacterIndex(characterIndexAtPosition); + } + + public string GetWordAtPosition(Vector2 localPos) + { + int characterIndexAtPosition = GetCharacterIndexAtPosition(localPos, precise: true); + return GetWordAtCharacterIndex(characterIndexAtPosition); + } + + public string GetWordAtCharacterIndex(int characterIndex) + { + if (characterIndex != -1 && characterIndex < mText.Length) + { + int num = mText.LastIndexOfAny(new char[2] + { + ' ', + '\n' + }, characterIndex) + 1; + int num2 = mText.IndexOfAny(new char[4] + { + ' ', + '\n', + ',', + '.' + }, characterIndex); + if (num2 == -1) + { + num2 = mText.Length; + } + if (num != num2) + { + int num3 = num2 - num; + if (num3 > 0) + { + string text = mText.Substring(num, num3); + return NGUIText.StripSymbols(text); + } + } + } + return null; + } + + public string GetUrlAtPosition(Vector3 worldPos) + { + return GetUrlAtCharacterIndex(GetCharacterIndexAtPosition(worldPos, precise: true)); + } + + public string GetUrlAtPosition(Vector2 localPos) + { + return GetUrlAtCharacterIndex(GetCharacterIndexAtPosition(localPos, precise: true)); + } + + public string GetUrlAtCharacterIndex(int characterIndex) + { + if (characterIndex != -1 && characterIndex < mText.Length - 6) + { + int num = (mText[characterIndex] != '[' || mText[characterIndex + 1] != 'u' || mText[characterIndex + 2] != 'r' || mText[characterIndex + 3] != 'l' || mText[characterIndex + 4] != '=') ? mText.LastIndexOf("[url=", characterIndex) : characterIndex; + if (num == -1) + { + return null; + } + num += 5; + int num2 = mText.IndexOf("]", num); + if (num2 == -1) + { + return null; + } + int num3 = mText.IndexOf("[/url]", num2); + if (num3 == -1 || characterIndex <= num3) + { + return mText.Substring(num, num2 - num); + } + } + return null; + } + + public int GetCharacterIndex(int currentIndex, KeyCode key) + { + if (isValid) + { + string processedText = this.processedText; + if (string.IsNullOrEmpty(processedText)) + { + return 0; + } + int defaultFontSize = this.defaultFontSize; + UpdateNGUIText(); + NGUIText.PrintApproximateCharacterPositions(processedText, mTempVerts, mTempIndices); + if (mTempVerts.size > 0) + { + ApplyOffset(mTempVerts, 0); + for (int i = 0; i < mTempIndices.size; i++) + { + if (mTempIndices[i] == currentIndex) + { + Vector2 pos = mTempVerts[i]; + switch (key) + { + case KeyCode.UpArrow: + pos.y += (float)(defaultFontSize + spacingY); + break; + case KeyCode.DownArrow: + pos.y -= (float)(defaultFontSize + spacingY); + break; + case KeyCode.Home: + pos.x -= 1000f; + break; + case KeyCode.End: + pos.x += 1000f; + break; + } + int approximateCharacterIndex = NGUIText.GetApproximateCharacterIndex(mTempVerts, mTempIndices, pos); + if (approximateCharacterIndex == currentIndex) + { + break; + } + mTempVerts.Clear(); + mTempIndices.Clear(); + return approximateCharacterIndex; + } + } + mTempVerts.Clear(); + mTempIndices.Clear(); + } + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + switch (key) + { + case KeyCode.UpArrow: + case KeyCode.Home: + return 0; + case KeyCode.DownArrow: + case KeyCode.End: + return processedText.Length; + } + } + return currentIndex; + } + + public void PrintOverlay(int start, int end, UIGeometry caret, UIGeometry highlight, Color caretColor, Color highlightColor) + { + caret?.Clear(); + highlight?.Clear(); + if (isValid) + { + string processedText = this.processedText; + UpdateNGUIText(); + int size = caret.verts.size; + Vector2 item = new Vector2(0.5f, 0.5f); + float finalAlpha = base.finalAlpha; + if (highlight != null && start != end) + { + int size2 = highlight.verts.size; + NGUIText.PrintCaretAndSelection(processedText, start, end, caret.verts, highlight.verts); + if (highlight.verts.size > size2) + { + ApplyOffset(highlight.verts, size2); + Color32 item2 = new Color(highlightColor.r, highlightColor.g, highlightColor.b, highlightColor.a * finalAlpha); + for (int i = size2; i < highlight.verts.size; i++) + { + highlight.uvs.Add(item); + highlight.cols.Add(item2); + } + } + } + else + { + NGUIText.PrintCaretAndSelection(processedText, start, end, caret.verts, null); + } + ApplyOffset(caret.verts, size); + Color32 item3 = new Color(caretColor.r, caretColor.g, caretColor.b, caretColor.a * finalAlpha); + for (int j = size; j < caret.verts.size; j++) + { + caret.uvs.Add(item); + caret.cols.Add(item3); + } + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + } + } + + public override void OnFill(BetterList verts, BetterList uvs, BetterList cols) + { + if (isValid) + { + int num = verts.size; + Color color = base.color; + color.a = finalAlpha; + if (mFont != null && mFont.premultipliedAlphaShader) + { + color = NGUITools.ApplyPMA(color); + } + if (QualitySettings.activeColorSpace == ColorSpace.Linear) + { + color.r = Mathf.Pow(color.r, 2.2f); + color.g = Mathf.Pow(color.g, 2.2f); + color.b = Mathf.Pow(color.b, 2.2f); + } + string processedText = this.processedText; + int size = verts.size; + UpdateNGUIText(); + NGUIText.tint = color; + NGUIText.Print(processedText, verts, uvs, cols); + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + Vector2 vector = ApplyOffset(verts, size); + if (!(mFont != null) || !mFont.packedFontShader) + { + if (effectStyle != 0) + { + int size2 = verts.size; + vector.x = mEffectDistance.x; + vector.y = mEffectDistance.y; + ApplyShadow(verts, uvs, cols, num, size2, vector.x, 0f - vector.y); + if (effectStyle == Effect.Outline) + { + num = size2; + size2 = verts.size; + ApplyShadow(verts, uvs, cols, num, size2, 0f - vector.x, vector.y); + num = size2; + size2 = verts.size; + ApplyShadow(verts, uvs, cols, num, size2, vector.x, vector.y); + num = size2; + size2 = verts.size; + ApplyShadow(verts, uvs, cols, num, size2, 0f - vector.x, 0f - vector.y); + } + } + if (onPostFill != null) + { + onPostFill(this, num, verts, uvs, cols); + } + } + } + } + + public Vector2 ApplyOffset(BetterList verts, int start) + { + Vector2 pivotOffset = base.pivotOffset; + float f = Mathf.Lerp(0f, (float)(-mWidth), pivotOffset.x); + float f2 = Mathf.Lerp((float)mHeight, 0f, pivotOffset.y) + Mathf.Lerp(mCalculatedSize.y - (float)mHeight, 0f, pivotOffset.y); + f = Mathf.Round(f); + f2 = Mathf.Round(f2); + for (int i = start; i < verts.size; i++) + { + verts.buffer[i].x += f; + verts.buffer[i].y += f2; + } + return new Vector2(f, f2); + } + + public void ApplyShadow(BetterList verts, BetterList uvs, BetterList cols, int start, int end, float x, float y) + { + Color color = mEffectColor; + color.a *= finalAlpha; + Color32 color2 = (!(bitmapFont != null) || !bitmapFont.premultipliedAlphaShader) ? color : NGUITools.ApplyPMA(color); + for (int i = start; i < end; i++) + { + verts.Add(verts.buffer[i]); + uvs.Add(uvs.buffer[i]); + cols.Add(cols.buffer[i]); + Vector3 vector = verts.buffer[i]; + vector.x += x; + vector.y += y; + verts.buffer[i] = vector; + Color32 color3 = cols.buffer[i]; + if (color3.a == 255) + { + cols.buffer[i] = color2; + } + else + { + Color color4 = color; + color4.a = (float)(int)color3.a / 255f * color.a; + cols.buffer[i] = ((!(bitmapFont != null) || !bitmapFont.premultipliedAlphaShader) ? color4 : NGUITools.ApplyPMA(color4)); + } + } + } + + public int CalculateOffsetToFit(string text) + { + UpdateNGUIText(); + NGUIText.encoding = false; + NGUIText.symbolStyle = NGUIText.SymbolStyle.None; + int result = NGUIText.CalculateOffsetToFit(text); + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + return result; + } + + public void SetCurrentProgress() + { + if (UIProgressBar.current != null) + { + text = UIProgressBar.current.value.ToString("F"); + } + } + + public void SetCurrentPercent() + { + if (UIProgressBar.current != null) + { + text = Mathf.RoundToInt(UIProgressBar.current.value * 100f) + "%"; + } + } + + public void SetCurrentSelection() + { + if (UIPopupList.current != null) + { + text = ((!UIPopupList.current.isLocalized) ? UIPopupList.current.value : Localization.Get(UIPopupList.current.value)); + } + } + + public bool Wrap(string text, out string final) + { + return Wrap(text, out final, 1000000); + } + + public bool Wrap(string text, out string final, int height) + { + UpdateNGUIText(); + NGUIText.rectHeight = height; + NGUIText.regionHeight = height; + bool result = NGUIText.WrapText(text, out final); + NGUIText.bitmapFont = null; + NGUIText.dynamicFont = null; + return result; + } + + public void UpdateNGUIText() + { + Font trueTypeFont = this.trueTypeFont; + bool flag = trueTypeFont != null; + NGUIText.fontSize = mPrintedSize; + NGUIText.fontStyle = mFontStyle; + NGUIText.rectWidth = mWidth; + NGUIText.rectHeight = mHeight; + NGUIText.regionWidth = Mathf.RoundToInt((float)mWidth * (mDrawRegion.z - mDrawRegion.x)); + NGUIText.regionHeight = Mathf.RoundToInt((float)mHeight * (mDrawRegion.w - mDrawRegion.y)); + NGUIText.gradient = (mApplyGradient && (mFont == null || !mFont.packedFontShader)); + NGUIText.gradientTop = mGradientTop; + NGUIText.gradientBottom = mGradientBottom; + NGUIText.encoding = mEncoding; + NGUIText.premultiply = mPremultiply; + NGUIText.symbolStyle = mSymbols; + NGUIText.maxLines = mMaxLineCount; + NGUIText.spacingX = (float)mSpacingX; + NGUIText.spacingY = (float)mSpacingY; + NGUIText.fontScale = ((!flag) ? ((float)mFontSize / (float)mFont.defaultSize * mScale) : mScale); + if (mFont != null) + { + NGUIText.bitmapFont = mFont; + while (true) + { + UIFont replacement = NGUIText.bitmapFont.replacement; + if (replacement == null) + { + break; + } + NGUIText.bitmapFont = replacement; + } + if (NGUIText.bitmapFont.isDynamic) + { + NGUIText.dynamicFont = NGUIText.bitmapFont.dynamicFont; + NGUIText.bitmapFont = null; + } + else + { + NGUIText.dynamicFont = null; + } + } + else + { + NGUIText.dynamicFont = trueTypeFont; + NGUIText.bitmapFont = null; + } + if (flag && keepCrisp) + { + UIRoot root = base.root; + if (root != null) + { + NGUIText.pixelDensity = ((!(root != null)) ? 1f : root.pixelSizeAdjustment); + } + } + else + { + NGUIText.pixelDensity = 1f; + } + if (mDensity != NGUIText.pixelDensity) + { + ProcessText(legacyMode: false, full: false); + NGUIText.rectWidth = mWidth; + NGUIText.rectHeight = mHeight; + NGUIText.regionWidth = Mathf.RoundToInt((float)mWidth * (mDrawRegion.z - mDrawRegion.x)); + NGUIText.regionHeight = Mathf.RoundToInt((float)mHeight * (mDrawRegion.w - mDrawRegion.y)); + } + if (alignment == NGUIText.Alignment.Automatic) + { + switch (base.pivot) + { + case Pivot.TopLeft: + case Pivot.Left: + case Pivot.BottomLeft: + NGUIText.alignment = NGUIText.Alignment.Left; + break; + case Pivot.TopRight: + case Pivot.Right: + case Pivot.BottomRight: + NGUIText.alignment = NGUIText.Alignment.Right; + break; + default: + NGUIText.alignment = NGUIText.Alignment.Center; + break; + } + } + else + { + NGUIText.alignment = alignment; + } + NGUIText.Update(); + } +} diff --git a/UILocalize.cs b/UILocalize.cs new file mode 100644 index 00000000..399e2932 --- /dev/null +++ b/UILocalize.cs @@ -0,0 +1,76 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Localize")] +[ExecuteInEditMode] +[RequireComponent(typeof(UIWidget))] +public class UILocalize : MonoBehaviour +{ + public string key; + + private bool mStarted; + + public string value + { + set + { + if (!string.IsNullOrEmpty(value)) + { + UIWidget component = GetComponent(); + UILabel uILabel = component as UILabel; + UISprite uISprite = component as UISprite; + if (uILabel != null) + { + UIInput uIInput = NGUITools.FindInParents(uILabel.gameObject); + if (uIInput != null && uIInput.label == uILabel) + { + uIInput.defaultText = value; + } + else + { + uILabel.text = value; + } + } + else if (uISprite != null) + { + UIButton uIButton = NGUITools.FindInParents(uISprite.gameObject); + if (uIButton != null && uIButton.tweenTarget == uISprite.gameObject) + { + uIButton.normalSprite = value; + } + uISprite.spriteName = value; + uISprite.MakePixelPerfect(); + } + } + } + } + + private void OnEnable() + { + if (mStarted) + { + OnLocalize(); + } + } + + private void Start() + { + mStarted = true; + OnLocalize(); + } + + private void OnLocalize() + { + if (string.IsNullOrEmpty(key)) + { + UILabel component = GetComponent(); + if (component != null) + { + key = component.text; + } + } + if (!string.IsNullOrEmpty(key)) + { + value = Localization.Get(key); + } + } +} diff --git a/UIOrthoCamera.cs b/UIOrthoCamera.cs new file mode 100644 index 00000000..0217e126 --- /dev/null +++ b/UIOrthoCamera.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Orthographic Camera")] +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +public class UIOrthoCamera : MonoBehaviour +{ + private Camera mCam; + + private Transform mTrans; + + private void Start() + { + mCam = GetComponent(); + mTrans = base.transform; + mCam.orthographic = true; + } + + private void Update() + { + float num = mCam.rect.yMin * (float)Screen.height; + float num2 = mCam.rect.yMax * (float)Screen.height; + float num3 = (num2 - num) * 0.5f; + Vector3 lossyScale = mTrans.lossyScale; + float num4 = num3 * lossyScale.y; + if (!Mathf.Approximately(mCam.orthographicSize, num4)) + { + mCam.orthographicSize = num4; + } + } +} diff --git a/UIPanel.cs b/UIPanel.cs new file mode 100644 index 00000000..98c31553 --- /dev/null +++ b/UIPanel.cs @@ -0,0 +1,1502 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Panel")] +[ExecuteInEditMode] +public class UIPanel : UIRect +{ + public enum RenderQueue + { + Automatic, + StartAt, + Explicit + } + + public delegate void OnGeometryUpdated(); + + public delegate void OnClippingMoved(UIPanel panel); + + public static List list = new List(); + + public OnGeometryUpdated onGeometryUpdated; + + public bool showInPanelTool = true; + + public bool generateNormals; + + public bool widgetsAreStatic; + + public bool cullWhileDragging = true; + + public bool alwaysOnScreen; + + public bool anchorOffset; + + public bool softBorderPadding = true; + + public RenderQueue renderQueue; + + public int startingRenderQueue = 3000; + + [NonSerialized] + public List widgets = new List(); + + [NonSerialized] + public List drawCalls = new List(); + + [NonSerialized] + public Matrix4x4 worldToLocal = Matrix4x4.identity; + + [NonSerialized] + public Vector4 drawCallClipRange = new Vector4(0f, 0f, 1f, 1f); + + public OnClippingMoved onClipMove; + + [HideInInspector] + [SerializeField] + private Texture2D mClipTexture; + + [HideInInspector] + [SerializeField] + private float mAlpha = 1f; + + [HideInInspector] + [SerializeField] + private UIDrawCall.Clipping mClipping; + + [HideInInspector] + [SerializeField] + private Vector4 mClipRange = new Vector4(0f, 0f, 300f, 200f); + + [HideInInspector] + [SerializeField] + private Vector2 mClipSoftness = new Vector2(4f, 4f); + + [HideInInspector] + [SerializeField] + private int mDepth; + + [HideInInspector] + [SerializeField] + private int mSortingOrder; + + private bool mRebuild; + + private bool mResized; + + [SerializeField] + private Vector2 mClipOffset = Vector2.zero; + + private float mCullTime; + + private float mUpdateTime; + + private int mMatrixFrame = -1; + + private int mAlphaFrameID; + + private int mLayer = -1; + + private static float[] mTemp = new float[4]; + + private Vector2 mMin = Vector2.zero; + + private Vector2 mMax = Vector2.zero; + + private bool mHalfPixelOffset; + + private bool mSortWidgets; + + private bool mUpdateScroll; + + private UIPanel mParentPanel; + + private static Vector3[] mCorners = new Vector3[4]; + + private static int mUpdateFrame = -1; + + private UIDrawCall.OnRenderCallback mOnRender; + + private bool mForced; + + public static int nextUnusedDepth + { + get + { + int num = -2147483648; + int i = 0; + for (int count = list.Count; i < count; i++) + { + num = Mathf.Max(num, list[i].depth); + } + return (num != -2147483648) ? (num + 1) : 0; + } + } + + public override bool canBeAnchored => mClipping != UIDrawCall.Clipping.None; + + public override float alpha + { + get + { + return mAlpha; + } + set + { + float num = Mathf.Clamp01(value); + if (mAlpha != num) + { + mAlphaFrameID = -1; + mResized = true; + mAlpha = num; + SetDirty(); + } + } + } + + public int depth + { + get + { + return mDepth; + } + set + { + if (mDepth != value) + { + mDepth = value; + list.Sort(CompareFunc); + } + } + } + + public int sortingOrder + { + get + { + return mSortingOrder; + } + set + { + if (mSortingOrder != value) + { + mSortingOrder = value; + UpdateDrawCalls(); + } + } + } + + public float width + { + get + { + Vector2 viewSize = GetViewSize(); + return viewSize.x; + } + } + + public float height + { + get + { + Vector2 viewSize = GetViewSize(); + return viewSize.y; + } + } + + public bool halfPixelOffset => mHalfPixelOffset; + + public bool usedForUI => base.anchorCamera != null && mCam.orthographic; + + public Vector3 drawCallOffset + { + get + { + if (mHalfPixelOffset && base.anchorCamera != null && mCam.orthographic) + { + Vector2 windowSize = GetWindowSize(); + float num = 1f / windowSize.y / mCam.orthographicSize; + return new Vector3(0f - num, num); + } + return Vector3.zero; + } + } + + public UIDrawCall.Clipping clipping + { + get + { + return mClipping; + } + set + { + if (mClipping != value) + { + mResized = true; + mClipping = value; + mMatrixFrame = -1; + } + } + } + + public UIPanel parentPanel => mParentPanel; + + public int clipCount + { + get + { + int num = 0; + UIPanel uIPanel = this; + while (uIPanel != null) + { + if (uIPanel.mClipping == UIDrawCall.Clipping.SoftClip || uIPanel.mClipping == UIDrawCall.Clipping.TextureMask) + { + num++; + } + uIPanel = uIPanel.mParentPanel; + } + return num; + } + } + + public bool hasClipping => mClipping == UIDrawCall.Clipping.SoftClip || mClipping == UIDrawCall.Clipping.TextureMask; + + public bool hasCumulativeClipping => clipCount != 0; + + [Obsolete("Use 'hasClipping' or 'hasCumulativeClipping' instead")] + public bool clipsChildren + { + get + { + return hasCumulativeClipping; + } + } + + public Vector2 clipOffset + { + get + { + return mClipOffset; + } + set + { + if (Mathf.Abs(mClipOffset.x - value.x) > 0.001f || Mathf.Abs(mClipOffset.y - value.y) > 0.001f) + { + mClipOffset = value; + InvalidateClipping(); + if (onClipMove != null) + { + onClipMove(this); + } + } + } + } + + public Texture2D clipTexture + { + get + { + return mClipTexture; + } + set + { + if (mClipTexture != value) + { + mClipTexture = value; + } + } + } + + [Obsolete("Use 'finalClipRegion' or 'baseClipRegion' instead")] + public Vector4 clipRange + { + get + { + return baseClipRegion; + } + set + { + baseClipRegion = value; + } + } + + public Vector4 baseClipRegion + { + get + { + return mClipRange; + } + set + { + if (Mathf.Abs(mClipRange.x - value.x) > 0.001f || Mathf.Abs(mClipRange.y - value.y) > 0.001f || Mathf.Abs(mClipRange.z - value.z) > 0.001f || Mathf.Abs(mClipRange.w - value.w) > 0.001f) + { + mResized = true; + mCullTime = ((mCullTime != 0f) ? (RealTime.time + 0.15f) : 0.001f); + mClipRange = value; + mMatrixFrame = -1; + UIScrollView component = GetComponent(); + if (component != null) + { + component.UpdatePosition(); + } + if (onClipMove != null) + { + onClipMove(this); + } + } + } + } + + public Vector4 finalClipRegion + { + get + { + Vector2 viewSize = GetViewSize(); + if (mClipping != 0) + { + return new Vector4(mClipRange.x + mClipOffset.x, mClipRange.y + mClipOffset.y, viewSize.x, viewSize.y); + } + return new Vector4(0f, 0f, viewSize.x, viewSize.y); + } + } + + public Vector2 clipSoftness + { + get + { + return mClipSoftness; + } + set + { + if (mClipSoftness != value) + { + mClipSoftness = value; + } + } + } + + public override Vector3[] localCorners + { + get + { + if (mClipping == UIDrawCall.Clipping.None) + { + Vector3[] worldCorners = this.worldCorners; + Transform cachedTransform = base.cachedTransform; + for (int i = 0; i < 4; i++) + { + worldCorners[i] = cachedTransform.InverseTransformPoint(worldCorners[i]); + } + return worldCorners; + } + float num = mClipOffset.x + mClipRange.x - 0.5f * mClipRange.z; + float num2 = mClipOffset.y + mClipRange.y - 0.5f * mClipRange.w; + float x = num + mClipRange.z; + float y = num2 + mClipRange.w; + mCorners[0] = new Vector3(num, num2); + mCorners[1] = new Vector3(num, y); + mCorners[2] = new Vector3(x, y); + mCorners[3] = new Vector3(x, num2); + return mCorners; + } + } + + public override Vector3[] worldCorners + { + get + { + if (mClipping != 0) + { + float num = mClipOffset.x + mClipRange.x - 0.5f * mClipRange.z; + float num2 = mClipOffset.y + mClipRange.y - 0.5f * mClipRange.w; + float x = num + mClipRange.z; + float y = num2 + mClipRange.w; + Transform cachedTransform = base.cachedTransform; + mCorners[0] = cachedTransform.TransformPoint(num, num2, 0f); + mCorners[1] = cachedTransform.TransformPoint(num, y, 0f); + mCorners[2] = cachedTransform.TransformPoint(x, y, 0f); + mCorners[3] = cachedTransform.TransformPoint(x, num2, 0f); + } + else + { + if (base.anchorCamera != null) + { + return mCam.GetWorldCorners(base.cameraRayDistance); + } + Vector2 viewSize = GetViewSize(); + float num3 = -0.5f * viewSize.x; + float num4 = -0.5f * viewSize.y; + float x2 = num3 + viewSize.x; + float y2 = num4 + viewSize.y; + mCorners[0] = new Vector3(num3, num4); + mCorners[1] = new Vector3(num3, y2); + mCorners[2] = new Vector3(x2, y2); + mCorners[3] = new Vector3(x2, num4); + if ((anchorOffset && mCam == null) || mCam.transform.parent != base.cachedTransform) + { + Vector3 position = base.cachedTransform.position; + for (int i = 0; i < 4; i++) + { + mCorners[i] += position; + } + } + } + return mCorners; + } + } + + public static int CompareFunc(UIPanel a, UIPanel b) + { + if (a != b && a != null && b != null) + { + if (a.mDepth < b.mDepth) + { + return -1; + } + if (a.mDepth > b.mDepth) + { + return 1; + } + return (a.GetInstanceID() >= b.GetInstanceID()) ? 1 : (-1); + } + return 0; + } + + private void InvalidateClipping() + { + mResized = true; + mMatrixFrame = -1; + mCullTime = ((mCullTime != 0f) ? (RealTime.time + 0.15f) : 0.001f); + int i = 0; + for (int count = list.Count; i < count; i++) + { + UIPanel uIPanel = list[i]; + if (uIPanel != this && uIPanel.parentPanel == this) + { + uIPanel.InvalidateClipping(); + } + } + } + + public override Vector3[] GetSides(Transform relativeTo) + { + if (mClipping != 0) + { + float num = mClipOffset.x + mClipRange.x - 0.5f * mClipRange.z; + float num2 = mClipOffset.y + mClipRange.y - 0.5f * mClipRange.w; + float num3 = num + mClipRange.z; + float num4 = num2 + mClipRange.w; + float x = (num + num3) * 0.5f; + float y = (num2 + num4) * 0.5f; + Transform cachedTransform = base.cachedTransform; + UIRect.mSides[0] = cachedTransform.TransformPoint(num, y, 0f); + UIRect.mSides[1] = cachedTransform.TransformPoint(x, num4, 0f); + UIRect.mSides[2] = cachedTransform.TransformPoint(num3, y, 0f); + UIRect.mSides[3] = cachedTransform.TransformPoint(x, num2, 0f); + if (relativeTo != null) + { + for (int i = 0; i < 4; i++) + { + UIRect.mSides[i] = relativeTo.InverseTransformPoint(UIRect.mSides[i]); + } + } + return UIRect.mSides; + } + if (base.anchorCamera != null && anchorOffset) + { + Vector3[] sides = mCam.GetSides(base.cameraRayDistance); + Vector3 position = base.cachedTransform.position; + for (int j = 0; j < 4; j++) + { + sides[j] += position; + } + if (relativeTo != null) + { + for (int k = 0; k < 4; k++) + { + sides[k] = relativeTo.InverseTransformPoint(sides[k]); + } + } + return sides; + } + return base.GetSides(relativeTo); + } + + public override void Invalidate(bool includeChildren) + { + mAlphaFrameID = -1; + base.Invalidate(includeChildren); + } + + public override float CalculateFinalAlpha(int frameID) + { + if (mAlphaFrameID != frameID) + { + mAlphaFrameID = frameID; + UIRect parent = base.parent; + finalAlpha = ((!(base.parent != null)) ? mAlpha : (parent.CalculateFinalAlpha(frameID) * mAlpha)); + } + return finalAlpha; + } + + public override void SetRect(float x, float y, float width, float height) + { + int num = Mathf.FloorToInt(width + 0.5f); + int num2 = Mathf.FloorToInt(height + 0.5f); + num = num >> 1 << 1; + num2 = num2 >> 1 << 1; + Transform cachedTransform = base.cachedTransform; + Vector3 localPosition = cachedTransform.localPosition; + localPosition.x = Mathf.Floor(x + 0.5f); + localPosition.y = Mathf.Floor(y + 0.5f); + if (num < 2) + { + num = 2; + } + if (num2 < 2) + { + num2 = 2; + } + baseClipRegion = new Vector4(localPosition.x, localPosition.y, (float)num, (float)num2); + if (base.isAnchored) + { + cachedTransform = cachedTransform.parent; + if ((bool)leftAnchor.target) + { + leftAnchor.SetHorizontal(cachedTransform, x); + } + if ((bool)rightAnchor.target) + { + rightAnchor.SetHorizontal(cachedTransform, x + width); + } + if ((bool)bottomAnchor.target) + { + bottomAnchor.SetVertical(cachedTransform, y); + } + if ((bool)topAnchor.target) + { + topAnchor.SetVertical(cachedTransform, y + height); + } + } + } + + public bool IsVisible(Vector3 a, Vector3 b, Vector3 c, Vector3 d) + { + UpdateTransformMatrix(); + a = worldToLocal.MultiplyPoint3x4(a); + b = worldToLocal.MultiplyPoint3x4(b); + c = worldToLocal.MultiplyPoint3x4(c); + d = worldToLocal.MultiplyPoint3x4(d); + mTemp[0] = a.x; + mTemp[1] = b.x; + mTemp[2] = c.x; + mTemp[3] = d.x; + float num = Mathf.Min(mTemp); + float num2 = Mathf.Max(mTemp); + mTemp[0] = a.y; + mTemp[1] = b.y; + mTemp[2] = c.y; + mTemp[3] = d.y; + float num3 = Mathf.Min(mTemp); + float num4 = Mathf.Max(mTemp); + if (num2 < mMin.x) + { + return false; + } + if (num4 < mMin.y) + { + return false; + } + if (num > mMax.x) + { + return false; + } + if (num3 > mMax.y) + { + return false; + } + return true; + } + + public bool IsVisible(Vector3 worldPos) + { + if (mAlpha < 0.001f) + { + return false; + } + if (mClipping == UIDrawCall.Clipping.None || mClipping == UIDrawCall.Clipping.ConstrainButDontClip) + { + return true; + } + UpdateTransformMatrix(); + Vector3 vector = worldToLocal.MultiplyPoint3x4(worldPos); + if (vector.x < mMin.x) + { + return false; + } + if (vector.y < mMin.y) + { + return false; + } + if (vector.x > mMax.x) + { + return false; + } + if (vector.y > mMax.y) + { + return false; + } + return true; + } + + public bool IsVisible(UIWidget w) + { + UIPanel uIPanel = this; + Vector3[] array = null; + while (uIPanel != null) + { + if ((uIPanel.mClipping == UIDrawCall.Clipping.None || uIPanel.mClipping == UIDrawCall.Clipping.ConstrainButDontClip) && !w.hideIfOffScreen) + { + uIPanel = uIPanel.mParentPanel; + } + else + { + if (array == null) + { + array = w.worldCorners; + } + if (!uIPanel.IsVisible(array[0], array[1], array[2], array[3])) + { + return false; + } + uIPanel = uIPanel.mParentPanel; + } + } + return true; + } + + public bool Affects(UIWidget w) + { + if (w == null) + { + return false; + } + UIPanel panel = w.panel; + if (panel == null) + { + return false; + } + UIPanel uIPanel = this; + while (uIPanel != null) + { + if (uIPanel == panel) + { + return true; + } + if (!uIPanel.hasCumulativeClipping) + { + return false; + } + uIPanel = uIPanel.mParentPanel; + } + return false; + } + + [ContextMenu("Force Refresh")] + public void RebuildAllDrawCalls() + { + mRebuild = true; + } + + public void SetDirty() + { + int i = 0; + for (int count = drawCalls.Count; i < count; i++) + { + drawCalls[i].isDirty = true; + } + Invalidate(includeChildren: true); + } + + private void Awake() + { + mGo = base.gameObject; + mTrans = base.transform; + mHalfPixelOffset = (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.XBOX360 || Application.platform == RuntimePlatform.WindowsWebPlayer || Application.platform == RuntimePlatform.WindowsEditor); + if (mHalfPixelOffset) + { + mHalfPixelOffset = (SystemInfo.graphicsShaderLevel < 40 && SystemInfo.graphicsDeviceVersion.Contains("Direct3D")); + } + } + + private void FindParent() + { + Transform parent = base.cachedTransform.parent; + mParentPanel = ((!(parent != null)) ? null : NGUITools.FindInParents(parent.gameObject)); + } + + public override void ParentHasChanged() + { + base.ParentHasChanged(); + FindParent(); + } + + protected override void OnStart() + { + mLayer = mGo.layer; + } + + protected override void OnEnable() + { + mRebuild = true; + mAlphaFrameID = -1; + mMatrixFrame = -1; + OnStart(); + base.OnEnable(); + mMatrixFrame = -1; + } + + protected override void OnInit() + { + base.OnInit(); + FindParent(); + if (GetComponent() == null && mParentPanel == null) + { + UICamera uICamera = (!(base.anchorCamera != null)) ? null : mCam.GetComponent(); + if (uICamera != null && (uICamera.eventType == UICamera.EventType.UI_3D || uICamera.eventType == UICamera.EventType.World_3D)) + { + Rigidbody rigidbody = base.gameObject.AddComponent(); + rigidbody.isKinematic = true; + rigidbody.useGravity = false; + } + } + mRebuild = true; + mAlphaFrameID = -1; + mMatrixFrame = -1; + list.Add(this); + list.Sort(CompareFunc); + } + + protected override void OnDisable() + { + int i = 0; + for (int count = drawCalls.Count; i < count; i++) + { + UIDrawCall uIDrawCall = drawCalls[i]; + if (uIDrawCall != null) + { + UIDrawCall.Destroy(uIDrawCall); + } + } + drawCalls.Clear(); + list.Remove(this); + mAlphaFrameID = -1; + mMatrixFrame = -1; + if (list.Count == 0) + { + UIDrawCall.ReleaseAll(); + mUpdateFrame = -1; + } + base.OnDisable(); + } + + private void UpdateTransformMatrix() + { + int frameCount = Time.frameCount; + if (mMatrixFrame != frameCount) + { + mMatrixFrame = frameCount; + worldToLocal = base.cachedTransform.worldToLocalMatrix; + Vector2 vector = GetViewSize() * 0.5f; + float num = mClipOffset.x + mClipRange.x; + float num2 = mClipOffset.y + mClipRange.y; + mMin.x = num - vector.x; + mMin.y = num2 - vector.y; + mMax.x = num + vector.x; + mMax.y = num2 + vector.y; + } + } + + protected override void OnAnchor() + { + if (mClipping != 0) + { + Transform cachedTransform = base.cachedTransform; + Transform parent = cachedTransform.parent; + Vector2 viewSize = GetViewSize(); + Vector2 vector = cachedTransform.localPosition; + float num; + float num2; + float num3; + float num4; + if (leftAnchor.target == bottomAnchor.target && leftAnchor.target == rightAnchor.target && leftAnchor.target == topAnchor.target) + { + Vector3[] sides = leftAnchor.GetSides(parent); + if (sides != null) + { + num = NGUIMath.Lerp(sides[0].x, sides[2].x, leftAnchor.relative) + (float)leftAnchor.absolute; + num2 = NGUIMath.Lerp(sides[0].x, sides[2].x, rightAnchor.relative) + (float)rightAnchor.absolute; + num3 = NGUIMath.Lerp(sides[3].y, sides[1].y, bottomAnchor.relative) + (float)bottomAnchor.absolute; + num4 = NGUIMath.Lerp(sides[3].y, sides[1].y, topAnchor.relative) + (float)topAnchor.absolute; + } + else + { + Vector2 vector2 = GetLocalPos(leftAnchor, parent); + num = vector2.x + (float)leftAnchor.absolute; + num3 = vector2.y + (float)bottomAnchor.absolute; + num2 = vector2.x + (float)rightAnchor.absolute; + num4 = vector2.y + (float)topAnchor.absolute; + } + } + else + { + if ((bool)leftAnchor.target) + { + Vector3[] sides2 = leftAnchor.GetSides(parent); + if (sides2 != null) + { + num = NGUIMath.Lerp(sides2[0].x, sides2[2].x, leftAnchor.relative) + (float)leftAnchor.absolute; + } + else + { + Vector3 localPos = GetLocalPos(leftAnchor, parent); + num = localPos.x + (float)leftAnchor.absolute; + } + } + else + { + num = mClipRange.x - 0.5f * viewSize.x; + } + if ((bool)rightAnchor.target) + { + Vector3[] sides3 = rightAnchor.GetSides(parent); + if (sides3 != null) + { + num2 = NGUIMath.Lerp(sides3[0].x, sides3[2].x, rightAnchor.relative) + (float)rightAnchor.absolute; + } + else + { + Vector3 localPos2 = GetLocalPos(rightAnchor, parent); + num2 = localPos2.x + (float)rightAnchor.absolute; + } + } + else + { + num2 = mClipRange.x + 0.5f * viewSize.x; + } + if ((bool)bottomAnchor.target) + { + Vector3[] sides4 = bottomAnchor.GetSides(parent); + if (sides4 != null) + { + num3 = NGUIMath.Lerp(sides4[3].y, sides4[1].y, bottomAnchor.relative) + (float)bottomAnchor.absolute; + } + else + { + Vector3 localPos3 = GetLocalPos(bottomAnchor, parent); + num3 = localPos3.y + (float)bottomAnchor.absolute; + } + } + else + { + num3 = mClipRange.y - 0.5f * viewSize.y; + } + if ((bool)topAnchor.target) + { + Vector3[] sides5 = topAnchor.GetSides(parent); + if (sides5 != null) + { + num4 = NGUIMath.Lerp(sides5[3].y, sides5[1].y, topAnchor.relative) + (float)topAnchor.absolute; + } + else + { + Vector3 localPos4 = GetLocalPos(topAnchor, parent); + num4 = localPos4.y + (float)topAnchor.absolute; + } + } + else + { + num4 = mClipRange.y + 0.5f * viewSize.y; + } + } + num -= vector.x + mClipOffset.x; + num2 -= vector.x + mClipOffset.x; + num3 -= vector.y + mClipOffset.y; + num4 -= vector.y + mClipOffset.y; + float x = Mathf.Lerp(num, num2, 0.5f); + float y = Mathf.Lerp(num3, num4, 0.5f); + float num5 = num2 - num; + float num6 = num4 - num3; + float num7 = Mathf.Max(2f, mClipSoftness.x); + float num8 = Mathf.Max(2f, mClipSoftness.y); + if (num5 < num7) + { + num5 = num7; + } + if (num6 < num8) + { + num6 = num8; + } + baseClipRegion = new Vector4(x, y, num5, num6); + } + } + + private void LateUpdate() + { + if (mUpdateFrame != Time.frameCount) + { + mUpdateFrame = Time.frameCount; + int i = 0; + for (int count = list.Count; i < count; i++) + { + list[i].UpdateSelf(); + } + int num = 3000; + int j = 0; + for (int count2 = list.Count; j < count2; j++) + { + UIPanel uIPanel = list[j]; + if (uIPanel.renderQueue == RenderQueue.Automatic) + { + uIPanel.startingRenderQueue = num; + uIPanel.UpdateDrawCalls(); + num += uIPanel.drawCalls.Count; + } + else if (uIPanel.renderQueue == RenderQueue.StartAt) + { + uIPanel.UpdateDrawCalls(); + if (uIPanel.drawCalls.Count != 0) + { + num = Mathf.Max(num, uIPanel.startingRenderQueue + uIPanel.drawCalls.Count); + } + } + else + { + uIPanel.UpdateDrawCalls(); + if (uIPanel.drawCalls.Count != 0) + { + num = Mathf.Max(num, uIPanel.startingRenderQueue + 1); + } + } + } + } + } + + private void UpdateSelf() + { + mUpdateTime = RealTime.time; + UpdateTransformMatrix(); + UpdateLayers(); + UpdateWidgets(); + if (mRebuild) + { + mRebuild = false; + FillAllDrawCalls(); + } + else + { + int num = 0; + while (num < drawCalls.Count) + { + UIDrawCall uIDrawCall = drawCalls[num]; + if (uIDrawCall.isDirty && !FillDrawCall(uIDrawCall)) + { + UIDrawCall.Destroy(uIDrawCall); + drawCalls.RemoveAt(num); + } + else + { + num++; + } + } + } + if (mUpdateScroll) + { + mUpdateScroll = false; + UIScrollView component = GetComponent(); + if (component != null) + { + component.UpdateScrollbars(); + } + } + } + + public void SortWidgets() + { + mSortWidgets = false; + widgets.Sort(UIWidget.PanelCompareFunc); + } + + private void FillAllDrawCalls() + { + for (int i = 0; i < drawCalls.Count; i++) + { + UIDrawCall.Destroy(drawCalls[i]); + } + drawCalls.Clear(); + Material material = null; + Texture texture = null; + Shader shader = null; + UIDrawCall uIDrawCall = null; + int num = 0; + if (mSortWidgets) + { + SortWidgets(); + } + for (int j = 0; j < widgets.Count; j++) + { + UIWidget uIWidget = widgets[j]; + if (uIWidget.isVisible && uIWidget.hasVertices) + { + Material material2 = uIWidget.material; + Texture mainTexture = uIWidget.mainTexture; + Shader shader2 = uIWidget.shader; + if (material != material2 || texture != mainTexture || shader != shader2) + { + if (uIDrawCall != null && uIDrawCall.verts.size != 0) + { + drawCalls.Add(uIDrawCall); + uIDrawCall.UpdateGeometry(num); + uIDrawCall.onRender = mOnRender; + mOnRender = null; + num = 0; + uIDrawCall = null; + } + material = material2; + texture = mainTexture; + shader = shader2; + } + if (material != null || shader != null || texture != null) + { + if (uIDrawCall == null) + { + uIDrawCall = UIDrawCall.Create(this, material, texture, shader); + uIDrawCall.depthStart = uIWidget.depth; + uIDrawCall.depthEnd = uIDrawCall.depthStart; + uIDrawCall.panel = this; + } + else + { + int depth = uIWidget.depth; + if (depth < uIDrawCall.depthStart) + { + uIDrawCall.depthStart = depth; + } + if (depth > uIDrawCall.depthEnd) + { + uIDrawCall.depthEnd = depth; + } + } + uIWidget.drawCall = uIDrawCall; + num++; + if (generateNormals) + { + uIWidget.WriteToBuffers(uIDrawCall.verts, uIDrawCall.uvs, uIDrawCall.cols, uIDrawCall.norms, uIDrawCall.tans); + } + else + { + uIWidget.WriteToBuffers(uIDrawCall.verts, uIDrawCall.uvs, uIDrawCall.cols, null, null); + } + if (uIWidget.mOnRender != null) + { + if (mOnRender == null) + { + mOnRender = uIWidget.mOnRender; + } + else + { + mOnRender = (UIDrawCall.OnRenderCallback)Delegate.Combine(mOnRender, uIWidget.mOnRender); + } + } + } + } + else + { + uIWidget.drawCall = null; + } + } + if (uIDrawCall != null && uIDrawCall.verts.size != 0) + { + drawCalls.Add(uIDrawCall); + uIDrawCall.UpdateGeometry(num); + uIDrawCall.onRender = mOnRender; + mOnRender = null; + } + } + + private bool FillDrawCall(UIDrawCall dc) + { + if (dc != null) + { + dc.isDirty = false; + int num = 0; + int num2 = 0; + while (num2 < widgets.Count) + { + UIWidget uIWidget = widgets[num2]; + if (uIWidget == null) + { + widgets.RemoveAt(num2); + } + else + { + if (uIWidget.drawCall == dc) + { + if (uIWidget.isVisible && uIWidget.hasVertices) + { + num++; + if (generateNormals) + { + uIWidget.WriteToBuffers(dc.verts, dc.uvs, dc.cols, dc.norms, dc.tans); + } + else + { + uIWidget.WriteToBuffers(dc.verts, dc.uvs, dc.cols, null, null); + } + if (uIWidget.mOnRender != null) + { + if (mOnRender == null) + { + mOnRender = uIWidget.mOnRender; + } + else + { + mOnRender = (UIDrawCall.OnRenderCallback)Delegate.Combine(mOnRender, uIWidget.mOnRender); + } + } + } + else + { + uIWidget.drawCall = null; + } + } + num2++; + } + } + if (dc.verts.size != 0) + { + dc.UpdateGeometry(num); + dc.onRender = mOnRender; + mOnRender = null; + return true; + } + } + return false; + } + + private void UpdateDrawCalls() + { + Transform cachedTransform = base.cachedTransform; + bool usedForUI = this.usedForUI; + if (clipping != 0) + { + drawCallClipRange = finalClipRegion; + drawCallClipRange.z *= 0.5f; + drawCallClipRange.w *= 0.5f; + } + else + { + drawCallClipRange = Vector4.zero; + } + if (drawCallClipRange.z == 0f) + { + drawCallClipRange.z = (float)Screen.width * 0.5f; + } + if (drawCallClipRange.w == 0f) + { + drawCallClipRange.w = (float)Screen.height * 0.5f; + } + if (halfPixelOffset) + { + drawCallClipRange.x -= 0.5f; + drawCallClipRange.y += 0.5f; + } + Vector3 vector; + if (usedForUI) + { + Transform parent = base.cachedTransform.parent; + vector = base.cachedTransform.localPosition; + if (parent != null) + { + vector = parent.TransformPoint(vector); + } + vector += drawCallOffset; + } + else + { + vector = cachedTransform.position; + } + Quaternion rotation = cachedTransform.rotation; + Vector3 lossyScale = cachedTransform.lossyScale; + for (int i = 0; i < drawCalls.Count; i++) + { + UIDrawCall uIDrawCall = drawCalls[i]; + Transform cachedTransform2 = uIDrawCall.cachedTransform; + cachedTransform2.position = vector; + cachedTransform2.rotation = rotation; + cachedTransform2.localScale = lossyScale; + uIDrawCall.renderQueue = ((renderQueue != RenderQueue.Explicit) ? (startingRenderQueue + i) : startingRenderQueue); + uIDrawCall.alwaysOnScreen = (alwaysOnScreen && (mClipping == UIDrawCall.Clipping.None || mClipping == UIDrawCall.Clipping.ConstrainButDontClip)); + uIDrawCall.sortingOrder = mSortingOrder; + uIDrawCall.clipTexture = mClipTexture; + } + } + + private void UpdateLayers() + { + if (mLayer != base.cachedGameObject.layer) + { + mLayer = mGo.layer; + NGUITools.SetChildLayer(base.cachedTransform, mLayer); + ResetAnchors(); + for (int i = 0; i < drawCalls.Count; i++) + { + drawCalls[i].gameObject.layer = mLayer; + } + } + } + + private void UpdateWidgets() + { + bool flag = !cullWhileDragging && mCullTime > mUpdateTime; + bool flag2 = false; + if (mForced != flag) + { + mForced = flag; + mResized = true; + } + bool hasCumulativeClipping = this.hasCumulativeClipping; + int i = 0; + for (int count = widgets.Count; i < count; i++) + { + UIWidget uIWidget = widgets[i]; + if (uIWidget.panel == this && uIWidget.enabled) + { + int frameCount = Time.frameCount; + if (uIWidget.UpdateTransform(frameCount) || mResized) + { + bool visibleByAlpha = flag || uIWidget.CalculateCumulativeAlpha(frameCount) > 0.001f; + uIWidget.UpdateVisibility(visibleByAlpha, flag || (!hasCumulativeClipping && !uIWidget.hideIfOffScreen) || IsVisible(uIWidget)); + } + if (uIWidget.UpdateGeometry(frameCount)) + { + flag2 = true; + if (!mRebuild) + { + if (uIWidget.drawCall != null) + { + uIWidget.drawCall.isDirty = true; + } + else + { + FindDrawCall(uIWidget); + } + } + } + } + } + if (flag2 && onGeometryUpdated != null) + { + onGeometryUpdated(); + } + mResized = false; + } + + public UIDrawCall FindDrawCall(UIWidget w) + { + Material material = w.material; + Texture mainTexture = w.mainTexture; + int depth = w.depth; + for (int i = 0; i < drawCalls.Count; i++) + { + UIDrawCall uIDrawCall = drawCalls[i]; + int num = (i != 0) ? (drawCalls[i - 1].depthEnd + 1) : (-2147483648); + int num2 = (i + 1 != drawCalls.Count) ? (drawCalls[i + 1].depthStart - 1) : 2147483647; + if (num <= depth && num2 >= depth) + { + if (uIDrawCall.baseMaterial == material && uIDrawCall.mainTexture == mainTexture) + { + if (w.isVisible) + { + w.drawCall = uIDrawCall; + if (w.hasVertices) + { + uIDrawCall.isDirty = true; + } + return uIDrawCall; + } + } + else + { + mRebuild = true; + } + return null; + } + } + mRebuild = true; + return null; + } + + public void AddWidget(UIWidget w) + { + mUpdateScroll = true; + if (widgets.Count == 0) + { + widgets.Add(w); + } + else if (mSortWidgets) + { + widgets.Add(w); + SortWidgets(); + } + else if (UIWidget.PanelCompareFunc(w, widgets[0]) == -1) + { + widgets.Insert(0, w); + } + else + { + int num = widgets.Count; + while (num > 0) + { + if (UIWidget.PanelCompareFunc(w, widgets[--num]) != -1) + { + widgets.Insert(num + 1, w); + break; + } + } + } + FindDrawCall(w); + } + + public void RemoveWidget(UIWidget w) + { + if (widgets.Remove(w) && w.drawCall != null) + { + int depth = w.depth; + if (depth == w.drawCall.depthStart || depth == w.drawCall.depthEnd) + { + mRebuild = true; + } + w.drawCall.isDirty = true; + w.drawCall = null; + } + } + + public void Refresh() + { + mRebuild = true; + mUpdateFrame = -1; + if (list.Count > 0) + { + list[0].LateUpdate(); + } + } + + public virtual Vector3 CalculateConstrainOffset(Vector2 min, Vector2 max) + { + Vector4 finalClipRegion = this.finalClipRegion; + float num = finalClipRegion.z * 0.5f; + float num2 = finalClipRegion.w * 0.5f; + Vector2 minRect = new Vector2(min.x, min.y); + Vector2 maxRect = new Vector2(max.x, max.y); + Vector2 minArea = new Vector2(finalClipRegion.x - num, finalClipRegion.y - num2); + Vector2 maxArea = new Vector2(finalClipRegion.x + num, finalClipRegion.y + num2); + if (softBorderPadding && clipping == UIDrawCall.Clipping.SoftClip) + { + minArea.x += mClipSoftness.x; + minArea.y += mClipSoftness.y; + maxArea.x -= mClipSoftness.x; + maxArea.y -= mClipSoftness.y; + } + return NGUIMath.ConstrainRect(minRect, maxRect, minArea, maxArea); + } + + public bool ConstrainTargetToBounds(Transform target, ref Bounds targetBounds, bool immediate) + { + Vector3 vector = targetBounds.min; + Vector3 vector2 = targetBounds.max; + float num = 1f; + if (mClipping == UIDrawCall.Clipping.None) + { + UIRoot root = base.root; + if (root != null) + { + num = root.pixelSizeAdjustment; + } + } + if (num != 1f) + { + vector /= num; + vector2 /= num; + } + Vector3 vector3 = CalculateConstrainOffset(vector, vector2) * num; + if (vector3.sqrMagnitude > 0f) + { + if (immediate) + { + target.localPosition += vector3; + targetBounds.center += vector3; + SpringPosition component = target.GetComponent(); + if (component != null) + { + component.enabled = false; + } + } + else + { + SpringPosition springPosition = SpringPosition.Begin(target.gameObject, target.localPosition + vector3, 13f); + springPosition.ignoreTimeScale = true; + springPosition.worldSpace = false; + } + return true; + } + return false; + } + + public bool ConstrainTargetToBounds(Transform target, bool immediate) + { + Bounds targetBounds = NGUIMath.CalculateRelativeWidgetBounds(base.cachedTransform, target); + return ConstrainTargetToBounds(target, ref targetBounds, immediate); + } + + public static UIPanel Find(Transform trans) + { + return Find(trans, /*createIfMissing:*/ false, -1); + } + + public static UIPanel Find(Transform trans, bool createIfMissing) + { + return Find(trans, createIfMissing, -1); + } + + public static UIPanel Find(Transform trans, bool createIfMissing, int layer) + { + UIPanel uIPanel = NGUITools.FindInParents(trans); + if (uIPanel != null) + { + return uIPanel; + } + return (!createIfMissing) ? null : NGUITools.CreateUI(trans, /*advanced3D:*/ false, layer); + } + + private Vector2 GetWindowSize() + { + UIRoot root = base.root; + Vector2 vector = NGUITools.screenSize; + if (root != null) + { + vector *= root.GetPixelSizeAdjustment(Mathf.RoundToInt(vector.y)); + } + return vector; + } + + public Vector2 GetViewSize() + { + if (mClipping != 0) + { + return new Vector2(mClipRange.z, mClipRange.w); + } + return NGUITools.screenSize; + } +} diff --git a/UIPlayAnimation.cs b/UIPlayAnimation.cs new file mode 100644 index 00000000..1088b45c --- /dev/null +++ b/UIPlayAnimation.cs @@ -0,0 +1,252 @@ +using AnimationOrTween; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Play Animation")] +[ExecuteInEditMode] +public class UIPlayAnimation : MonoBehaviour +{ + public static UIPlayAnimation current; + + public Animation target; + + public Animator animator; + + public string clipName; + + public Trigger trigger; + + public Direction playDirection = Direction.Forward; + + public bool resetOnPlay; + + public bool clearSelection; + + public EnableCondition ifDisabledOnPlay; + + public DisableCondition disableWhenFinished; + + public List onFinished = new List(); + + [HideInInspector] + [SerializeField] + private GameObject eventReceiver; + + [HideInInspector] + [SerializeField] + private string callWhenFinished; + + private bool mStarted; + + private bool mActivated; + + private bool dragHighlight; + + private bool dualState => trigger == Trigger.OnPress || trigger == Trigger.OnHover; + + private void Awake() + { + UIButton component = GetComponent(); + if (component != null) + { + dragHighlight = component.dragHighlight; + } + if (eventReceiver != null && EventDelegate.IsValid(onFinished)) + { + eventReceiver = null; + callWhenFinished = null; + } + } + + private void Start() + { + mStarted = true; + if (target == null && animator == null) + { + animator = GetComponentInChildren(); + } + if (animator != null) + { + if (animator.enabled) + { + animator.enabled = false; + } + } + else + { + if (target == null) + { + target = GetComponentInChildren(); + } + if (target != null && target.enabled) + { + target.enabled = false; + } + } + } + + private void OnEnable() + { + if (mStarted) + { + OnHover(UICamera.IsHighlighted(base.gameObject)); + } + if (UICamera.currentTouch != null) + { + if (trigger == Trigger.OnPress || trigger == Trigger.OnPressTrue) + { + mActivated = (UICamera.currentTouch.pressed == base.gameObject); + } + if (trigger == Trigger.OnHover || trigger == Trigger.OnHoverTrue) + { + mActivated = (UICamera.currentTouch.current == base.gameObject); + } + } + UIToggle component = GetComponent(); + if (component != null) + { + EventDelegate.Add(component.onChange, OnToggle); + } + } + + private void OnDisable() + { + UIToggle component = GetComponent(); + if (component != null) + { + EventDelegate.Remove(component.onChange, OnToggle); + } + } + + private void OnHover(bool isOver) + { + if (base.enabled && (trigger == Trigger.OnHover || (trigger == Trigger.OnHoverTrue && isOver) || (trigger == Trigger.OnHoverFalse && !isOver))) + { + Play(isOver, dualState); + } + } + + private void OnPress(bool isPressed) + { + if (base.enabled && UICamera.currentTouchID >= -1 && (trigger == Trigger.OnPress || (trigger == Trigger.OnPressTrue && isPressed) || (trigger == Trigger.OnPressFalse && !isPressed))) + { + Play(isPressed, dualState); + } + } + + private void OnClick() + { + if (UICamera.currentTouchID >= -1 && base.enabled && trigger == Trigger.OnClick) + { + Play(forward: true, onlyIfDifferent: false); + } + } + + private void OnDoubleClick() + { + if (UICamera.currentTouchID >= -1 && base.enabled && trigger == Trigger.OnDoubleClick) + { + Play(forward: true, onlyIfDifferent: false); + } + } + + private void OnSelect(bool isSelected) + { + if (base.enabled && (trigger == Trigger.OnSelect || (trigger == Trigger.OnSelectTrue && isSelected) || (trigger == Trigger.OnSelectFalse && !isSelected))) + { + Play(isSelected, dualState); + } + } + + private void OnToggle() + { + if (base.enabled && !(UIToggle.current == null) && (trigger == Trigger.OnActivate || (trigger == Trigger.OnActivateTrue && UIToggle.current.value) || (trigger == Trigger.OnActivateFalse && !UIToggle.current.value))) + { + Play(UIToggle.current.value, dualState); + } + } + + private void OnDragOver() + { + if (base.enabled && dualState) + { + if (UICamera.currentTouch.dragged == base.gameObject) + { + Play(forward: true, onlyIfDifferent: true); + } + else if (dragHighlight && trigger == Trigger.OnPress) + { + Play(forward: true, onlyIfDifferent: true); + } + } + } + + private void OnDragOut() + { + if (base.enabled && dualState && UICamera.hoveredObject != base.gameObject) + { + Play(forward: false, onlyIfDifferent: true); + } + } + + private void OnDrop(GameObject go) + { + if (base.enabled && trigger == Trigger.OnPress && UICamera.currentTouch.dragged != base.gameObject) + { + Play(forward: false, onlyIfDifferent: true); + } + } + + public void Play(bool forward) + { + Play(forward, onlyIfDifferent: true); + } + + public void Play(bool forward, bool onlyIfDifferent) + { + if ((bool)target || (bool)animator) + { + if (onlyIfDifferent) + { + if (mActivated == forward) + { + return; + } + mActivated = forward; + } + if (clearSelection && UICamera.selectedObject == base.gameObject) + { + UICamera.selectedObject = null; + } + int num = 0 - playDirection; + Direction direction = (Direction)((!forward) ? num : ((int)playDirection)); + ActiveAnimation activeAnimation = (!(bool)target) ? ActiveAnimation.Play(animator, clipName, direction, ifDisabledOnPlay, disableWhenFinished) : ActiveAnimation.Play(target, clipName, direction, ifDisabledOnPlay, disableWhenFinished); + if (activeAnimation != null) + { + if (resetOnPlay) + { + activeAnimation.Reset(); + } + for (int i = 0; i < onFinished.Count; i++) + { + EventDelegate.Add(activeAnimation.onFinished, OnFinished, oneShot: true); + } + } + } + } + + private void OnFinished() + { + if (current == null) + { + current = this; + EventDelegate.Execute(onFinished); + if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished)) + { + eventReceiver.SendMessage(callWhenFinished, SendMessageOptions.DontRequireReceiver); + } + eventReceiver = null; + current = null; + } + } +} diff --git a/UIPlaySound.cs b/UIPlaySound.cs new file mode 100644 index 00000000..79df071f --- /dev/null +++ b/UIPlaySound.cs @@ -0,0 +1,111 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Play Sound")] +public class UIPlaySound : MonoBehaviour +{ + public enum Trigger + { + OnClick, + OnMouseOver, + OnMouseOut, + OnPress, + OnRelease, + Custom, + OnEnable, + OnDisable + } + + public AudioClip audioClip; + + public Trigger trigger; + + [Range(0f, 1f)] + public float volume = 1f; + + [Range(0f, 2f)] + public float pitch = 1f; + + private bool mIsOver; + + private bool canPlay + { + get + { + if (!base.enabled) + { + return false; + } + UIButton component = GetComponent(); + return component == null || component.isEnabled; + } + } + + private void OnEnable() + { + if (trigger == Trigger.OnEnable) + { + NGUITools.PlaySound(audioClip, volume, pitch); + } + } + + private void OnDisable() + { + if (trigger == Trigger.OnDisable) + { + NGUITools.PlaySound(audioClip, volume, pitch); + } + } + + private void OnHover(bool isOver) + { + if (trigger == Trigger.OnMouseOver) + { + if (mIsOver == isOver) + { + return; + } + mIsOver = isOver; + } + if (canPlay && ((isOver && trigger == Trigger.OnMouseOver) || (!isOver && trigger == Trigger.OnMouseOut))) + { + NGUITools.PlaySound(audioClip, volume, pitch); + } + } + + private void OnPress(bool isPressed) + { + if (trigger == Trigger.OnPress) + { + if (mIsOver == isPressed) + { + return; + } + mIsOver = isPressed; + } + if (canPlay && ((isPressed && trigger == Trigger.OnPress) || (!isPressed && trigger == Trigger.OnRelease))) + { + NGUITools.PlaySound(audioClip, volume, pitch); + } + } + + private void OnClick() + { + if (canPlay && trigger == Trigger.OnClick) + { + NGUITools.PlaySound(audioClip, volume, pitch); + } + } + + private void OnSelect(bool isSelected) + { + if (canPlay && (!isSelected || UICamera.currentScheme == UICamera.ControlScheme.Controller)) + { + OnHover(isSelected); + } + } + + public void Play() + { + NGUITools.PlaySound(audioClip, volume, pitch); + } +} diff --git a/UIPlayTween.cs b/UIPlayTween.cs new file mode 100644 index 00000000..8af9e066 --- /dev/null +++ b/UIPlayTween.cs @@ -0,0 +1,273 @@ +using AnimationOrTween; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Play Tween")] +[ExecuteInEditMode] +public class UIPlayTween : MonoBehaviour +{ + public static UIPlayTween current; + + public GameObject tweenTarget; + + public int tweenGroup; + + public Trigger trigger; + + public Direction playDirection = Direction.Forward; + + public bool resetOnPlay; + + public bool resetIfDisabled; + + public EnableCondition ifDisabledOnPlay; + + public DisableCondition disableWhenFinished; + + public bool includeChildren; + + public List onFinished = new List(); + + [HideInInspector] + [SerializeField] + private GameObject eventReceiver; + + [HideInInspector] + [SerializeField] + private string callWhenFinished; + + private UITweener[] mTweens; + + private bool mStarted; + + private int mActive; + + private bool mActivated; + + private void Awake() + { + if (eventReceiver != null && EventDelegate.IsValid(onFinished)) + { + eventReceiver = null; + callWhenFinished = null; + } + } + + private void Start() + { + mStarted = true; + if (tweenTarget == null) + { + tweenTarget = base.gameObject; + } + } + + private void OnEnable() + { + if (mStarted) + { + OnHover(UICamera.IsHighlighted(base.gameObject)); + } + if (UICamera.currentTouch != null) + { + if (trigger == Trigger.OnPress || trigger == Trigger.OnPressTrue) + { + mActivated = (UICamera.currentTouch.pressed == base.gameObject); + } + if (trigger == Trigger.OnHover || trigger == Trigger.OnHoverTrue) + { + mActivated = (UICamera.currentTouch.current == base.gameObject); + } + } + UIToggle component = GetComponent(); + if (component != null) + { + EventDelegate.Add(component.onChange, OnToggle); + } + } + + private void OnDisable() + { + UIToggle component = GetComponent(); + if (component != null) + { + EventDelegate.Remove(component.onChange, OnToggle); + } + } + + private void OnDragOver() + { + if (trigger == Trigger.OnHover) + { + OnHover(isOver: true); + } + } + + private void OnHover(bool isOver) + { + if (base.enabled && (trigger == Trigger.OnHover || (trigger == Trigger.OnHoverTrue && isOver) || (trigger == Trigger.OnHoverFalse && !isOver))) + { + mActivated = (isOver && trigger == Trigger.OnHover); + Play(isOver); + } + } + + private void OnDragOut() + { + if (base.enabled && mActivated) + { + mActivated = false; + Play(forward: false); + } + } + + private void OnPress(bool isPressed) + { + if (base.enabled && (trigger == Trigger.OnPress || (trigger == Trigger.OnPressTrue && isPressed) || (trigger == Trigger.OnPressFalse && !isPressed))) + { + mActivated = (isPressed && trigger == Trigger.OnPress); + Play(isPressed); + } + } + + private void OnClick() + { + if (base.enabled && trigger == Trigger.OnClick) + { + Play(forward: true); + } + } + + private void OnDoubleClick() + { + if (base.enabled && trigger == Trigger.OnDoubleClick) + { + Play(forward: true); + } + } + + private void OnSelect(bool isSelected) + { + if (base.enabled && (trigger == Trigger.OnSelect || (trigger == Trigger.OnSelectTrue && isSelected) || (trigger == Trigger.OnSelectFalse && !isSelected))) + { + mActivated = (isSelected && trigger == Trigger.OnSelect); + Play(isSelected); + } + } + + private void OnToggle() + { + if (base.enabled && !(UIToggle.current == null) && (trigger == Trigger.OnActivate || (trigger == Trigger.OnActivateTrue && UIToggle.current.value) || (trigger == Trigger.OnActivateFalse && !UIToggle.current.value))) + { + Play(UIToggle.current.value); + } + } + + private void Update() + { + if (disableWhenFinished != 0 && mTweens != null) + { + bool flag = true; + bool flag2 = true; + int i = 0; + for (int num = mTweens.Length; i < num; i++) + { + UITweener uITweener = mTweens[i]; + if (uITweener.tweenGroup == tweenGroup) + { + if (uITweener.enabled) + { + flag = false; + break; + } + if (uITweener.direction != (Direction)disableWhenFinished) + { + flag2 = false; + } + } + } + if (flag) + { + if (flag2) + { + NGUITools.SetActive(tweenTarget, state: false); + } + mTweens = null; + } + } + } + + public void Play(bool forward) + { + mActive = 0; + GameObject gameObject = (!(tweenTarget == null)) ? tweenTarget : base.gameObject; + if (!NGUITools.GetActive(gameObject)) + { + if (ifDisabledOnPlay != EnableCondition.EnableThenPlay) + { + return; + } + NGUITools.SetActive(gameObject, state: true); + } + mTweens = ((!includeChildren) ? gameObject.GetComponents() : gameObject.GetComponentsInChildren()); + if (mTweens.Length == 0) + { + if (disableWhenFinished != 0) + { + NGUITools.SetActive(tweenTarget, state: false); + } + } + else + { + bool flag = false; + if (playDirection == Direction.Reverse) + { + forward = !forward; + } + int i = 0; + for (int num = mTweens.Length; i < num; i++) + { + UITweener uITweener = mTweens[i]; + if (uITweener.tweenGroup == tweenGroup) + { + if (!flag && !NGUITools.GetActive(gameObject)) + { + flag = true; + NGUITools.SetActive(gameObject, state: true); + } + mActive++; + if (playDirection == Direction.Toggle) + { + EventDelegate.Add(uITweener.onFinished, OnFinished, oneShot: true); + uITweener.Toggle(); + } + else + { + if (resetOnPlay || (resetIfDisabled && !uITweener.enabled)) + { + uITweener.Play(forward); + uITweener.ResetToBeginning(); + } + EventDelegate.Add(uITweener.onFinished, OnFinished, oneShot: true); + uITweener.Play(forward); + } + } + } + } + } + + private void OnFinished() + { + if (--mActive == 0 && current == null) + { + current = this; + EventDelegate.Execute(onFinished); + if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished)) + { + eventReceiver.SendMessage(callWhenFinished, SendMessageOptions.DontRequireReceiver); + } + eventReceiver = null; + current = null; + } + } +} diff --git a/UIPopupList.cs b/UIPopupList.cs new file mode 100644 index 00000000..be8dd797 --- /dev/null +++ b/UIPopupList.cs @@ -0,0 +1,754 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Popup List")] +[ExecuteInEditMode] +public class UIPopupList : UIWidgetContainer +{ + public enum Position + { + Auto, + Above, + Below + } + + public enum OpenOn + { + ClickOrTap, + RightClick, + DoubleClick, + Manual + } + + public delegate void LegacyEvent(string val); + + private const float animSpeed = 0.15f; + + public static UIPopupList current; + + public UIAtlas atlas; + + public UIFont bitmapFont; + + public Font trueTypeFont; + + public int fontSize = 16; + + public FontStyle fontStyle; + + public string backgroundSprite; + + public string highlightSprite; + + public Position position; + + public NGUIText.Alignment alignment = NGUIText.Alignment.Left; + + public List items = new List(); + + public List itemData = new List(); + + public Vector2 padding = new Vector3(4f, 4f); + + public Color textColor = Color.white; + + public Color backgroundColor = Color.white; + + public Color highlightColor = new Color(0.882352948f, 0.784313738f, 0.5882353f, 1f); + + public bool isAnimated = true; + + public bool isLocalized; + + public OpenOn openOn; + + public List onChange = new List(); + + [HideInInspector] + [SerializeField] + private string mSelectedItem; + + private UIPanel mPanel; + + private GameObject mChild; + + private UISprite mBackground; + + private UISprite mHighlight; + + private UILabel mHighlightedLabel; + + private List mLabelList = new List(); + + private float mBgBorder; + + [HideInInspector] + [SerializeField] + private GameObject eventReceiver; + + [HideInInspector] + [SerializeField] + private string functionName = "OnSelectionChange"; + + [HideInInspector] + [SerializeField] + private float textScale; + + [HideInInspector] + [SerializeField] + private UIFont font; + + [HideInInspector] + [SerializeField] + private UILabel textLabel; + + private LegacyEvent mLegacyEvent; + + private bool mUseDynamicFont; + + private bool mTweening; + + public UnityEngine.Object ambigiousFont + { + get + { + if (trueTypeFont != null) + { + return trueTypeFont; + } + if (bitmapFont != null) + { + return bitmapFont; + } + return font; + } + set + { + if (value is Font) + { + trueTypeFont = (value as Font); + bitmapFont = null; + font = null; + } + else if (value is UIFont) + { + bitmapFont = (value as UIFont); + trueTypeFont = null; + font = null; + } + } + } + + [Obsolete("Use EventDelegate.Add(popup.onChange, YourCallback) instead, and UIPopupList.current.value to determine the state")] + public LegacyEvent onSelectionChange + { + get + { + return mLegacyEvent; + } + set + { + mLegacyEvent = value; + } + } + + public bool isOpen => mChild != null; + + public string value + { + get + { + return mSelectedItem; + } + set + { + mSelectedItem = value; + if (mSelectedItem != null && mSelectedItem != null) + { + TriggerCallbacks(); + } + } + } + + public object data + { + get + { + int num = items.IndexOf(mSelectedItem); + return (num >= itemData.Count) ? null : itemData[num]; + } + } + + [Obsolete("Use 'value' instead")] + public string selection + { + get + { + return value; + } + set + { + this.value = value; + } + } + + private bool handleEvents + { + get + { + UIKeyNavigation component = GetComponent(); + return component == null || !component.enabled; + } + set + { + UIKeyNavigation component = GetComponent(); + if (component != null) + { + component.enabled = !value; + } + } + } + + private bool isValid => bitmapFont != null || trueTypeFont != null; + + private int activeFontSize => (!(trueTypeFont != null) && !(bitmapFont == null)) ? bitmapFont.defaultSize : fontSize; + + private float activeFontScale => (!(trueTypeFont != null) && !(bitmapFont == null)) ? ((float)fontSize / (float)bitmapFont.defaultSize) : 1f; + + public void Clear() + { + items.Clear(); + itemData.Clear(); + } + + public void AddItem(string text) + { + items.Add(text); + itemData.Add(null); + } + + public void AddItem(string text, object data) + { + items.Add(text); + itemData.Add(data); + } + + protected void TriggerCallbacks() + { + if (current != this) + { + UIPopupList uIPopupList = current; + current = this; + if (mLegacyEvent != null) + { + mLegacyEvent(mSelectedItem); + } + if (EventDelegate.IsValid(onChange)) + { + EventDelegate.Execute(onChange); + } + else if (eventReceiver != null && !string.IsNullOrEmpty(functionName)) + { + eventReceiver.SendMessage(functionName, mSelectedItem, SendMessageOptions.DontRequireReceiver); + } + current = uIPopupList; + } + } + + private void OnEnable() + { + if (EventDelegate.IsValid(onChange)) + { + eventReceiver = null; + functionName = null; + } + if (font != null) + { + if (font.isDynamic) + { + trueTypeFont = font.dynamicFont; + fontStyle = font.dynamicFontStyle; + mUseDynamicFont = true; + } + else if (bitmapFont == null) + { + bitmapFont = font; + mUseDynamicFont = false; + } + font = null; + } + if (textScale != 0f) + { + fontSize = ((!(bitmapFont != null)) ? 16 : Mathf.RoundToInt((float)bitmapFont.defaultSize * textScale)); + textScale = 0f; + } + if (trueTypeFont == null && bitmapFont != null && bitmapFont.isDynamic) + { + trueTypeFont = bitmapFont.dynamicFont; + bitmapFont = null; + } + } + + private void OnValidate() + { + Font x = trueTypeFont; + UIFont uIFont = bitmapFont; + bitmapFont = null; + trueTypeFont = null; + if (x != null && (uIFont == null || !mUseDynamicFont)) + { + bitmapFont = null; + trueTypeFont = x; + mUseDynamicFont = true; + } + else if (uIFont != null) + { + if (uIFont.isDynamic) + { + trueTypeFont = uIFont.dynamicFont; + fontStyle = uIFont.dynamicFontStyle; + fontSize = uIFont.defaultSize; + mUseDynamicFont = true; + } + else + { + bitmapFont = uIFont; + mUseDynamicFont = false; + } + } + else + { + trueTypeFont = x; + mUseDynamicFont = true; + } + } + + private void Start() + { + if (textLabel != null) + { + EventDelegate.Add(onChange, textLabel.SetCurrentSelection); + textLabel = null; + } + if (Application.isPlaying) + { + if (string.IsNullOrEmpty(mSelectedItem)) + { + if (items.Count > 0) + { + this.value = items[0]; + } + } + else + { + string value = mSelectedItem; + mSelectedItem = null; + this.value = value; + } + } + } + + private void OnLocalize() + { + if (isLocalized) + { + TriggerCallbacks(); + } + } + + private void Highlight(UILabel lbl, bool instant) + { + if (mHighlight != null) + { + mHighlightedLabel = lbl; + UISpriteData atlasSprite = mHighlight.GetAtlasSprite(); + if (atlasSprite != null) + { + Vector3 highlightPosition = GetHighlightPosition(); + if (instant || !isAnimated) + { + mHighlight.cachedTransform.localPosition = highlightPosition; + } + else + { + TweenPosition.Begin(mHighlight.gameObject, 0.1f, highlightPosition).method = UITweener.Method.EaseOut; + if (!mTweening) + { + mTweening = true; + StartCoroutine(UpdateTweenPosition()); + } + } + } + } + } + + private Vector3 GetHighlightPosition() + { + if (mHighlightedLabel == null || mHighlight == null) + { + return Vector3.zero; + } + UISpriteData atlasSprite = mHighlight.GetAtlasSprite(); + if (atlasSprite == null) + { + return Vector3.zero; + } + float pixelSize = atlas.pixelSize; + float num = (float)atlasSprite.borderLeft * pixelSize; + float y = (float)atlasSprite.borderTop * pixelSize; + return mHighlightedLabel.cachedTransform.localPosition + new Vector3(0f - num, y, 1f); + } + + private IEnumerator UpdateTweenPosition() + { + if (mHighlight != null && mHighlightedLabel != null) + { + TweenPosition tp = mHighlight.GetComponent(); + while (tp != null && tp.enabled) + { + tp.to = GetHighlightPosition(); + yield return (object)null; + } + } + mTweening = false; + } + + private void OnItemHover(GameObject go, bool isOver) + { + if (isOver) + { + UILabel component = go.GetComponent(); + Highlight(component, instant: false); + } + } + + private void Select(UILabel lbl, bool instant) + { + Highlight(lbl, instant); + UIEventListener component = lbl.gameObject.GetComponent(); + value = (component.parameter as string); + UIPlaySound[] components = GetComponents(); + int i = 0; + for (int num = components.Length; i < num; i++) + { + UIPlaySound uIPlaySound = components[i]; + if (uIPlaySound.trigger == UIPlaySound.Trigger.OnClick) + { + NGUITools.PlaySound(uIPlaySound.audioClip, uIPlaySound.volume, 1f); + } + } + } + + private void OnItemPress(GameObject go, bool isPressed) + { + if (isPressed) + { + Select(go.GetComponent(), instant: true); + } + } + + private void OnItemClick(GameObject go) + { + Close(); + } + + private void OnKey(KeyCode key) + { + if (base.enabled && NGUITools.GetActive(base.gameObject) && handleEvents) + { + int num = mLabelList.IndexOf(mHighlightedLabel); + if (num == -1) + { + num = 0; + } + switch (key) + { + case KeyCode.UpArrow: + if (num > 0) + { + Select(mLabelList[--num], instant: false); + } + break; + case KeyCode.DownArrow: + if (num + 1 < mLabelList.Count) + { + Select(mLabelList[++num], instant: false); + } + break; + case KeyCode.Escape: + OnSelect(isSelected: false); + break; + } + } + } + + private void OnDisable() + { + Close(); + } + + private void OnSelect(bool isSelected) + { + if (!isSelected) + { + Close(); + } + } + + public void Close() + { + if (mChild != null) + { + mLabelList.Clear(); + handleEvents = false; + if (isAnimated) + { + UIWidget[] componentsInChildren = mChild.GetComponentsInChildren(); + int i = 0; + for (int num = componentsInChildren.Length; i < num; i++) + { + UIWidget uIWidget = componentsInChildren[i]; + Color color = uIWidget.color; + color.a = 0f; + TweenColor.Begin(uIWidget.gameObject, 0.15f, color).method = UITweener.Method.EaseOut; + } + Collider[] componentsInChildren2 = mChild.GetComponentsInChildren(); + int j = 0; + for (int num2 = componentsInChildren2.Length; j < num2; j++) + { + componentsInChildren2[j].enabled = false; + } + UnityEngine.Object.Destroy(mChild, 0.15f); + } + else + { + UnityEngine.Object.Destroy(mChild); + } + mBackground = null; + mHighlight = null; + mChild = null; + } + } + + private void AnimateColor(UIWidget widget) + { + Color color = widget.color; + widget.color = new Color(color.r, color.g, color.b, 0f); + TweenColor.Begin(widget.gameObject, 0.15f, color).method = UITweener.Method.EaseOut; + } + + private void AnimatePosition(UIWidget widget, bool placeAbove, float bottom) + { + Vector3 localPosition = widget.cachedTransform.localPosition; + Vector3 localPosition2 = (!placeAbove) ? new Vector3(localPosition.x, 0f, localPosition.z) : new Vector3(localPosition.x, bottom, localPosition.z); + widget.cachedTransform.localPosition = localPosition2; + GameObject gameObject = widget.gameObject; + TweenPosition.Begin(gameObject, 0.15f, localPosition).method = UITweener.Method.EaseOut; + } + + private void AnimateScale(UIWidget widget, bool placeAbove, float bottom) + { + GameObject gameObject = widget.gameObject; + Transform cachedTransform = widget.cachedTransform; + float num = (float)activeFontSize * activeFontScale + mBgBorder * 2f; + cachedTransform.localScale = new Vector3(1f, num / (float)widget.height, 1f); + TweenScale.Begin(gameObject, 0.15f, Vector3.one).method = UITweener.Method.EaseOut; + if (placeAbove) + { + Vector3 localPosition = cachedTransform.localPosition; + cachedTransform.localPosition = new Vector3(localPosition.x, localPosition.y - (float)widget.height + num, localPosition.z); + TweenPosition.Begin(gameObject, 0.15f, localPosition).method = UITweener.Method.EaseOut; + } + } + + private void Animate(UIWidget widget, bool placeAbove, float bottom) + { + AnimateColor(widget); + AnimatePosition(widget, placeAbove, bottom); + } + + private void OnClick() + { + if (openOn != OpenOn.DoubleClick && openOn != OpenOn.Manual && (openOn != OpenOn.RightClick || UICamera.currentTouchID == -2)) + { + Show(); + } + } + + private void OnDoubleClick() + { + if (openOn == OpenOn.DoubleClick) + { + Show(); + } + } + + public void Show() + { + if (base.enabled && NGUITools.GetActive(base.gameObject) && mChild == null && atlas != null && isValid && items.Count > 0) + { + mLabelList.Clear(); + if (mPanel == null) + { + mPanel = UIPanel.Find(base.transform); + if (mPanel == null) + { + return; + } + } + handleEvents = true; + Transform transform = base.transform; + Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(transform.parent, transform); + mChild = new GameObject("Drop-down List"); + mChild.layer = base.gameObject.layer; + Transform transform2 = mChild.transform; + transform2.parent = transform.parent; + transform2.localPosition = bounds.min; + transform2.localRotation = Quaternion.identity; + transform2.localScale = Vector3.one; + mBackground = NGUITools.AddSprite(mChild, atlas, backgroundSprite); + mBackground.pivot = UIWidget.Pivot.TopLeft; + mBackground.depth = NGUITools.CalculateNextDepth(mPanel.gameObject); + mBackground.color = backgroundColor; + Vector4 border = mBackground.border; + mBgBorder = border.y; + mBackground.cachedTransform.localPosition = new Vector3(0f, border.y, 0f); + mHighlight = NGUITools.AddSprite(mChild, atlas, highlightSprite); + mHighlight.pivot = UIWidget.Pivot.TopLeft; + mHighlight.color = highlightColor; + UISpriteData atlasSprite = mHighlight.GetAtlasSprite(); + if (atlasSprite != null) + { + float num = (float)atlasSprite.borderTop; + float num2 = (float)activeFontSize; + float activeFontScale = this.activeFontScale; + float num3 = num2 * activeFontScale; + float num4 = 0f; + float num5 = 0f - padding.y; + List list = new List(); + if (!items.Contains(mSelectedItem)) + { + mSelectedItem = null; + } + int i = 0; + for (int count = items.Count; i < count; i++) + { + string text = items[i]; + UILabel uILabel = NGUITools.AddWidget(mChild); + uILabel.name = i.ToString(); + uILabel.pivot = UIWidget.Pivot.TopLeft; + uILabel.bitmapFont = bitmapFont; + uILabel.trueTypeFont = trueTypeFont; + uILabel.fontSize = fontSize; + uILabel.fontStyle = fontStyle; + uILabel.text = ((!isLocalized) ? text : Localization.Get(text)); + uILabel.color = textColor; + Transform cachedTransform = uILabel.cachedTransform; + float num6 = border.x + padding.x; + Vector2 pivotOffset = uILabel.pivotOffset; + cachedTransform.localPosition = new Vector3(num6 - pivotOffset.x, num5, -1f); + uILabel.overflowMethod = UILabel.Overflow.ResizeFreely; + uILabel.alignment = alignment; + list.Add(uILabel); + num5 -= num3; + num5 -= padding.y; + float a = num4; + Vector2 printedSize = uILabel.printedSize; + num4 = Mathf.Max(a, printedSize.x); + UIEventListener uIEventListener = UIEventListener.Get(uILabel.gameObject); + uIEventListener.onHover = OnItemHover; + uIEventListener.onPress = OnItemPress; + uIEventListener.onClick = OnItemClick; + uIEventListener.parameter = text; + if (mSelectedItem == text || (i == 0 && string.IsNullOrEmpty(mSelectedItem))) + { + Highlight(uILabel, instant: true); + } + mLabelList.Add(uILabel); + } + float a2 = num4; + Vector3 size = bounds.size; + num4 = Mathf.Max(a2, size.x * activeFontScale - (border.x + padding.x) * 2f); + float num7 = num4; + Vector3 vector = new Vector3(num7 * 0.5f, (0f - num2) * 0.5f, 0f); + Vector3 vector2 = new Vector3(num7, num3 + padding.y, 1f); + int j = 0; + for (int count2 = list.Count; j < count2; j++) + { + UILabel uILabel2 = list[j]; + NGUITools.AddWidgetCollider(uILabel2.gameObject); + uILabel2.autoResizeBoxCollider = false; + BoxCollider component = uILabel2.GetComponent(); + if (component != null) + { + Vector3 center = component.center; + vector.z = center.z; + component.center = vector; + component.size = vector2; + } + else + { + BoxCollider2D component2 = uILabel2.GetComponent(); + component2.offset = vector; + component2.size = vector2; + } + } + int width = Mathf.RoundToInt(num4); + num4 += (border.x + padding.x) * 2f; + num5 -= border.y; + mBackground.width = Mathf.RoundToInt(num4); + mBackground.height = Mathf.RoundToInt(0f - num5 + border.y); + int k = 0; + for (int count3 = list.Count; k < count3; k++) + { + UILabel uILabel3 = list[k]; + uILabel3.overflowMethod = UILabel.Overflow.ShrinkContent; + uILabel3.width = width; + } + float num8 = 2f * atlas.pixelSize; + float f = num4 - (border.x + padding.x) * 2f + (float)atlasSprite.borderLeft * num8; + float f2 = num3 + num * num8; + mHighlight.width = Mathf.RoundToInt(f); + mHighlight.height = Mathf.RoundToInt(f2); + bool flag = position == Position.Above; + if (position == Position.Auto) + { + UICamera uICamera = UICamera.FindCameraForLayer(base.gameObject.layer); + if (uICamera != null) + { + Vector3 vector3 = uICamera.cachedCamera.WorldToViewportPoint(transform.position); + flag = (vector3.y < 0.5f); + } + } + if (isAnimated) + { + float bottom = num5 + num3; + Animate(mHighlight, flag, bottom); + int l = 0; + for (int count4 = list.Count; l < count4; l++) + { + Animate(list[l], flag, bottom); + } + AnimateColor(mBackground); + AnimateScale(mBackground, flag, bottom); + } + if (flag) + { + Transform transform3 = transform2; + Vector3 min = bounds.min; + float x = min.x; + Vector3 max = bounds.max; + float y = max.y - num5 - border.y; + Vector3 min2 = bounds.min; + transform3.localPosition = new Vector3(x, y, min2.z); + } + } + } + else + { + OnSelect(isSelected: false); + } + } +} diff --git a/UIProgressBar.cs b/UIProgressBar.cs new file mode 100644 index 00000000..eb16742f --- /dev/null +++ b/UIProgressBar.cs @@ -0,0 +1,403 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/NGUI Progress Bar")] +[ExecuteInEditMode] +public class UIProgressBar : UIWidgetContainer +{ + public enum FillDirection + { + LeftToRight, + RightToLeft, + BottomToTop, + TopToBottom + } + + public delegate void OnDragFinished(); + + public static UIProgressBar current; + + public OnDragFinished onDragFinished; + + public Transform thumb; + + [HideInInspector] + [SerializeField] + protected UIWidget mBG; + + [HideInInspector] + [SerializeField] + protected UIWidget mFG; + + [HideInInspector] + [SerializeField] + protected float mValue = 1f; + + [HideInInspector] + [SerializeField] + protected FillDirection mFill; + + protected Transform mTrans; + + protected bool mIsDirty; + + protected Camera mCam; + + protected float mOffset; + + public int numberOfSteps; + + public List onChange = new List(); + + public Transform cachedTransform + { + get + { + if (mTrans == null) + { + mTrans = base.transform; + } + return mTrans; + } + } + + public Camera cachedCamera + { + get + { + if (mCam == null) + { + mCam = NGUITools.FindCameraForLayer(base.gameObject.layer); + } + return mCam; + } + } + + public UIWidget foregroundWidget + { + get + { + return mFG; + } + set + { + if (mFG != value) + { + mFG = value; + mIsDirty = true; + } + } + } + + public UIWidget backgroundWidget + { + get + { + return mBG; + } + set + { + if (mBG != value) + { + mBG = value; + mIsDirty = true; + } + } + } + + public FillDirection fillDirection + { + get + { + return mFill; + } + set + { + if (mFill != value) + { + mFill = value; + ForceUpdate(); + } + } + } + + public float value + { + get + { + if (numberOfSteps > 1) + { + return Mathf.Round(mValue * (float)(numberOfSteps - 1)) / (float)(numberOfSteps - 1); + } + return mValue; + } + set + { + float num = Mathf.Clamp01(value); + if (mValue != num) + { + float value2 = this.value; + mValue = num; + if (value2 != this.value) + { + ForceUpdate(); + if (current == null && NGUITools.GetActive(this) && EventDelegate.IsValid(onChange)) + { + current = this; + EventDelegate.Execute(onChange); + current = null; + } + } + } + } + } + + public float alpha + { + get + { + if (mFG != null) + { + return mFG.alpha; + } + if (mBG != null) + { + return mBG.alpha; + } + return 1f; + } + set + { + if (mFG != null) + { + mFG.alpha = value; + if (mFG.GetComponent() != null) + { + mFG.GetComponent().enabled = (mFG.alpha > 0.001f); + } + else if (mFG.GetComponent() != null) + { + mFG.GetComponent().enabled = (mFG.alpha > 0.001f); + } + } + if (mBG != null) + { + mBG.alpha = value; + if (mBG.GetComponent() != null) + { + mBG.GetComponent().enabled = (mBG.alpha > 0.001f); + } + else if (mBG.GetComponent() != null) + { + mBG.GetComponent().enabled = (mBG.alpha > 0.001f); + } + } + if (thumb != null) + { + UIWidget component = thumb.GetComponent(); + if (component != null) + { + component.alpha = value; + if (component.GetComponent() != null) + { + component.GetComponent().enabled = (component.alpha > 0.001f); + } + else if (component.GetComponent() != null) + { + component.GetComponent().enabled = (component.alpha > 0.001f); + } + } + } + } + } + + protected bool isHorizontal => mFill == FillDirection.LeftToRight || mFill == FillDirection.RightToLeft; + + protected bool isInverted => mFill == FillDirection.RightToLeft || mFill == FillDirection.TopToBottom; + + protected void Start() + { + Upgrade(); + if (Application.isPlaying) + { + if (mBG != null) + { + mBG.autoResizeBoxCollider = true; + } + OnStart(); + if (current == null && onChange != null) + { + current = this; + EventDelegate.Execute(onChange); + current = null; + } + } + ForceUpdate(); + } + + protected virtual void Upgrade() + { + } + + protected virtual void OnStart() + { + } + + protected void Update() + { + if (mIsDirty) + { + ForceUpdate(); + } + } + + protected void OnValidate() + { + if (NGUITools.GetActive(this)) + { + Upgrade(); + mIsDirty = true; + float num = Mathf.Clamp01(mValue); + if (mValue != num) + { + mValue = num; + } + if (numberOfSteps < 0) + { + numberOfSteps = 0; + } + ForceUpdate(); + } + else + { + float num2 = Mathf.Clamp01(mValue); + if (mValue != num2) + { + mValue = num2; + } + if (numberOfSteps < 0) + { + numberOfSteps = 0; + } + } + } + + protected float ScreenToValue(Vector2 screenPos) + { + Transform cachedTransform = this.cachedTransform; + Plane plane = new Plane(cachedTransform.rotation * Vector3.back, cachedTransform.position); + Ray ray = cachedCamera.ScreenPointToRay(screenPos); + if (!plane.Raycast(ray, out float enter)) + { + return value; + } + return LocalToValue(cachedTransform.InverseTransformPoint(ray.GetPoint(enter))); + } + + protected virtual float LocalToValue(Vector2 localPos) + { + if (mFG != null) + { + Vector3[] localCorners = mFG.localCorners; + Vector3 vector = localCorners[2] - localCorners[0]; + if (isHorizontal) + { + float num = (localPos.x - localCorners[0].x) / vector.x; + return (!isInverted) ? num : (1f - num); + } + float num2 = (localPos.y - localCorners[0].y) / vector.y; + return (!isInverted) ? num2 : (1f - num2); + } + return value; + } + + public virtual void ForceUpdate() + { + mIsDirty = false; + if (mFG != null) + { + UIBasicSprite uIBasicSprite = mFG as UIBasicSprite; + if (isHorizontal) + { + if (uIBasicSprite != null && uIBasicSprite.type == UIBasicSprite.Type.Filled) + { + if (uIBasicSprite.fillDirection == UIBasicSprite.FillDirection.Horizontal || uIBasicSprite.fillDirection == UIBasicSprite.FillDirection.Vertical) + { + uIBasicSprite.fillDirection = UIBasicSprite.FillDirection.Horizontal; + uIBasicSprite.invert = isInverted; + } + uIBasicSprite.fillAmount = value; + } + else + { + mFG.drawRegion = ((!isInverted) ? new Vector4(0f, 0f, value, 1f) : new Vector4(1f - value, 0f, 1f, 1f)); + mFG.enabled = (value > 0.001f); + } + } + else if (uIBasicSprite != null && uIBasicSprite.type == UIBasicSprite.Type.Filled) + { + if (uIBasicSprite.fillDirection == UIBasicSprite.FillDirection.Horizontal || uIBasicSprite.fillDirection == UIBasicSprite.FillDirection.Vertical) + { + uIBasicSprite.fillDirection = UIBasicSprite.FillDirection.Vertical; + uIBasicSprite.invert = isInverted; + } + uIBasicSprite.fillAmount = value; + } + else + { + mFG.drawRegion = ((!isInverted) ? new Vector4(0f, 0f, 1f, value) : new Vector4(0f, 1f - value, 1f, 1f)); + mFG.enabled = (value > 0.001f); + } + } + if (thumb != null && (mFG != null || mBG != null)) + { + Vector3[] array = (!(mFG != null)) ? mBG.localCorners : mFG.localCorners; + Vector4 vector = (!(mFG != null)) ? mBG.border : mFG.border; + array[0].x += vector.x; + array[1].x += vector.x; + array[2].x -= vector.z; + array[3].x -= vector.z; + array[0].y += vector.y; + array[1].y -= vector.w; + array[2].y -= vector.w; + array[3].y += vector.y; + Transform transform = (!(mFG != null)) ? mBG.cachedTransform : mFG.cachedTransform; + for (int i = 0; i < 4; i++) + { + array[i] = transform.TransformPoint(array[i]); + } + if (isHorizontal) + { + Vector3 a = Vector3.Lerp(array[0], array[1], 0.5f); + Vector3 b = Vector3.Lerp(array[2], array[3], 0.5f); + SetThumbPosition(Vector3.Lerp(a, b, (!isInverted) ? value : (1f - value))); + } + else + { + Vector3 a2 = Vector3.Lerp(array[0], array[3], 0.5f); + Vector3 b2 = Vector3.Lerp(array[1], array[2], 0.5f); + SetThumbPosition(Vector3.Lerp(a2, b2, (!isInverted) ? value : (1f - value))); + } + } + } + + protected void SetThumbPosition(Vector3 worldPos) + { + Transform parent = thumb.parent; + if (parent != null) + { + worldPos = parent.InverseTransformPoint(worldPos); + worldPos.x = Mathf.Round(worldPos.x); + worldPos.y = Mathf.Round(worldPos.y); + worldPos.z = 0f; + if (Vector3.Distance(thumb.localPosition, worldPos) > 0.001f) + { + thumb.localPosition = worldPos; + } + } + else if (Vector3.Distance(thumb.position, worldPos) > 1E-05f) + { + thumb.position = worldPos; + } + } +} diff --git a/UIRect.cs b/UIRect.cs new file mode 100644 index 00000000..94a75416 --- /dev/null +++ b/UIRect.cs @@ -0,0 +1,548 @@ +using System; +using UnityEngine; + +public abstract class UIRect : MonoBehaviour +{ + [Serializable] + public class AnchorPoint + { + public Transform target; + + public float relative; + + public int absolute; + + [NonSerialized] + public UIRect rect; + + [NonSerialized] + public Camera targetCam; + + public AnchorPoint() + { + } + + public AnchorPoint(float relative) + { + this.relative = relative; + } + + public void Set(float relative, float absolute) + { + this.relative = relative; + this.absolute = Mathf.FloorToInt(absolute + 0.5f); + } + + public void Set(Transform target, float relative, float absolute) + { + this.target = target; + this.relative = relative; + this.absolute = Mathf.FloorToInt(absolute + 0.5f); + } + + public void SetToNearest(float abs0, float abs1, float abs2) + { + SetToNearest(0f, 0.5f, 1f, abs0, abs1, abs2); + } + + public void SetToNearest(float rel0, float rel1, float rel2, float abs0, float abs1, float abs2) + { + float num = Mathf.Abs(abs0); + float num2 = Mathf.Abs(abs1); + float num3 = Mathf.Abs(abs2); + if (num < num2 && num < num3) + { + Set(rel0, abs0); + } + else if (num2 < num && num2 < num3) + { + Set(rel1, abs1); + } + else + { + Set(rel2, abs2); + } + } + + public void SetHorizontal(Transform parent, float localPos) + { + if ((bool)rect) + { + Vector3[] sides = rect.GetSides(parent); + float num = Mathf.Lerp(sides[0].x, sides[2].x, relative); + absolute = Mathf.FloorToInt(localPos - num + 0.5f); + } + else + { + Vector3 position = target.position; + if (parent != null) + { + position = parent.InverseTransformPoint(position); + } + absolute = Mathf.FloorToInt(localPos - position.x + 0.5f); + } + } + + public void SetVertical(Transform parent, float localPos) + { + if ((bool)rect) + { + Vector3[] sides = rect.GetSides(parent); + float num = Mathf.Lerp(sides[3].y, sides[1].y, relative); + absolute = Mathf.FloorToInt(localPos - num + 0.5f); + } + else + { + Vector3 position = target.position; + if (parent != null) + { + position = parent.InverseTransformPoint(position); + } + absolute = Mathf.FloorToInt(localPos - position.y + 0.5f); + } + } + + public Vector3[] GetSides(Transform relativeTo) + { + if (target != null) + { + if (rect != null) + { + return rect.GetSides(relativeTo); + } + if (target.GetComponent() != null) + { + return target.GetComponent().GetSides(relativeTo); + } + } + return null; + } + } + + public enum AnchorUpdate + { + OnEnable, + OnUpdate, + OnStart + } + + public AnchorPoint leftAnchor = new AnchorPoint(); + + public AnchorPoint rightAnchor = new AnchorPoint(1f); + + public AnchorPoint bottomAnchor = new AnchorPoint(); + + public AnchorPoint topAnchor = new AnchorPoint(1f); + + public AnchorUpdate updateAnchors = AnchorUpdate.OnUpdate; + + protected GameObject mGo; + + protected Transform mTrans; + + protected BetterList mChildren = new BetterList(); + + protected bool mChanged = true; + + protected bool mStarted; + + protected bool mParentFound; + + [NonSerialized] + private bool mUpdateAnchors = true; + + [NonSerialized] + private int mUpdateFrame = -1; + + [NonSerialized] + private bool mAnchorsCached; + + [NonSerialized] + public float finalAlpha = 1f; + + private UIRoot mRoot; + + private UIRect mParent; + + private bool mRootSet; + + protected Camera mCam; + + protected static Vector3[] mSides = new Vector3[4]; + + public GameObject cachedGameObject + { + get + { + if (mGo == null) + { + mGo = base.gameObject; + } + return mGo; + } + } + + public Transform cachedTransform + { + get + { + if (mTrans == null) + { + mTrans = base.transform; + } + return mTrans; + } + } + + public Camera anchorCamera + { + get + { + if (!mAnchorsCached) + { + ResetAnchors(); + } + return mCam; + } + } + + public bool isFullyAnchored => (bool)leftAnchor.target && (bool)rightAnchor.target && (bool)topAnchor.target && (bool)bottomAnchor.target; + + public virtual bool isAnchoredHorizontally => (bool)leftAnchor.target || (bool)rightAnchor.target; + + public virtual bool isAnchoredVertically => (bool)bottomAnchor.target || (bool)topAnchor.target; + + public virtual bool canBeAnchored => true; + + public UIRect parent + { + get + { + if (!mParentFound) + { + mParentFound = true; + mParent = NGUITools.FindInParents(cachedTransform.parent); + } + return mParent; + } + } + + public UIRoot root + { + get + { + if (parent != null) + { + return mParent.root; + } + if (!mRootSet) + { + mRootSet = true; + mRoot = NGUITools.FindInParents(cachedTransform); + } + return mRoot; + } + } + + public bool isAnchored => ((bool)leftAnchor.target || (bool)rightAnchor.target || (bool)topAnchor.target || (bool)bottomAnchor.target) && canBeAnchored; + + public abstract float alpha + { + get; + set; + } + + public abstract Vector3[] localCorners + { + get; + } + + public abstract Vector3[] worldCorners + { + get; + } + + protected float cameraRayDistance + { + get + { + if (anchorCamera == null) + { + return 0f; + } + if (!mCam.orthographic) + { + Transform cachedTransform = this.cachedTransform; + Transform transform = mCam.transform; + Plane plane = new Plane(cachedTransform.rotation * Vector3.back, cachedTransform.position); + Ray ray = new Ray(transform.position, transform.rotation * Vector3.forward); + if (plane.Raycast(ray, out float enter)) + { + return enter; + } + } + return Mathf.Lerp(mCam.nearClipPlane, mCam.farClipPlane, 0.5f); + } + } + + public abstract float CalculateFinalAlpha(int frameID); + + public virtual void Invalidate(bool includeChildren) + { + mChanged = true; + if (includeChildren) + { + for (int i = 0; i < mChildren.size; i++) + { + mChildren.buffer[i].Invalidate(includeChildren: true); + } + } + } + + public virtual Vector3[] GetSides(Transform relativeTo) + { + if (anchorCamera != null) + { + return mCam.GetSides(cameraRayDistance, relativeTo); + } + Vector3 position = cachedTransform.position; + for (int i = 0; i < 4; i++) + { + mSides[i] = position; + } + if (relativeTo != null) + { + for (int j = 0; j < 4; j++) + { + mSides[j] = relativeTo.InverseTransformPoint(mSides[j]); + } + } + return mSides; + } + + protected Vector3 GetLocalPos(AnchorPoint ac, Transform trans) + { + if (anchorCamera == null || ac.targetCam == null) + { + return cachedTransform.localPosition; + } + Vector3 vector = mCam.ViewportToWorldPoint(ac.targetCam.WorldToViewportPoint(ac.target.position)); + if (trans != null) + { + vector = trans.InverseTransformPoint(vector); + } + vector.x = Mathf.Floor(vector.x + 0.5f); + vector.y = Mathf.Floor(vector.y + 0.5f); + return vector; + } + + protected virtual void OnEnable() + { + mUpdateFrame = -1; + if (updateAnchors == AnchorUpdate.OnEnable) + { + mAnchorsCached = false; + mUpdateAnchors = true; + } + if (mStarted) + { + OnInit(); + } + mUpdateFrame = -1; + } + + protected virtual void OnInit() + { + mChanged = true; + mRootSet = false; + mParentFound = false; + if (parent != null) + { + mParent.mChildren.Add(this); + } + } + + protected virtual void OnDisable() + { + if ((bool)mParent) + { + mParent.mChildren.Remove(this); + } + mParent = null; + mRoot = null; + mRootSet = false; + mParentFound = false; + } + + protected void Start() + { + mStarted = true; + OnInit(); + OnStart(); + } + + public void Update() + { + if (!mAnchorsCached) + { + ResetAnchors(); + } + int frameCount = Time.frameCount; + if (mUpdateFrame != frameCount) + { + if (updateAnchors == AnchorUpdate.OnUpdate || mUpdateAnchors) + { + mUpdateFrame = frameCount; + mUpdateAnchors = false; + bool flag = false; + if ((bool)leftAnchor.target) + { + flag = true; + if (leftAnchor.rect != null && leftAnchor.rect.mUpdateFrame != frameCount) + { + leftAnchor.rect.Update(); + } + } + if ((bool)bottomAnchor.target) + { + flag = true; + if (bottomAnchor.rect != null && bottomAnchor.rect.mUpdateFrame != frameCount) + { + bottomAnchor.rect.Update(); + } + } + if ((bool)rightAnchor.target) + { + flag = true; + if (rightAnchor.rect != null && rightAnchor.rect.mUpdateFrame != frameCount) + { + rightAnchor.rect.Update(); + } + } + if ((bool)topAnchor.target) + { + flag = true; + if (topAnchor.rect != null && topAnchor.rect.mUpdateFrame != frameCount) + { + topAnchor.rect.Update(); + } + } + if (flag) + { + OnAnchor(); + } + } + OnUpdate(); + } + } + + public void UpdateAnchors() + { + if (isAnchored && updateAnchors != AnchorUpdate.OnStart) + { + OnAnchor(); + } + } + + protected abstract void OnAnchor(); + + public void SetAnchor(Transform t) + { + leftAnchor.target = t; + rightAnchor.target = t; + topAnchor.target = t; + bottomAnchor.target = t; + ResetAnchors(); + UpdateAnchors(); + } + + public void SetAnchor(GameObject go) + { + Transform target = (!(go != null)) ? null : go.transform; + leftAnchor.target = target; + rightAnchor.target = target; + topAnchor.target = target; + bottomAnchor.target = target; + ResetAnchors(); + UpdateAnchors(); + } + + public void SetAnchor(GameObject go, int left, int bottom, int right, int top) + { + Transform target = (!(go != null)) ? null : go.transform; + leftAnchor.target = target; + rightAnchor.target = target; + topAnchor.target = target; + bottomAnchor.target = target; + leftAnchor.relative = 0f; + rightAnchor.relative = 1f; + bottomAnchor.relative = 0f; + topAnchor.relative = 1f; + leftAnchor.absolute = left; + rightAnchor.absolute = right; + bottomAnchor.absolute = bottom; + topAnchor.absolute = top; + ResetAnchors(); + UpdateAnchors(); + } + + public void ResetAnchors() + { + mAnchorsCached = true; + leftAnchor.rect = ((!(bool)leftAnchor.target) ? null : leftAnchor.target.GetComponent()); + bottomAnchor.rect = ((!(bool)bottomAnchor.target) ? null : bottomAnchor.target.GetComponent()); + rightAnchor.rect = ((!(bool)rightAnchor.target) ? null : rightAnchor.target.GetComponent()); + topAnchor.rect = ((!(bool)topAnchor.target) ? null : topAnchor.target.GetComponent()); + mCam = NGUITools.FindCameraForLayer(cachedGameObject.layer); + FindCameraFor(leftAnchor); + FindCameraFor(bottomAnchor); + FindCameraFor(rightAnchor); + FindCameraFor(topAnchor); + mUpdateAnchors = true; + } + + public void ResetAndUpdateAnchors() + { + ResetAnchors(); + UpdateAnchors(); + } + + public abstract void SetRect(float x, float y, float width, float height); + + private void FindCameraFor(AnchorPoint ap) + { + if (ap.target == null || ap.rect != null) + { + ap.targetCam = null; + } + else + { + ap.targetCam = NGUITools.FindCameraForLayer(ap.target.gameObject.layer); + } + } + + public virtual void ParentHasChanged() + { + mParentFound = false; + UIRect y = NGUITools.FindInParents(cachedTransform.parent); + if (mParent != y) + { + if ((bool)mParent) + { + mParent.mChildren.Remove(this); + } + mParent = y; + if ((bool)mParent) + { + mParent.mChildren.Add(this); + } + mRootSet = false; + } + } + + protected abstract void OnStart(); + + protected virtual void OnUpdate() + { + } +} diff --git a/UIRoot.cs b/UIRoot.cs new file mode 100644 index 00000000..bba9cc98 --- /dev/null +++ b/UIRoot.cs @@ -0,0 +1,238 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Root")] +[ExecuteInEditMode] +public class UIRoot : MonoBehaviour +{ + public enum Scaling + { + Flexible, + Constrained, + ConstrainedOnMobiles + } + + public enum Constraint + { + Fit, + Fill, + FitWidth, + FitHeight + } + + public static List list = new List(); + + public Scaling scalingStyle; + + public int manualWidth = 1280; + + public int manualHeight = 720; + + public int minimumHeight = 320; + + public int maximumHeight = 1536; + + public bool fitWidth; + + public bool fitHeight = true; + + public bool adjustByDPI; + + public bool shrinkPortraitUI; + + private Transform mTrans; + + public Constraint constraint + { + get + { + if (fitWidth) + { + if (fitHeight) + { + return Constraint.Fit; + } + return Constraint.FitWidth; + } + if (fitHeight) + { + return Constraint.FitHeight; + } + return Constraint.Fill; + } + } + + public Scaling activeScaling + { + get + { + Scaling scaling = scalingStyle; + if (scaling == Scaling.ConstrainedOnMobiles) + { + return Scaling.Flexible; + } + return scaling; + } + } + + public int activeHeight + { + get + { + if (activeScaling == Scaling.Flexible) + { + Vector2 screenSize = NGUITools.screenSize; + float num = screenSize.x / screenSize.y; + if (screenSize.y < (float)minimumHeight) + { + screenSize.y = (float)minimumHeight; + screenSize.x = screenSize.y * num; + } + else if (screenSize.y > (float)maximumHeight) + { + screenSize.y = (float)maximumHeight; + screenSize.x = screenSize.y * num; + } + int num2 = Mathf.RoundToInt((!shrinkPortraitUI || !(screenSize.y > screenSize.x)) ? screenSize.y : (screenSize.y / num)); + return (!adjustByDPI) ? num2 : NGUIMath.AdjustByDPI((float)num2); + } + Constraint constraint = this.constraint; + if (constraint != Constraint.FitHeight) + { + Vector2 screenSize2 = NGUITools.screenSize; + float num3 = screenSize2.x / screenSize2.y; + float num4 = (float)manualWidth / (float)manualHeight; + switch (constraint) + { + case Constraint.FitWidth: + return Mathf.RoundToInt((float)manualWidth / num3); + case Constraint.Fit: + return (!(num4 > num3)) ? manualHeight : Mathf.RoundToInt((float)manualWidth / num3); + case Constraint.Fill: + return (!(num4 < num3)) ? manualHeight : Mathf.RoundToInt((float)manualWidth / num3); + default: + return manualHeight; + } + } + return manualHeight; + } + } + + public float pixelSizeAdjustment + { + get + { + Vector2 screenSize = NGUITools.screenSize; + int num = Mathf.RoundToInt(screenSize.y); + return (num != -1) ? GetPixelSizeAdjustment(num) : 1f; + } + } + + public static float GetPixelSizeAdjustment(GameObject go) + { + UIRoot uIRoot = NGUITools.FindInParents(go); + return (!(uIRoot != null)) ? 1f : uIRoot.pixelSizeAdjustment; + } + + public float GetPixelSizeAdjustment(int height) + { + height = Mathf.Max(2, height); + if (activeScaling == Scaling.Constrained) + { + return (float)activeHeight / (float)height; + } + if (height < minimumHeight) + { + return (float)minimumHeight / (float)height; + } + if (height > maximumHeight) + { + return (float)maximumHeight / (float)height; + } + return 1f; + } + + protected virtual void Awake() + { + mTrans = base.transform; + } + + protected virtual void OnEnable() + { + list.Add(this); + } + + protected virtual void OnDisable() + { + list.Remove(this); + } + + protected virtual void Start() + { + UIOrthoCamera componentInChildren = GetComponentInChildren(); + if (componentInChildren != null) + { + Debug.LogWarning("UIRoot should not be active at the same time as UIOrthoCamera. Disabling UIOrthoCamera.", componentInChildren); + Camera component = componentInChildren.gameObject.GetComponent(); + componentInChildren.enabled = false; + if (component != null) + { + component.orthographicSize = 1f; + } + } + else + { + Update(); + } + } + + private void Update() + { + if (mTrans != null) + { + float num = (float)activeHeight; + if (num > 0f) + { + float num2 = 2f / num; + Vector3 localScale = mTrans.localScale; + if (!(Mathf.Abs(localScale.x - num2) <= 1.401298E-45f) || !(Mathf.Abs(localScale.y - num2) <= 1.401298E-45f) || !(Mathf.Abs(localScale.z - num2) <= 1.401298E-45f)) + { + mTrans.localScale = new Vector3(num2, num2, num2); + } + } + } + } + + public static void Broadcast(string funcName) + { + int i = 0; + for (int count = list.Count; i < count; i++) + { + UIRoot uIRoot = list[i]; + if (uIRoot != null) + { + uIRoot.BroadcastMessage(funcName, SendMessageOptions.DontRequireReceiver); + } + } + } + + public static void Broadcast(string funcName, object param) + { + if (param == null) + { + Debug.LogError("SendMessage is bugged when you try to pass 'null' in the parameter field. It behaves as if no parameter was specified."); + } + else + { + int i = 0; + for (int count = list.Count; i < count; i++) + { + UIRoot uIRoot = list[i]; + if (uIRoot != null) + { + uIRoot.BroadcastMessage(funcName, param, SendMessageOptions.DontRequireReceiver); + } + } + } + } +} diff --git a/UISavedOption.cs b/UISavedOption.cs new file mode 100644 index 00000000..af244dfc --- /dev/null +++ b/UISavedOption.cs @@ -0,0 +1,97 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Saved Option")] +public class UISavedOption : MonoBehaviour +{ + public string keyName; + + private UIPopupList mList; + + private UIToggle mCheck; + + private string key => (!string.IsNullOrEmpty(keyName)) ? keyName : ("NGUI State: " + base.name); + + private void Awake() + { + mList = GetComponent(); + mCheck = GetComponent(); + } + + private void OnEnable() + { + if (mList != null) + { + EventDelegate.Add(mList.onChange, SaveSelection); + } + if (mCheck != null) + { + EventDelegate.Add(mCheck.onChange, SaveState); + } + if (mList != null) + { + string @string = PlayerPrefs.GetString(key); + if (!string.IsNullOrEmpty(@string)) + { + mList.value = @string; + } + } + else if (mCheck != null) + { + mCheck.value = (PlayerPrefs.GetInt(key, mCheck.startsActive ? 1 : 0) != 0); + } + else + { + string string2 = PlayerPrefs.GetString(key); + UIToggle[] componentsInChildren = GetComponentsInChildren(includeInactive: true); + int i = 0; + for (int num = componentsInChildren.Length; i < num; i++) + { + UIToggle uIToggle = componentsInChildren[i]; + uIToggle.value = (uIToggle.name == string2); + } + } + } + + private void OnDisable() + { + if (mCheck != null) + { + EventDelegate.Remove(mCheck.onChange, SaveState); + } + if (mList != null) + { + EventDelegate.Remove(mList.onChange, SaveSelection); + } + if (mCheck == null && mList == null) + { + UIToggle[] componentsInChildren = GetComponentsInChildren(includeInactive: true); + int num = 0; + int num2 = componentsInChildren.Length; + UIToggle uIToggle; + while (true) + { + if (num >= num2) + { + return; + } + uIToggle = componentsInChildren[num]; + if (uIToggle.value) + { + break; + } + num++; + } + PlayerPrefs.SetString(key, uIToggle.name); + } + } + + public void SaveSelection() + { + PlayerPrefs.SetString(key, UIPopupList.current.value); + } + + public void SaveState() + { + PlayerPrefs.SetInt(key, UIToggle.current.value ? 1 : 0); + } +} diff --git a/UIScrollBar.cs b/UIScrollBar.cs new file mode 100644 index 00000000..d808d0e2 --- /dev/null +++ b/UIScrollBar.cs @@ -0,0 +1,158 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/NGUI Scroll Bar")] +[ExecuteInEditMode] +public class UIScrollBar : UISlider +{ + private enum Direction + { + Horizontal, + Vertical, + Upgraded + } + + [HideInInspector] + [SerializeField] + protected float mSize = 1f; + + [HideInInspector] + [SerializeField] + private float mScroll; + + [HideInInspector] + [SerializeField] + private Direction mDir = Direction.Upgraded; + + [Obsolete("Use 'value' instead")] + public float scrollValue + { + get + { + return base.value; + } + set + { + base.value = value; + } + } + + public float barSize + { + get + { + return mSize; + } + set + { + float num = Mathf.Clamp01(value); + if (mSize != num) + { + mSize = num; + mIsDirty = true; + if (NGUITools.GetActive(this)) + { + if (UIProgressBar.current == null && onChange != null) + { + UIProgressBar.current = this; + EventDelegate.Execute(onChange); + UIProgressBar.current = null; + } + ForceUpdate(); + } + } + } + } + + protected override void Upgrade() + { + if (mDir != Direction.Upgraded) + { + mValue = mScroll; + if (mDir == Direction.Horizontal) + { + mFill = (mInverted ? FillDirection.RightToLeft : FillDirection.LeftToRight); + } + else + { + mFill = ((!mInverted) ? FillDirection.TopToBottom : FillDirection.BottomToTop); + } + mDir = Direction.Upgraded; + } + } + + protected override void OnStart() + { + base.OnStart(); + if (mFG != null && mFG.gameObject != base.gameObject && (mFG.GetComponent() != null || mFG.GetComponent() != null)) + { + UIEventListener uIEventListener = UIEventListener.Get(mFG.gameObject); + UIEventListener uIEventListener2 = uIEventListener; + uIEventListener2.onPress = (UIEventListener.BoolDelegate)Delegate.Combine(uIEventListener2.onPress, new UIEventListener.BoolDelegate(base.OnPressForeground)); + UIEventListener uIEventListener3 = uIEventListener; + uIEventListener3.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener3.onDrag, new UIEventListener.VectorDelegate(base.OnDragForeground)); + mFG.autoResizeBoxCollider = true; + } + } + + protected override float LocalToValue(Vector2 localPos) + { + if (mFG != null) + { + float num = Mathf.Clamp01(mSize) * 0.5f; + float t = num; + float t2 = 1f - num; + Vector3[] localCorners = mFG.localCorners; + if (base.isHorizontal) + { + t = Mathf.Lerp(localCorners[0].x, localCorners[2].x, t); + t2 = Mathf.Lerp(localCorners[0].x, localCorners[2].x, t2); + float num2 = t2 - t; + if (num2 == 0f) + { + return base.value; + } + return (!base.isInverted) ? ((localPos.x - t) / num2) : ((t2 - localPos.x) / num2); + } + t = Mathf.Lerp(localCorners[0].y, localCorners[1].y, t); + t2 = Mathf.Lerp(localCorners[3].y, localCorners[2].y, t2); + float num3 = t2 - t; + if (num3 == 0f) + { + return base.value; + } + return (!base.isInverted) ? ((localPos.y - t) / num3) : ((t2 - localPos.y) / num3); + } + return base.LocalToValue(localPos); + } + + public override void ForceUpdate() + { + if (mFG != null) + { + mIsDirty = false; + float num = Mathf.Clamp01(mSize) * 0.5f; + float num2 = Mathf.Lerp(num, 1f - num, base.value); + float num3 = num2 - num; + float num4 = num2 + num; + if (base.isHorizontal) + { + mFG.drawRegion = ((!base.isInverted) ? new Vector4(num3, 0f, num4, 1f) : new Vector4(1f - num4, 0f, 1f - num3, 1f)); + } + else + { + mFG.drawRegion = ((!base.isInverted) ? new Vector4(0f, num3, 1f, num4) : new Vector4(0f, 1f - num4, 1f, 1f - num3)); + } + if (thumb != null) + { + Vector4 drawingDimensions = mFG.drawingDimensions; + Vector3 position = new Vector3(Mathf.Lerp(drawingDimensions.x, drawingDimensions.z, 0.5f), Mathf.Lerp(drawingDimensions.y, drawingDimensions.w, 0.5f)); + SetThumbPosition(mFG.cachedTransform.TransformPoint(position)); + } + } + else + { + base.ForceUpdate(); + } + } +} diff --git a/UIScrollView.cs b/UIScrollView.cs new file mode 100644 index 00000000..fdf07779 --- /dev/null +++ b/UIScrollView.cs @@ -0,0 +1,852 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Scroll View")] +[ExecuteInEditMode] +[RequireComponent(typeof(UIPanel))] +public class UIScrollView : MonoBehaviour +{ + public enum Movement + { + Horizontal, + Vertical, + Unrestricted, + Custom + } + + public enum DragEffect + { + None, + Momentum, + MomentumAndSpring + } + + public enum ShowCondition + { + Always, + OnlyIfNeeded, + WhenDragging + } + + public delegate void OnDragNotification(); + + public static BetterList list = new BetterList(); + + public Movement movement; + + public DragEffect dragEffect = DragEffect.MomentumAndSpring; + + public bool restrictWithinPanel = true; + + public bool disableDragIfFits; + + public bool smoothDragStart = true; + + public bool iOSDragEmulation = true; + + public float scrollWheelFactor = 0.25f; + + public float momentumAmount = 35f; + + public UIProgressBar horizontalScrollBar; + + public UIProgressBar verticalScrollBar; + + public ShowCondition showScrollBars = ShowCondition.OnlyIfNeeded; + + public Vector2 customMovement = new Vector2(1f, 0f); + + public UIWidget.Pivot contentPivot; + + public OnDragNotification onDragStarted; + + public OnDragNotification onDragFinished; + + public OnDragNotification onMomentumMove; + + public OnDragNotification onStoppedMoving; + + [HideInInspector] + [SerializeField] + private Vector3 scale = new Vector3(1f, 0f, 0f); + + [HideInInspector] + [SerializeField] + private Vector2 relativePositionOnReset = Vector2.zero; + + protected Transform mTrans; + + protected UIPanel mPanel; + + protected Plane mPlane; + + protected Vector3 mLastPos; + + protected bool mPressed; + + protected Vector3 mMomentum = Vector3.zero; + + protected float mScroll; + + protected Bounds mBounds; + + protected bool mCalculatedBounds; + + protected bool mShouldMove; + + protected bool mIgnoreCallbacks; + + protected int mDragID = -10; + + protected Vector2 mDragStartOffset = Vector2.zero; + + protected bool mDragStarted; + + [HideInInspector] + public UICenterOnChild centerOnChild; + + public UIPanel panel => mPanel; + + public bool isDragging => mPressed && mDragStarted; + + public virtual Bounds bounds + { + get + { + if (!mCalculatedBounds) + { + mCalculatedBounds = true; + mTrans = base.transform; + mBounds = NGUIMath.CalculateRelativeWidgetBounds(mTrans, mTrans); + } + return mBounds; + } + } + + public bool canMoveHorizontally => movement == Movement.Horizontal || movement == Movement.Unrestricted || (movement == Movement.Custom && customMovement.x != 0f); + + public bool canMoveVertically => movement == Movement.Vertical || movement == Movement.Unrestricted || (movement == Movement.Custom && customMovement.y != 0f); + + public virtual bool shouldMoveHorizontally + { + get + { + Vector3 size = bounds.size; + float num = size.x; + if (mPanel.clipping == UIDrawCall.Clipping.SoftClip) + { + float num2 = num; + Vector2 clipSoftness = mPanel.clipSoftness; + num = num2 + clipSoftness.x * 2f; + } + return Mathf.RoundToInt(num - mPanel.width) > 0; + } + } + + public virtual bool shouldMoveVertically + { + get + { + Vector3 size = bounds.size; + float num = size.y; + if (mPanel.clipping == UIDrawCall.Clipping.SoftClip) + { + float num2 = num; + Vector2 clipSoftness = mPanel.clipSoftness; + num = num2 + clipSoftness.y * 2f; + } + return Mathf.RoundToInt(num - mPanel.height) > 0; + } + } + + protected virtual bool shouldMove + { + get + { + if (!disableDragIfFits) + { + return true; + } + if (mPanel == null) + { + mPanel = GetComponent(); + } + Vector4 finalClipRegion = mPanel.finalClipRegion; + Bounds bounds = this.bounds; + float num = (finalClipRegion.z != 0f) ? (finalClipRegion.z * 0.5f) : ((float)Screen.width); + float num2 = (finalClipRegion.w != 0f) ? (finalClipRegion.w * 0.5f) : ((float)Screen.height); + if (canMoveHorizontally) + { + Vector3 min = bounds.min; + if (min.x < finalClipRegion.x - num) + { + return true; + } + Vector3 max = bounds.max; + if (max.x > finalClipRegion.x + num) + { + return true; + } + } + if (canMoveVertically) + { + Vector3 min2 = bounds.min; + if (min2.y < finalClipRegion.y - num2) + { + return true; + } + Vector3 max2 = bounds.max; + if (max2.y > finalClipRegion.y + num2) + { + return true; + } + } + return false; + } + } + + public Vector3 currentMomentum + { + get + { + return mMomentum; + } + set + { + mMomentum = value; + mShouldMove = true; + } + } + + private void Awake() + { + mTrans = base.transform; + mPanel = GetComponent(); + if (mPanel.clipping == UIDrawCall.Clipping.None) + { + mPanel.clipping = UIDrawCall.Clipping.ConstrainButDontClip; + } + if (movement != Movement.Custom && scale.sqrMagnitude > 0.001f) + { + if (scale.x == 1f && scale.y == 0f) + { + movement = Movement.Horizontal; + } + else if (scale.x == 0f && scale.y == 1f) + { + movement = Movement.Vertical; + } + else if (scale.x == 1f && scale.y == 1f) + { + movement = Movement.Unrestricted; + } + else + { + movement = Movement.Custom; + customMovement.x = scale.x; + customMovement.y = scale.y; + } + scale = Vector3.zero; + } + if (contentPivot == UIWidget.Pivot.TopLeft && relativePositionOnReset != Vector2.zero) + { + contentPivot = NGUIMath.GetPivot(new Vector2(relativePositionOnReset.x, 1f - relativePositionOnReset.y)); + relativePositionOnReset = Vector2.zero; + } + } + + private void OnEnable() + { + list.Add(this); + if (Application.isPlaying) + { + if (horizontalScrollBar != null) + { + EventDelegate.Add(horizontalScrollBar.onChange, OnScrollBar); + horizontalScrollBar.alpha = ((showScrollBars != 0 && !shouldMoveHorizontally) ? 0f : 1f); + } + if (verticalScrollBar != null) + { + EventDelegate.Add(verticalScrollBar.onChange, OnScrollBar); + verticalScrollBar.alpha = ((showScrollBars != 0 && !shouldMoveVertically) ? 0f : 1f); + } + } + } + + private void OnDisable() + { + list.Remove(this); + } + + public bool RestrictWithinBounds(bool instant) + { + return RestrictWithinBounds(instant, horizontal: true, vertical: true); + } + + public bool RestrictWithinBounds(bool instant, bool horizontal, bool vertical) + { + Bounds bounds = this.bounds; + Vector3 vector = mPanel.CalculateConstrainOffset(bounds.min, bounds.max); + if (!horizontal) + { + vector.x = 0f; + } + if (!vertical) + { + vector.y = 0f; + } + if (vector.sqrMagnitude > 0.1f) + { + if (!instant && dragEffect == DragEffect.MomentumAndSpring) + { + Vector3 pos = mTrans.localPosition + vector; + pos.x = Mathf.Round(pos.x); + pos.y = Mathf.Round(pos.y); + SpringPanel.Begin(mPanel.gameObject, pos, 13f).strength = 8f; + } + else + { + MoveRelative(vector); + if (Mathf.Abs(vector.x) > 0.01f) + { + mMomentum.x = 0f; + } + if (Mathf.Abs(vector.y) > 0.01f) + { + mMomentum.y = 0f; + } + if (Mathf.Abs(vector.z) > 0.01f) + { + mMomentum.z = 0f; + } + mScroll = 0f; + } + return true; + } + return false; + } + + public void DisableSpring() + { + SpringPanel component = GetComponent(); + if (component != null) + { + component.enabled = false; + } + } + + public void UpdateScrollbars() + { + UpdateScrollbars(recalculateBounds: true); + } + + public virtual void UpdateScrollbars(bool recalculateBounds) + { + if (!(mPanel == null)) + { + if (horizontalScrollBar != null || verticalScrollBar != null) + { + if (recalculateBounds) + { + mCalculatedBounds = false; + mShouldMove = shouldMove; + } + Bounds bounds = this.bounds; + Vector2 vector = bounds.min; + Vector2 vector2 = bounds.max; + if (horizontalScrollBar != null && vector2.x > vector.x) + { + Vector4 finalClipRegion = mPanel.finalClipRegion; + int num = Mathf.RoundToInt(finalClipRegion.z); + if ((num & 1) != 0) + { + num--; + } + float f = (float)num * 0.5f; + f = Mathf.Round(f); + if (mPanel.clipping == UIDrawCall.Clipping.SoftClip) + { + float num2 = f; + Vector2 clipSoftness = mPanel.clipSoftness; + f = num2 - clipSoftness.x; + } + float contentSize = vector2.x - vector.x; + float viewSize = f * 2f; + float x = vector.x; + float x2 = vector2.x; + float num3 = finalClipRegion.x - f; + float num4 = finalClipRegion.x + f; + x = num3 - x; + x2 -= num4; + UpdateScrollbars(horizontalScrollBar, x, x2, contentSize, viewSize, inverted: false); + } + if (verticalScrollBar != null && vector2.y > vector.y) + { + Vector4 finalClipRegion2 = mPanel.finalClipRegion; + int num5 = Mathf.RoundToInt(finalClipRegion2.w); + if ((num5 & 1) != 0) + { + num5--; + } + float f2 = (float)num5 * 0.5f; + f2 = Mathf.Round(f2); + if (mPanel.clipping == UIDrawCall.Clipping.SoftClip) + { + float num6 = f2; + Vector2 clipSoftness2 = mPanel.clipSoftness; + f2 = num6 - clipSoftness2.y; + } + float contentSize2 = vector2.y - vector.y; + float viewSize2 = f2 * 2f; + float y = vector.y; + float y2 = vector2.y; + float num7 = finalClipRegion2.y - f2; + float num8 = finalClipRegion2.y + f2; + y = num7 - y; + y2 -= num8; + UpdateScrollbars(verticalScrollBar, y, y2, contentSize2, viewSize2, inverted: true); + } + } + else if (recalculateBounds) + { + mCalculatedBounds = false; + } + } + } + + protected void UpdateScrollbars(UIProgressBar slider, float contentMin, float contentMax, float contentSize, float viewSize, bool inverted) + { + if (!(slider == null)) + { + mIgnoreCallbacks = true; + float num; + if (viewSize < contentSize) + { + contentMin = Mathf.Clamp01(contentMin / contentSize); + contentMax = Mathf.Clamp01(contentMax / contentSize); + num = contentMin + contentMax; + slider.value = (inverted ? ((!(num > 0.001f)) ? 0f : (1f - contentMin / num)) : ((!(num > 0.001f)) ? 1f : (contentMin / num))); + } + else + { + contentMin = Mathf.Clamp01((0f - contentMin) / contentSize); + contentMax = Mathf.Clamp01((0f - contentMax) / contentSize); + num = contentMin + contentMax; + slider.value = (inverted ? ((!(num > 0.001f)) ? 0f : (1f - contentMin / num)) : ((!(num > 0.001f)) ? 1f : (contentMin / num))); + if (contentSize > 0f) + { + contentMin = Mathf.Clamp01(contentMin / contentSize); + contentMax = Mathf.Clamp01(contentMax / contentSize); + num = contentMin + contentMax; + } + } + UIScrollBar uIScrollBar = slider as UIScrollBar; + if (uIScrollBar != null) + { + uIScrollBar.barSize = 1f - num; + } + mIgnoreCallbacks = false; + } + } + + public virtual void SetDragAmount(float x, float y, bool updateScrollbars) + { + if (mPanel == null) + { + mPanel = GetComponent(); + } + DisableSpring(); + Bounds bounds = this.bounds; + Vector3 min = bounds.min; + float x2 = min.x; + Vector3 max = bounds.max; + if (x2 != max.x) + { + Vector3 min2 = bounds.min; + float y2 = min2.y; + Vector3 max2 = bounds.max; + if (y2 != max2.y) + { + Vector4 finalClipRegion = mPanel.finalClipRegion; + float num = finalClipRegion.z * 0.5f; + float num2 = finalClipRegion.w * 0.5f; + Vector3 min3 = bounds.min; + float num3 = min3.x + num; + Vector3 max3 = bounds.max; + float num4 = max3.x - num; + Vector3 min4 = bounds.min; + float num5 = min4.y + num2; + Vector3 max4 = bounds.max; + float num6 = max4.y - num2; + if (mPanel.clipping == UIDrawCall.Clipping.SoftClip) + { + float num7 = num3; + Vector2 clipSoftness = mPanel.clipSoftness; + num3 = num7 - clipSoftness.x; + float num8 = num4; + Vector2 clipSoftness2 = mPanel.clipSoftness; + num4 = num8 + clipSoftness2.x; + float num9 = num5; + Vector2 clipSoftness3 = mPanel.clipSoftness; + num5 = num9 - clipSoftness3.y; + float num10 = num6; + Vector2 clipSoftness4 = mPanel.clipSoftness; + num6 = num10 + clipSoftness4.y; + } + float num11 = Mathf.Lerp(num3, num4, x); + float num12 = Mathf.Lerp(num6, num5, y); + if (!updateScrollbars) + { + Vector3 localPosition = mTrans.localPosition; + if (canMoveHorizontally) + { + localPosition.x += finalClipRegion.x - num11; + } + if (canMoveVertically) + { + localPosition.y += finalClipRegion.y - num12; + } + mTrans.localPosition = localPosition; + } + if (canMoveHorizontally) + { + finalClipRegion.x = num11; + } + if (canMoveVertically) + { + finalClipRegion.y = num12; + } + Vector4 baseClipRegion = mPanel.baseClipRegion; + mPanel.clipOffset = new Vector2(finalClipRegion.x - baseClipRegion.x, finalClipRegion.y - baseClipRegion.y); + if (updateScrollbars) + { + UpdateScrollbars(mDragID == -10); + } + } + } + } + + public void InvalidateBounds() + { + mCalculatedBounds = false; + } + + [ContextMenu("Reset Clipping Position")] + public void ResetPosition() + { + if (NGUITools.GetActive(this)) + { + mCalculatedBounds = false; + Vector2 pivotOffset = NGUIMath.GetPivotOffset(contentPivot); + SetDragAmount(pivotOffset.x, 1f - pivotOffset.y, updateScrollbars: false); + SetDragAmount(pivotOffset.x, 1f - pivotOffset.y, updateScrollbars: true); + } + } + + public void UpdatePosition() + { + if (!mIgnoreCallbacks && (horizontalScrollBar != null || verticalScrollBar != null)) + { + mIgnoreCallbacks = true; + mCalculatedBounds = false; + Vector2 pivotOffset = NGUIMath.GetPivotOffset(contentPivot); + float x = (!(horizontalScrollBar != null)) ? pivotOffset.x : horizontalScrollBar.value; + float y = (!(verticalScrollBar != null)) ? (1f - pivotOffset.y) : verticalScrollBar.value; + SetDragAmount(x, y, updateScrollbars: false); + UpdateScrollbars(recalculateBounds: true); + mIgnoreCallbacks = false; + } + } + + public void OnScrollBar() + { + if (!mIgnoreCallbacks) + { + mIgnoreCallbacks = true; + float x = (!(horizontalScrollBar != null)) ? 0f : horizontalScrollBar.value; + float y = (!(verticalScrollBar != null)) ? 0f : verticalScrollBar.value; + SetDragAmount(x, y, updateScrollbars: false); + mIgnoreCallbacks = false; + } + } + + public virtual void MoveRelative(Vector3 relative) + { + mTrans.localPosition += relative; + Vector2 clipOffset = mPanel.clipOffset; + clipOffset.x -= relative.x; + clipOffset.y -= relative.y; + mPanel.clipOffset = clipOffset; + UpdateScrollbars(recalculateBounds: false); + } + + public void MoveAbsolute(Vector3 absolute) + { + Vector3 a = mTrans.InverseTransformPoint(absolute); + Vector3 b = mTrans.InverseTransformPoint(Vector3.zero); + MoveRelative(a - b); + } + + public void Press(bool pressed) + { + if (UICamera.currentScheme != UICamera.ControlScheme.Controller) + { + if (smoothDragStart && pressed) + { + mDragStarted = false; + mDragStartOffset = Vector2.zero; + } + if (base.enabled && NGUITools.GetActive(base.gameObject)) + { + if (!pressed && mDragID == UICamera.currentTouchID) + { + mDragID = -10; + } + mCalculatedBounds = false; + mShouldMove = shouldMove; + if (mShouldMove) + { + mPressed = pressed; + if (pressed) + { + mMomentum = Vector3.zero; + mScroll = 0f; + DisableSpring(); + mLastPos = UICamera.lastWorldPosition; + mPlane = new Plane(mTrans.rotation * Vector3.back, mLastPos); + Vector2 clipOffset = mPanel.clipOffset; + clipOffset.x = Mathf.Round(clipOffset.x); + clipOffset.y = Mathf.Round(clipOffset.y); + mPanel.clipOffset = clipOffset; + Vector3 localPosition = mTrans.localPosition; + localPosition.x = Mathf.Round(localPosition.x); + localPosition.y = Mathf.Round(localPosition.y); + mTrans.localPosition = localPosition; + if (!smoothDragStart) + { + mDragStarted = true; + mDragStartOffset = Vector2.zero; + if (onDragStarted != null) + { + onDragStarted(); + } + } + } + else + { + if (restrictWithinPanel && mPanel.clipping != 0) + { + RestrictWithinBounds(dragEffect == DragEffect.None, canMoveHorizontally, canMoveVertically); + } + if (mDragStarted && onDragFinished != null) + { + onDragFinished(); + } + if (!mShouldMove && onStoppedMoving != null) + { + onStoppedMoving(); + } + } + } + } + } + } + + public void Drag() + { + if (UICamera.currentScheme != UICamera.ControlScheme.Controller && base.enabled && NGUITools.GetActive(base.gameObject) && mShouldMove) + { + if (mDragID == -10) + { + mDragID = UICamera.currentTouchID; + } + UICamera.currentTouch.clickNotification = UICamera.ClickNotification.BasedOnDelta; + if (smoothDragStart && !mDragStarted) + { + mDragStarted = true; + mDragStartOffset = UICamera.currentTouch.totalDelta; + if (onDragStarted != null) + { + onDragStarted(); + } + } + Ray ray = (!smoothDragStart) ? UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos) : UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos - mDragStartOffset); + float enter = 0f; + if (mPlane.Raycast(ray, out enter)) + { + Vector3 point = ray.GetPoint(enter); + Vector3 vector = point - mLastPos; + mLastPos = point; + if (vector.x != 0f || vector.y != 0f || vector.z != 0f) + { + vector = mTrans.InverseTransformDirection(vector); + if (movement == Movement.Horizontal) + { + vector.y = 0f; + vector.z = 0f; + } + else if (movement == Movement.Vertical) + { + vector.x = 0f; + vector.z = 0f; + } + else if (movement == Movement.Unrestricted) + { + vector.z = 0f; + } + else + { + vector.Scale(customMovement); + } + vector = mTrans.TransformDirection(vector); + } + if (dragEffect == DragEffect.None) + { + mMomentum = Vector3.zero; + } + else + { + mMomentum = Vector3.Lerp(mMomentum, mMomentum + vector * (0.01f * momentumAmount), 0.67f); + } + if (!iOSDragEmulation || dragEffect != DragEffect.MomentumAndSpring) + { + MoveAbsolute(vector); + } + else if (mPanel.CalculateConstrainOffset(bounds.min, bounds.max).magnitude > 1f) + { + MoveAbsolute(vector * 0.5f); + mMomentum *= 0.5f; + } + else + { + MoveAbsolute(vector); + } + if (restrictWithinPanel && mPanel.clipping != 0 && dragEffect != DragEffect.MomentumAndSpring) + { + RestrictWithinBounds(/*instant:*/ true, canMoveHorizontally, canMoveVertically); + } + } + } + } + + public void Scroll(float delta) + { + if (base.enabled && NGUITools.GetActive(base.gameObject) && scrollWheelFactor != 0f) + { + DisableSpring(); + mShouldMove |= shouldMove; + if (Mathf.Sign(mScroll) != Mathf.Sign(delta)) + { + mScroll = 0f; + } + mScroll += delta * scrollWheelFactor; + } + } + + private void LateUpdate() + { + if (Application.isPlaying) + { + float deltaTime = RealTime.deltaTime; + if (showScrollBars != 0 && ((bool)verticalScrollBar || (bool)horizontalScrollBar)) + { + bool flag = false; + bool flag2 = false; + if (showScrollBars != ShowCondition.WhenDragging || mDragID != -10 || mMomentum.magnitude > 0.01f) + { + flag = shouldMoveVertically; + flag2 = shouldMoveHorizontally; + } + if ((bool)verticalScrollBar) + { + float alpha = verticalScrollBar.alpha; + alpha += ((!flag) ? ((0f - deltaTime) * 3f) : (deltaTime * 6f)); + alpha = Mathf.Clamp01(alpha); + if (verticalScrollBar.alpha != alpha) + { + verticalScrollBar.alpha = alpha; + } + } + if ((bool)horizontalScrollBar) + { + float alpha2 = horizontalScrollBar.alpha; + alpha2 += ((!flag2) ? ((0f - deltaTime) * 3f) : (deltaTime * 6f)); + alpha2 = Mathf.Clamp01(alpha2); + if (horizontalScrollBar.alpha != alpha2) + { + horizontalScrollBar.alpha = alpha2; + } + } + } + if (mShouldMove) + { + if (!mPressed) + { + if (mMomentum.magnitude > 0.0001f || mScroll != 0f) + { + if (movement == Movement.Horizontal) + { + mMomentum -= mTrans.TransformDirection(new Vector3(mScroll * 0.05f, 0f, 0f)); + } + else if (movement == Movement.Vertical) + { + mMomentum -= mTrans.TransformDirection(new Vector3(0f, mScroll * 0.05f, 0f)); + } + else if (movement == Movement.Unrestricted) + { + mMomentum -= mTrans.TransformDirection(new Vector3(mScroll * 0.05f, mScroll * 0.05f, 0f)); + } + else + { + mMomentum -= mTrans.TransformDirection(new Vector3(mScroll * customMovement.x * 0.05f, mScroll * customMovement.y * 0.05f, 0f)); + } + mScroll = NGUIMath.SpringLerp(mScroll, 0f, 20f, deltaTime); + Vector3 absolute = NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime); + MoveAbsolute(absolute); + if (restrictWithinPanel && mPanel.clipping != 0) + { + if (NGUITools.GetActive(centerOnChild)) + { + if (centerOnChild.nextPageThreshold != 0f) + { + mMomentum = Vector3.zero; + mScroll = 0f; + } + else + { + centerOnChild.Recenter(); + } + } + else + { + RestrictWithinBounds(/*instant:*/ false, canMoveHorizontally, canMoveVertically); + } + } + if (onMomentumMove != null) + { + onMomentumMove(); + } + } + else + { + mScroll = 0f; + mMomentum = Vector3.zero; + SpringPanel component = GetComponent(); + if (!(component != null) || !component.enabled) + { + mShouldMove = false; + if (onStoppedMoving != null) + { + onStoppedMoving(); + } + } + } + } + else + { + mScroll = 0f; + NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime); + } + } + } + } +} diff --git a/UISlider.cs b/UISlider.cs new file mode 100644 index 00000000..879ccbab --- /dev/null +++ b/UISlider.cs @@ -0,0 +1,196 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/NGUI Slider")] +[ExecuteInEditMode] +public class UISlider : UIProgressBar +{ + private enum Direction + { + Horizontal, + Vertical, + Upgraded + } + + [HideInInspector] + [SerializeField] + private Transform foreground; + + [HideInInspector] + [SerializeField] + private float rawValue = 1f; + + [HideInInspector] + [SerializeField] + private Direction direction = Direction.Upgraded; + + [HideInInspector] + [SerializeField] + protected bool mInverted; + + [Obsolete("Use 'value' instead")] + public float sliderValue + { + get + { + return base.value; + } + set + { + base.value = value; + } + } + + [Obsolete("Use 'fillDirection' instead")] + public bool inverted + { + get + { + return base.isInverted; + } + set + { + } + } + + protected override void Upgrade() + { + if (direction != Direction.Upgraded) + { + mValue = rawValue; + if (foreground != null) + { + mFG = foreground.GetComponent(); + } + if (direction == Direction.Horizontal) + { + mFill = (mInverted ? FillDirection.RightToLeft : FillDirection.LeftToRight); + } + else + { + mFill = ((!mInverted) ? FillDirection.BottomToTop : FillDirection.TopToBottom); + } + direction = Direction.Upgraded; + } + } + + protected override void OnStart() + { + GameObject go = (!(mBG != null) || (!(mBG.GetComponent() != null) && !(mBG.GetComponent() != null))) ? base.gameObject : mBG.gameObject; + UIEventListener uIEventListener = UIEventListener.Get(go); + UIEventListener uIEventListener2 = uIEventListener; + uIEventListener2.onPress = (UIEventListener.BoolDelegate)Delegate.Combine(uIEventListener2.onPress, new UIEventListener.BoolDelegate(OnPressBackground)); + UIEventListener uIEventListener3 = uIEventListener; + uIEventListener3.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener3.onDrag, new UIEventListener.VectorDelegate(OnDragBackground)); + if (thumb != null && (thumb.GetComponent() != null || thumb.GetComponent() != null) && (mFG == null || thumb != mFG.cachedTransform)) + { + UIEventListener uIEventListener4 = UIEventListener.Get(thumb.gameObject); + UIEventListener uIEventListener5 = uIEventListener4; + uIEventListener5.onPress = (UIEventListener.BoolDelegate)Delegate.Combine(uIEventListener5.onPress, new UIEventListener.BoolDelegate(OnPressForeground)); + UIEventListener uIEventListener6 = uIEventListener4; + uIEventListener6.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener6.onDrag, new UIEventListener.VectorDelegate(OnDragForeground)); + } + } + + protected void OnPressBackground(GameObject go, bool isPressed) + { + if (UICamera.currentScheme != UICamera.ControlScheme.Controller) + { + mCam = UICamera.currentCamera; + base.value = ScreenToValue(UICamera.lastTouchPosition); + if (!isPressed && onDragFinished != null) + { + onDragFinished(); + } + } + } + + protected void OnDragBackground(GameObject go, Vector2 delta) + { + if (UICamera.currentScheme != UICamera.ControlScheme.Controller) + { + mCam = UICamera.currentCamera; + base.value = ScreenToValue(UICamera.lastTouchPosition); + } + } + + protected void OnPressForeground(GameObject go, bool isPressed) + { + if (UICamera.currentScheme != UICamera.ControlScheme.Controller) + { + mCam = UICamera.currentCamera; + if (isPressed) + { + mOffset = ((!(mFG == null)) ? (base.value - ScreenToValue(UICamera.lastTouchPosition)) : 0f); + } + else if (onDragFinished != null) + { + onDragFinished(); + } + } + } + + protected void OnDragForeground(GameObject go, Vector2 delta) + { + if (UICamera.currentScheme != UICamera.ControlScheme.Controller) + { + mCam = UICamera.currentCamera; + base.value = mOffset + ScreenToValue(UICamera.lastTouchPosition); + } + } + + protected void OnKey(KeyCode key) + { + if (base.enabled) + { + float num = (!((float)numberOfSteps > 1f)) ? 0.125f : (1f / (float)(numberOfSteps - 1)); + switch (mFill) + { + case FillDirection.LeftToRight: + switch (key) + { + case KeyCode.LeftArrow: + base.value = mValue - num; + break; + case KeyCode.RightArrow: + base.value = mValue + num; + break; + } + break; + case FillDirection.RightToLeft: + switch (key) + { + case KeyCode.LeftArrow: + base.value = mValue + num; + break; + case KeyCode.RightArrow: + base.value = mValue - num; + break; + } + break; + case FillDirection.BottomToTop: + switch (key) + { + case KeyCode.DownArrow: + base.value = mValue - num; + break; + case KeyCode.UpArrow: + base.value = mValue + num; + break; + } + break; + case FillDirection.TopToBottom: + switch (key) + { + case KeyCode.DownArrow: + base.value = mValue + num; + break; + case KeyCode.UpArrow: + base.value = mValue - num; + break; + } + break; + } + } + } +} diff --git a/UISnapshotPoint.cs b/UISnapshotPoint.cs new file mode 100644 index 00000000..08437ee6 --- /dev/null +++ b/UISnapshotPoint.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Internal/Snapshot Point")] +[ExecuteInEditMode] +public class UISnapshotPoint : MonoBehaviour +{ + public bool isOrthographic = true; + + public float nearClip = -100f; + + public float farClip = 100f; + + [Range(10f, 80f)] + public int fieldOfView = 35; + + public float orthoSize = 30f; + + public Texture2D thumbnail; + + private void Start() + { + if (base.tag != "EditorOnly") + { + base.tag = "EditorOnly"; + } + } +} diff --git a/UISoundVolume.cs b/UISoundVolume.cs new file mode 100644 index 00000000..78229960 --- /dev/null +++ b/UISoundVolume.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Sound Volume")] +[RequireComponent(typeof(UISlider))] +public class UISoundVolume : MonoBehaviour +{ + private UISlider mSlider; + + private void Awake() + { + mSlider = GetComponent(); + mSlider.value = NGUITools.soundVolume; + EventDelegate.Add(mSlider.onChange, OnChange); + } + + private void OnChange() + { + NGUITools.soundVolume = UIProgressBar.current.value; + } +} diff --git a/UISprite.cs b/UISprite.cs new file mode 100644 index 00000000..7d894a46 --- /dev/null +++ b/UISprite.cs @@ -0,0 +1,352 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Sprite")] +[ExecuteInEditMode] +public class UISprite : UIBasicSprite +{ + [HideInInspector] + [SerializeField] + private UIAtlas mAtlas; + + [HideInInspector] + [SerializeField] + private string mSpriteName; + + [HideInInspector] + [SerializeField] + private bool mFillCenter = true; + + [NonSerialized] + protected UISpriteData mSprite; + + [NonSerialized] + private bool mSpriteSet; + + public override Material material => (!(mAtlas != null)) ? null : mAtlas.spriteMaterial; + + public UIAtlas atlas + { + get + { + return mAtlas; + } + set + { + if (mAtlas != value) + { + RemoveFromPanel(); + mAtlas = value; + mSpriteSet = false; + mSprite = null; + if (string.IsNullOrEmpty(mSpriteName) && mAtlas != null && mAtlas.spriteList.Count > 0) + { + SetAtlasSprite(mAtlas.spriteList[0]); + mSpriteName = mSprite.name; + } + if (!string.IsNullOrEmpty(mSpriteName)) + { + string spriteName = mSpriteName; + mSpriteName = string.Empty; + this.spriteName = spriteName; + MarkAsChanged(); + } + } + } + } + + public string spriteName + { + get + { + return mSpriteName; + } + set + { + if (string.IsNullOrEmpty(value)) + { + if (!string.IsNullOrEmpty(mSpriteName)) + { + mSpriteName = string.Empty; + mSprite = null; + mChanged = true; + mSpriteSet = false; + } + } + else if (mSpriteName != value) + { + mSpriteName = value; + mSprite = null; + mChanged = true; + mSpriteSet = false; + } + } + } + + public bool isValid => GetAtlasSprite() != null; + + [Obsolete("Use 'centerType' instead")] + public bool fillCenter + { + get + { + return centerType != AdvancedType.Invisible; + } + set + { + if (value != (centerType != AdvancedType.Invisible)) + { + centerType = (value ? AdvancedType.Sliced : AdvancedType.Invisible); + MarkAsChanged(); + } + } + } + + public override Vector4 border + { + get + { + UISpriteData atlasSprite = GetAtlasSprite(); + if (atlasSprite == null) + { + return base.border; + } + return new Vector4((float)atlasSprite.borderLeft, (float)atlasSprite.borderBottom, (float)atlasSprite.borderRight, (float)atlasSprite.borderTop); + } + } + + public override float pixelSize => (!(mAtlas != null)) ? 1f : mAtlas.pixelSize; + + public override int minWidth + { + get + { + if (type == Type.Sliced || type == Type.Advanced) + { + Vector4 vector = border * pixelSize; + int num = Mathf.RoundToInt(vector.x + vector.z); + UISpriteData atlasSprite = GetAtlasSprite(); + if (atlasSprite != null) + { + num += atlasSprite.paddingLeft + atlasSprite.paddingRight; + } + return Mathf.Max(base.minWidth, ((num & 1) != 1) ? num : (num + 1)); + } + return base.minWidth; + } + } + + public override int minHeight + { + get + { + if (type == Type.Sliced || type == Type.Advanced) + { + Vector4 vector = border * pixelSize; + int num = Mathf.RoundToInt(vector.y + vector.w); + UISpriteData atlasSprite = GetAtlasSprite(); + if (atlasSprite != null) + { + num += atlasSprite.paddingTop + atlasSprite.paddingBottom; + } + return Mathf.Max(base.minHeight, ((num & 1) != 1) ? num : (num + 1)); + } + return base.minHeight; + } + } + + public override Vector4 drawingDimensions + { + get + { + Vector2 pivotOffset = base.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float num3 = num + (float)mWidth; + float num4 = num2 + (float)mHeight; + if (GetAtlasSprite() != null && mType != Type.Tiled) + { + int paddingLeft = mSprite.paddingLeft; + int paddingBottom = mSprite.paddingBottom; + int num5 = mSprite.paddingRight; + int num6 = mSprite.paddingTop; + int num7 = mSprite.width + paddingLeft + num5; + int num8 = mSprite.height + paddingBottom + num6; + float num9 = 1f; + float num10 = 1f; + if (num7 > 0 && num8 > 0 && (mType == Type.Simple || mType == Type.Filled)) + { + if ((num7 & 1) != 0) + { + num5++; + } + if ((num8 & 1) != 0) + { + num6++; + } + num9 = 1f / (float)num7 * (float)mWidth; + num10 = 1f / (float)num8 * (float)mHeight; + } + if (mFlip == Flip.Horizontally || mFlip == Flip.Both) + { + num += (float)num5 * num9; + num3 -= (float)paddingLeft * num9; + } + else + { + num += (float)paddingLeft * num9; + num3 -= (float)num5 * num9; + } + if (mFlip == Flip.Vertically || mFlip == Flip.Both) + { + num2 += (float)num6 * num10; + num4 -= (float)paddingBottom * num10; + } + else + { + num2 += (float)paddingBottom * num10; + num4 -= (float)num6 * num10; + } + } + Vector4 vector = (!(mAtlas != null)) ? Vector4.zero : (border * pixelSize); + float num11 = vector.x + vector.z; + float num12 = vector.y + vector.w; + float x = Mathf.Lerp(num, num3 - num11, mDrawRegion.x); + float y = Mathf.Lerp(num2, num4 - num12, mDrawRegion.y); + float z = Mathf.Lerp(num + num11, num3, mDrawRegion.z); + float w = Mathf.Lerp(num2 + num12, num4, mDrawRegion.w); + return new Vector4(x, y, z, w); + } + } + + public override bool premultipliedAlpha => mAtlas != null && mAtlas.premultipliedAlpha; + + public UISpriteData GetAtlasSprite() + { + if (!mSpriteSet) + { + mSprite = null; + } + if (mSprite == null && mAtlas != null) + { + if (!string.IsNullOrEmpty(mSpriteName)) + { + UISpriteData sprite = mAtlas.GetSprite(mSpriteName); + if (sprite == null) + { + return null; + } + SetAtlasSprite(sprite); + } + if (mSprite == null && mAtlas.spriteList.Count > 0) + { + UISpriteData uISpriteData = mAtlas.spriteList[0]; + if (uISpriteData == null) + { + return null; + } + SetAtlasSprite(uISpriteData); + if (mSprite == null) + { + Debug.LogError(mAtlas.name + " seems to have a null sprite!"); + return null; + } + mSpriteName = mSprite.name; + } + } + return mSprite; + } + + protected void SetAtlasSprite(UISpriteData sp) + { + mChanged = true; + mSpriteSet = true; + if (sp != null) + { + mSprite = sp; + mSpriteName = mSprite.name; + } + else + { + mSpriteName = ((mSprite == null) ? string.Empty : mSprite.name); + mSprite = sp; + } + } + + public override void MakePixelPerfect() + { + if (isValid) + { + base.MakePixelPerfect(); + if (mType != Type.Tiled) + { + UISpriteData atlasSprite = GetAtlasSprite(); + if (atlasSprite != null) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null) && (mType == Type.Simple || mType == Type.Filled || !atlasSprite.hasBorder) && mainTexture != null) + { + int num = Mathf.RoundToInt(pixelSize * (float)(atlasSprite.width + atlasSprite.paddingLeft + atlasSprite.paddingRight)); + int num2 = Mathf.RoundToInt(pixelSize * (float)(atlasSprite.height + atlasSprite.paddingTop + atlasSprite.paddingBottom)); + if ((num & 1) == 1) + { + num++; + } + if ((num2 & 1) == 1) + { + num2++; + } + base.width = num; + base.height = num2; + } + } + } + } + } + + protected override void OnInit() + { + if (!mFillCenter) + { + mFillCenter = true; + centerType = AdvancedType.Invisible; + } + base.OnInit(); + } + + protected override void OnUpdate() + { + base.OnUpdate(); + if (mChanged || !mSpriteSet) + { + mSpriteSet = true; + mSprite = null; + mChanged = true; + } + } + + public override void OnFill(BetterList verts, BetterList uvs, BetterList cols) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null)) + { + if (mSprite == null) + { + mSprite = atlas.GetSprite(spriteName); + } + if (mSprite != null) + { + Rect rect = new Rect((float)mSprite.x, (float)mSprite.y, (float)mSprite.width, (float)mSprite.height); + Rect rect2 = new Rect((float)(mSprite.x + mSprite.borderLeft), (float)(mSprite.y + mSprite.borderTop), (float)(mSprite.width - mSprite.borderLeft - mSprite.borderRight), (float)(mSprite.height - mSprite.borderBottom - mSprite.borderTop)); + rect = NGUIMath.ConvertToTexCoords(rect, mainTexture.width, mainTexture.height); + rect2 = NGUIMath.ConvertToTexCoords(rect2, mainTexture.width, mainTexture.height); + int size = verts.size; + Fill(verts, uvs, cols, rect, rect2); + if (onPostFill != null) + { + onPostFill(this, size, verts, uvs, cols); + } + } + } + } +} diff --git a/UISpriteAnimation.cs b/UISpriteAnimation.cs new file mode 100644 index 00000000..5aa8296d --- /dev/null +++ b/UISpriteAnimation.cs @@ -0,0 +1,156 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Sprite Animation")] +[ExecuteInEditMode] +[RequireComponent(typeof(UISprite))] +public class UISpriteAnimation : MonoBehaviour +{ + [HideInInspector] + [SerializeField] + protected int mFPS = 30; + + [HideInInspector] + [SerializeField] + protected string mPrefix = string.Empty; + + [HideInInspector] + [SerializeField] + protected bool mLoop = true; + + [HideInInspector] + [SerializeField] + protected bool mSnap = true; + + protected UISprite mSprite; + + protected float mDelta; + + protected int mIndex; + + protected bool mActive = true; + + protected List mSpriteNames = new List(); + + public int frames => mSpriteNames.Count; + + public int framesPerSecond + { + get + { + return mFPS; + } + set + { + mFPS = value; + } + } + + public string namePrefix + { + get + { + return mPrefix; + } + set + { + if (mPrefix != value) + { + mPrefix = value; + RebuildSpriteList(); + } + } + } + + public bool loop + { + get + { + return mLoop; + } + set + { + mLoop = value; + } + } + + public bool isPlaying => mActive; + + protected virtual void Start() + { + RebuildSpriteList(); + } + + protected virtual void Update() + { + if (mActive && mSpriteNames.Count > 1 && Application.isPlaying && mFPS > 0) + { + mDelta += RealTime.deltaTime; + float num = 1f / (float)mFPS; + if (num < mDelta) + { + mDelta = ((!(num > 0f)) ? 0f : (mDelta - num)); + if (++mIndex >= mSpriteNames.Count) + { + mIndex = 0; + mActive = mLoop; + } + if (mActive) + { + mSprite.spriteName = mSpriteNames[mIndex]; + if (mSnap) + { + mSprite.MakePixelPerfect(); + } + } + } + } + } + + public void RebuildSpriteList() + { + if (mSprite == null) + { + mSprite = GetComponent(); + } + mSpriteNames.Clear(); + if (mSprite != null && mSprite.atlas != null) + { + List spriteList = mSprite.atlas.spriteList; + int i = 0; + for (int count = spriteList.Count; i < count; i++) + { + UISpriteData uISpriteData = spriteList[i]; + if (string.IsNullOrEmpty(mPrefix) || uISpriteData.name.StartsWith(mPrefix)) + { + mSpriteNames.Add(uISpriteData.name); + } + } + mSpriteNames.Sort(); + } + } + + public void Play() + { + mActive = true; + } + + public void Pause() + { + mActive = false; + } + + public void ResetToBeginning() + { + mActive = true; + mIndex = 0; + if (mSprite != null && mSpriteNames.Count > 0) + { + mSprite.spriteName = mSpriteNames[mIndex]; + if (mSnap) + { + mSprite.MakePixelPerfect(); + } + } + } +} diff --git a/UISpriteData.cs b/UISpriteData.cs new file mode 100644 index 00000000..a092c382 --- /dev/null +++ b/UISpriteData.cs @@ -0,0 +1,84 @@ +using System; + +[Serializable] +public class UISpriteData +{ + public string name = "Sprite"; + + public int x; + + public int y; + + public int width; + + public int height; + + public int borderLeft; + + public int borderRight; + + public int borderTop; + + public int borderBottom; + + public int paddingLeft; + + public int paddingRight; + + public int paddingTop; + + public int paddingBottom; + + public bool hasBorder => (borderLeft | borderRight | borderTop | borderBottom) != 0; + + public bool hasPadding => (paddingLeft | paddingRight | paddingTop | paddingBottom) != 0; + + public void SetRect(int x, int y, int width, int height) + { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + public void SetPadding(int left, int bottom, int right, int top) + { + paddingLeft = left; + paddingBottom = bottom; + paddingRight = right; + paddingTop = top; + } + + public void SetBorder(int left, int bottom, int right, int top) + { + borderLeft = left; + borderBottom = bottom; + borderRight = right; + borderTop = top; + } + + public void CopyFrom(UISpriteData sd) + { + name = sd.name; + x = sd.x; + y = sd.y; + width = sd.width; + height = sd.height; + borderLeft = sd.borderLeft; + borderRight = sd.borderRight; + borderTop = sd.borderTop; + borderBottom = sd.borderBottom; + paddingLeft = sd.paddingLeft; + paddingRight = sd.paddingRight; + paddingTop = sd.paddingTop; + paddingBottom = sd.paddingBottom; + } + + public void CopyBorderFrom(UISpriteData sd) + { + borderLeft = sd.borderLeft; + borderRight = sd.borderRight; + borderTop = sd.borderTop; + borderBottom = sd.borderBottom; + } +} diff --git a/UIStretch.cs b/UIStretch.cs new file mode 100644 index 00000000..c5e25cc1 --- /dev/null +++ b/UIStretch.cs @@ -0,0 +1,285 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Stretch")] +[ExecuteInEditMode] +public class UIStretch : MonoBehaviour +{ + public enum Style + { + None, + Horizontal, + Vertical, + Both, + BasedOnHeight, + FillKeepingRatio, + FitInternalKeepingRatio + } + + public Camera uiCamera; + + public GameObject container; + + public Style style; + + public bool runOnlyOnce = true; + + public Vector2 relativeSize = Vector2.one; + + public Vector2 initialSize = Vector2.one; + + public Vector2 borderPadding = Vector2.zero; + + [HideInInspector] + [SerializeField] + private UIWidget widgetContainer; + + private Transform mTrans; + + private UIWidget mWidget; + + private UISprite mSprite; + + private UIPanel mPanel; + + private UIRoot mRoot; + + private Animation mAnim; + + private Rect mRect; + + private bool mStarted; + + private void Awake() + { + mAnim = GetComponent(); + mRect = default(Rect); + mTrans = base.transform; + mWidget = GetComponent(); + mSprite = GetComponent(); + mPanel = GetComponent(); + UICamera.onScreenResize = (UICamera.OnScreenResize)Delegate.Combine(UICamera.onScreenResize, new UICamera.OnScreenResize(ScreenSizeChanged)); + } + + private void OnDestroy() + { + UICamera.onScreenResize = (UICamera.OnScreenResize)Delegate.Remove(UICamera.onScreenResize, new UICamera.OnScreenResize(ScreenSizeChanged)); + } + + private void ScreenSizeChanged() + { + if (mStarted && runOnlyOnce) + { + Update(); + } + } + + private void Start() + { + if (container == null && widgetContainer != null) + { + container = widgetContainer.gameObject; + widgetContainer = null; + } + if (uiCamera == null) + { + uiCamera = NGUITools.FindCameraForLayer(base.gameObject.layer); + } + mRoot = NGUITools.FindInParents(base.gameObject); + Update(); + mStarted = true; + } + + private void Update() + { + if ((!(mAnim != null) || !mAnim.isPlaying) && style != 0) + { + UIWidget uIWidget = (!(container == null)) ? container.GetComponent() : null; + UIPanel uIPanel = (!(container == null) || !(uIWidget == null)) ? container.GetComponent() : null; + float num = 1f; + if (uIWidget != null) + { + Bounds bounds = uIWidget.CalculateBounds(base.transform.parent); + ref Rect reference = ref mRect; + Vector3 min = bounds.min; + reference.x = min.x; + ref Rect reference2 = ref mRect; + Vector3 min2 = bounds.min; + reference2.y = min2.y; + ref Rect reference3 = ref mRect; + Vector3 size = bounds.size; + reference3.width = size.x; + ref Rect reference4 = ref mRect; + Vector3 size2 = bounds.size; + reference4.height = size2.y; + } + else if (uIPanel != null) + { + if (uIPanel.clipping == UIDrawCall.Clipping.None) + { + float num2 = (!(mRoot != null)) ? 0.5f : ((float)mRoot.activeHeight / (float)Screen.height * 0.5f); + mRect.xMin = (float)(-Screen.width) * num2; + mRect.yMin = (float)(-Screen.height) * num2; + mRect.xMax = 0f - mRect.xMin; + mRect.yMax = 0f - mRect.yMin; + } + else + { + Vector4 finalClipRegion = uIPanel.finalClipRegion; + mRect.x = finalClipRegion.x - finalClipRegion.z * 0.5f; + mRect.y = finalClipRegion.y - finalClipRegion.w * 0.5f; + mRect.width = finalClipRegion.z; + mRect.height = finalClipRegion.w; + } + } + else if (container != null) + { + Transform parent = base.transform.parent; + Bounds bounds2 = (!(parent != null)) ? NGUIMath.CalculateRelativeWidgetBounds(container.transform) : NGUIMath.CalculateRelativeWidgetBounds(parent, container.transform); + ref Rect reference5 = ref mRect; + Vector3 min3 = bounds2.min; + reference5.x = min3.x; + ref Rect reference6 = ref mRect; + Vector3 min4 = bounds2.min; + reference6.y = min4.y; + ref Rect reference7 = ref mRect; + Vector3 size3 = bounds2.size; + reference7.width = size3.x; + ref Rect reference8 = ref mRect; + Vector3 size4 = bounds2.size; + reference8.height = size4.y; + } + else + { + if (!(uiCamera != null)) + { + return; + } + mRect = uiCamera.pixelRect; + if (mRoot != null) + { + num = mRoot.pixelSizeAdjustment; + } + } + float num3 = mRect.width; + float num4 = mRect.height; + if (num != 1f && num4 > 1f) + { + float num5 = (float)mRoot.activeHeight / num4; + num3 *= num5; + num4 *= num5; + } + Vector3 vector = (!(mWidget != null)) ? mTrans.localScale : new Vector3((float)mWidget.width, (float)mWidget.height); + if (style == Style.BasedOnHeight) + { + vector.x = relativeSize.x * num4; + vector.y = relativeSize.y * num4; + } + else if (style == Style.FillKeepingRatio) + { + float num6 = num3 / num4; + float num7 = initialSize.x / initialSize.y; + if (num7 < num6) + { + float num8 = num3 / initialSize.x; + vector.x = num3; + vector.y = initialSize.y * num8; + } + else + { + float num9 = num4 / initialSize.y; + vector.x = initialSize.x * num9; + vector.y = num4; + } + } + else if (style == Style.FitInternalKeepingRatio) + { + float num10 = num3 / num4; + float num11 = initialSize.x / initialSize.y; + if (num11 > num10) + { + float num12 = num3 / initialSize.x; + vector.x = num3; + vector.y = initialSize.y * num12; + } + else + { + float num13 = num4 / initialSize.y; + vector.x = initialSize.x * num13; + vector.y = num4; + } + } + else + { + if (style != Style.Vertical) + { + vector.x = relativeSize.x * num3; + } + if (style != Style.Horizontal) + { + vector.y = relativeSize.y * num4; + } + } + if (mSprite != null) + { + float num14 = (!(mSprite.atlas != null)) ? 1f : mSprite.atlas.pixelSize; + vector.x -= borderPadding.x * num14; + vector.y -= borderPadding.y * num14; + if (style != Style.Vertical) + { + mSprite.width = Mathf.RoundToInt(vector.x); + } + if (style != Style.Horizontal) + { + mSprite.height = Mathf.RoundToInt(vector.y); + } + vector = Vector3.one; + } + else if (mWidget != null) + { + if (style != Style.Vertical) + { + mWidget.width = Mathf.RoundToInt(vector.x - borderPadding.x); + } + if (style != Style.Horizontal) + { + mWidget.height = Mathf.RoundToInt(vector.y - borderPadding.y); + } + vector = Vector3.one; + } + else if (mPanel != null) + { + Vector4 baseClipRegion = mPanel.baseClipRegion; + if (style != Style.Vertical) + { + baseClipRegion.z = vector.x - borderPadding.x; + } + if (style != Style.Horizontal) + { + baseClipRegion.w = vector.y - borderPadding.y; + } + mPanel.baseClipRegion = baseClipRegion; + vector = Vector3.one; + } + else + { + if (style != Style.Vertical) + { + vector.x -= borderPadding.x; + } + if (style != Style.Horizontal) + { + vector.y -= borderPadding.y; + } + } + if (mTrans.localScale != vector) + { + mTrans.localScale = vector; + } + if (runOnlyOnce && Application.isPlaying) + { + base.enabled = false; + } + } + } +} diff --git a/UITable.cs b/UITable.cs new file mode 100644 index 00000000..b9446e03 --- /dev/null +++ b/UITable.cs @@ -0,0 +1,294 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Table")] +public class UITable : UIWidgetContainer +{ + public enum Direction + { + Down, + Up + } + + public enum Sorting + { + None, + Alphabetic, + Horizontal, + Vertical, + Custom + } + + public delegate void OnReposition(); + + public int columns; + + public Direction direction; + + public Sorting sorting; + + public UIWidget.Pivot pivot; + + public UIWidget.Pivot cellAlignment; + + public bool hideInactive = true; + + public bool keepWithinPanel; + + public Vector2 padding = Vector2.zero; + + public OnReposition onReposition; + + public Comparison onCustomSort; + + protected UIPanel mPanel; + + protected bool mInitDone; + + protected bool mReposition; + + public bool repositionNow + { + set + { + if (value) + { + mReposition = true; + base.enabled = true; + } + } + } + + public List GetChildList() + { + Transform transform = base.transform; + List list = new List(); + for (int i = 0; i < transform.childCount; i++) + { + Transform child = transform.GetChild(i); + if (!hideInactive || ((bool)child && NGUITools.GetActive(child.gameObject))) + { + list.Add(child); + } + } + if (sorting != 0) + { + if (sorting == Sorting.Alphabetic) + { + list.Sort(UIGrid.SortByName); + } + else if (sorting == Sorting.Horizontal) + { + list.Sort(UIGrid.SortHorizontal); + } + else if (sorting == Sorting.Vertical) + { + list.Sort(UIGrid.SortVertical); + } + else if (onCustomSort != null) + { + list.Sort(onCustomSort); + } + else + { + Sort(list); + } + } + return list; + } + + protected virtual void Sort(List list) + { + list.Sort(UIGrid.SortByName); + } + + protected virtual void Start() + { + Init(); + Reposition(); + base.enabled = false; + } + + protected virtual void Init() + { + mInitDone = true; + mPanel = NGUITools.FindInParents(base.gameObject); + } + + protected virtual void LateUpdate() + { + if (mReposition) + { + Reposition(); + } + base.enabled = false; + } + + private void OnValidate() + { + if (!Application.isPlaying && NGUITools.GetActive(this)) + { + Reposition(); + } + } + + protected void RepositionVariableSize(List children) + { + float num = 0f; + float num2 = 0f; + int num3 = (columns <= 0) ? 1 : (children.Count / columns + 1); + int num4 = (columns <= 0) ? children.Count : columns; + Bounds[,] array = new Bounds[num3, num4]; + Bounds[] array2 = new Bounds[num4]; + Bounds[] array3 = new Bounds[num3]; + int num5 = 0; + int num6 = 0; + int i = 0; + for (int count = children.Count; i < count; i++) + { + Transform transform = children[i]; + Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(transform, !hideInactive); + Vector3 localScale = transform.localScale; + bounds.min = Vector3.Scale(bounds.min, localScale); + bounds.max = Vector3.Scale(bounds.max, localScale); + array[num6, num5] = bounds; + array2[num5].Encapsulate(bounds); + array3[num6].Encapsulate(bounds); + if (++num5 >= columns && columns > 0) + { + num5 = 0; + num6++; + } + } + num5 = 0; + num6 = 0; + Vector2 pivotOffset = NGUIMath.GetPivotOffset(cellAlignment); + int j = 0; + for (int count2 = children.Count; j < count2; j++) + { + Transform transform2 = children[j]; + Bounds bounds2 = array[num6, num5]; + Bounds bounds3 = array2[num5]; + Bounds bounds4 = array3[num6]; + Vector3 localPosition = transform2.localPosition; + float num7 = num; + Vector3 extents = bounds2.extents; + float num8 = num7 + extents.x; + Vector3 center = bounds2.center; + localPosition.x = num8 - center.x; + float x = localPosition.x; + Vector3 max = bounds2.max; + float x2 = max.x; + Vector3 min = bounds2.min; + float num9 = x2 - min.x; + Vector3 max2 = bounds3.max; + float num10 = num9 - max2.x; + Vector3 min2 = bounds3.min; + localPosition.x = x - (Mathf.Lerp(0f, num10 + min2.x, pivotOffset.x) - padding.x); + if (direction == Direction.Down) + { + float num11 = 0f - num2; + Vector3 extents2 = bounds2.extents; + float num12 = num11 - extents2.y; + Vector3 center2 = bounds2.center; + localPosition.y = num12 - center2.y; + float y = localPosition.y; + Vector3 max3 = bounds2.max; + float y2 = max3.y; + Vector3 min3 = bounds2.min; + float num13 = y2 - min3.y; + Vector3 max4 = bounds4.max; + float num14 = num13 - max4.y; + Vector3 min4 = bounds4.min; + localPosition.y = y + (Mathf.Lerp(num14 + min4.y, 0f, pivotOffset.y) - padding.y); + } + else + { + float num15 = num2; + Vector3 extents3 = bounds2.extents; + float num16 = num15 + extents3.y; + Vector3 center3 = bounds2.center; + localPosition.y = num16 - center3.y; + float y3 = localPosition.y; + Vector3 max5 = bounds2.max; + float y4 = max5.y; + Vector3 min5 = bounds2.min; + float num17 = y4 - min5.y; + Vector3 max6 = bounds4.max; + float num18 = num17 - max6.y; + Vector3 min6 = bounds4.min; + localPosition.y = y3 - (Mathf.Lerp(0f, num18 + min6.y, pivotOffset.y) - padding.y); + } + float num19 = num; + Vector3 size = bounds3.size; + num = num19 + (size.x + padding.x * 2f); + transform2.localPosition = localPosition; + if (++num5 >= columns && columns > 0) + { + num5 = 0; + num6++; + num = 0f; + float num20 = num2; + Vector3 size2 = bounds4.size; + num2 = num20 + (size2.y + padding.y * 2f); + } + } + if (pivot != 0) + { + pivotOffset = NGUIMath.GetPivotOffset(pivot); + Bounds bounds5 = NGUIMath.CalculateRelativeWidgetBounds(base.transform); + Vector3 size3 = bounds5.size; + float num21 = Mathf.Lerp(0f, size3.x, pivotOffset.x); + Vector3 size4 = bounds5.size; + float num22 = Mathf.Lerp(0f - size4.y, 0f, pivotOffset.y); + Transform transform3 = base.transform; + for (int k = 0; k < transform3.childCount; k++) + { + Transform child = transform3.GetChild(k); + SpringPosition component = child.GetComponent(); + if (component != null) + { + component.target.x -= num21; + component.target.y -= num22; + } + else + { + Vector3 localPosition2 = child.localPosition; + localPosition2.x -= num21; + localPosition2.y -= num22; + child.localPosition = localPosition2; + } + } + } + } + + [ContextMenu("Execute")] + public virtual void Reposition() + { + if (Application.isPlaying && !mInitDone && NGUITools.GetActive(this)) + { + Init(); + } + mReposition = false; + Transform transform = base.transform; + List childList = GetChildList(); + if (childList.Count > 0) + { + RepositionVariableSize(childList); + } + if (keepWithinPanel && mPanel != null) + { + mPanel.ConstrainTargetToBounds(transform, immediate: true); + UIScrollView component = mPanel.GetComponent(); + if (component != null) + { + component.UpdateScrollbars(recalculateBounds: true); + } + } + if (onReposition != null) + { + onReposition(); + } + } +} diff --git a/UITextList.cs b/UITextList.cs new file mode 100644 index 00000000..467a7ba0 --- /dev/null +++ b/UITextList.cs @@ -0,0 +1,252 @@ +using System.Text; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Text List")] +public class UITextList : MonoBehaviour +{ + public enum Style + { + Text, + Chat + } + + protected class Paragraph + { + public string text; + + public string[] lines; + } + + public UILabel textLabel; + + public UIProgressBar scrollBar; + + public Style style; + + public int paragraphHistory = 50; + + protected char[] mSeparator = new char[1] + { + '\n' + }; + + protected BetterList mParagraphs = new BetterList(); + + protected float mScroll; + + protected int mTotalLines; + + protected int mLastWidth; + + protected int mLastHeight; + + public bool isValid => textLabel != null && textLabel.ambigiousFont != null; + + public float scrollValue + { + get + { + return mScroll; + } + set + { + value = Mathf.Clamp01(value); + if (isValid && mScroll != value) + { + if (scrollBar != null) + { + scrollBar.value = value; + } + else + { + mScroll = value; + UpdateVisibleText(); + } + } + } + } + + protected float lineHeight => (!(textLabel != null)) ? 20f : ((float)(textLabel.fontSize + textLabel.spacingY)); + + protected int scrollHeight + { + get + { + if (!isValid) + { + return 0; + } + int num = Mathf.FloorToInt((float)textLabel.height / lineHeight); + return Mathf.Max(0, mTotalLines - num); + } + } + + public void Clear() + { + mParagraphs.Clear(); + UpdateVisibleText(); + } + + private void Start() + { + if (textLabel == null) + { + textLabel = GetComponentInChildren(); + } + if (scrollBar != null) + { + EventDelegate.Add(scrollBar.onChange, OnScrollBar); + } + textLabel.overflowMethod = UILabel.Overflow.ClampContent; + if (style == Style.Chat) + { + textLabel.pivot = UIWidget.Pivot.BottomLeft; + scrollValue = 1f; + } + else + { + textLabel.pivot = UIWidget.Pivot.TopLeft; + scrollValue = 0f; + } + } + + private void Update() + { + if (isValid && (textLabel.width != mLastWidth || textLabel.height != mLastHeight)) + { + mLastWidth = textLabel.width; + mLastHeight = textLabel.height; + Rebuild(); + } + } + + public void OnScroll(float val) + { + int scrollHeight = this.scrollHeight; + if (scrollHeight != 0) + { + val *= lineHeight; + scrollValue = mScroll - val / (float)scrollHeight; + } + } + + public void OnDrag(Vector2 delta) + { + int scrollHeight = this.scrollHeight; + if (scrollHeight != 0) + { + float num = delta.y / lineHeight; + scrollValue = mScroll + num / (float)scrollHeight; + } + } + + private void OnScrollBar() + { + mScroll = UIProgressBar.current.value; + UpdateVisibleText(); + } + + public void Add(string text) + { + Add(text, updateVisible: true); + } + + protected void Add(string text, bool updateVisible) + { + Paragraph paragraph = null; + if (mParagraphs.size < paragraphHistory) + { + paragraph = new Paragraph(); + } + else + { + paragraph = mParagraphs[0]; + mParagraphs.RemoveAt(0); + } + paragraph.text = text; + mParagraphs.Add(paragraph); + Rebuild(); + } + + protected void Rebuild() + { + if (isValid) + { + textLabel.UpdateNGUIText(); + NGUIText.rectHeight = 1000000; + mTotalLines = 0; + for (int i = 0; i < mParagraphs.size; i++) + { + Paragraph paragraph = mParagraphs.buffer[i]; + NGUIText.WrapText(paragraph.text, out string finalText); + paragraph.lines = finalText.Split('\n'); + mTotalLines += paragraph.lines.Length; + } + mTotalLines = 0; + int j = 0; + for (int size = mParagraphs.size; j < size; j++) + { + mTotalLines += mParagraphs.buffer[j].lines.Length; + } + if (scrollBar != null) + { + UIScrollBar uIScrollBar = scrollBar as UIScrollBar; + if (uIScrollBar != null) + { + uIScrollBar.barSize = ((mTotalLines != 0) ? (1f - (float)scrollHeight / (float)mTotalLines) : 1f); + } + } + UpdateVisibleText(); + } + } + + protected void UpdateVisibleText() + { + if (isValid) + { + if (mTotalLines == 0) + { + textLabel.text = string.Empty; + } + else + { + int num = Mathf.FloorToInt((float)textLabel.height / lineHeight); + int num2 = Mathf.Max(0, mTotalLines - num); + int num3 = Mathf.RoundToInt(mScroll * (float)num2); + if (num3 < 0) + { + num3 = 0; + } + StringBuilder stringBuilder = new StringBuilder(); + int num4 = 0; + int size = mParagraphs.size; + while (num > 0 && num4 < size) + { + Paragraph paragraph = mParagraphs.buffer[num4]; + int num5 = 0; + int num6 = paragraph.lines.Length; + while (num > 0 && num5 < num6) + { + string value = paragraph.lines[num5]; + if (num3 > 0) + { + num3--; + } + else + { + if (stringBuilder.Length > 0) + { + stringBuilder.Append("\n"); + } + stringBuilder.Append(value); + num--; + } + num5++; + } + num4++; + } + textLabel.text = stringBuilder.ToString(); + } + } + } +} diff --git a/UITexture.cs b/UITexture.cs new file mode 100644 index 00000000..7f2de3d9 --- /dev/null +++ b/UITexture.cs @@ -0,0 +1,343 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Texture")] +[ExecuteInEditMode] +public class UITexture : UIBasicSprite +{ + [HideInInspector] + [SerializeField] + private Rect mRect = new Rect(0f, 0f, 1f, 1f); + + [HideInInspector] + [SerializeField] + private Texture mTexture; + + [HideInInspector] + [SerializeField] + private Material mMat; + + [HideInInspector] + [SerializeField] + private Shader mShader; + + [HideInInspector] + [SerializeField] + private Vector4 mBorder = Vector4.zero; + + [HideInInspector] + [SerializeField] + private bool mFixedAspect; + + [NonSerialized] + private int mPMA = -1; + + public override Texture mainTexture + { + get + { + if (mTexture != null) + { + return mTexture; + } + if (mMat != null) + { + return mMat.mainTexture; + } + return null; + } + set + { + if (mTexture != value) + { + if (drawCall != null && drawCall.widgetCount == 1 && mMat == null) + { + mTexture = value; + drawCall.mainTexture = value; + } + else + { + RemoveFromPanel(); + mTexture = value; + mPMA = -1; + MarkAsChanged(); + } + } + } + } + + public override Material material + { + get + { + return mMat; + } + set + { + if (mMat != value) + { + RemoveFromPanel(); + mShader = null; + mMat = value; + mPMA = -1; + MarkAsChanged(); + } + } + } + + public override Shader shader + { + get + { + if (mMat != null) + { + return mMat.shader; + } + if (mShader == null) + { + mShader = Shader.Find("Unlit/Transparent Colored"); + } + return mShader; + } + set + { + if (mShader != value) + { + if (drawCall != null && drawCall.widgetCount == 1 && mMat == null) + { + mShader = value; + drawCall.shader = value; + } + else + { + RemoveFromPanel(); + mShader = value; + mPMA = -1; + mMat = null; + MarkAsChanged(); + } + } + } + } + + public override bool premultipliedAlpha + { + get + { + if (mPMA == -1) + { + Material material = this.material; + mPMA = ((material != null && material.shader != null && material.shader.name.Contains("Premultiplied")) ? 1 : 0); + } + return mPMA == 1; + } + } + + public override Vector4 border + { + get + { + return mBorder; + } + set + { + if (mBorder != value) + { + mBorder = value; + MarkAsChanged(); + } + } + } + + public Rect uvRect + { + get + { + return mRect; + } + set + { + if (mRect != value) + { + mRect = value; + MarkAsChanged(); + } + } + } + + public override Vector4 drawingDimensions + { + get + { + Vector2 pivotOffset = base.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float num3 = num + (float)mWidth; + float num4 = num2 + (float)mHeight; + if (mTexture != null && mType != Type.Tiled) + { + int width = mTexture.width; + int height = mTexture.height; + int num5 = 0; + int num6 = 0; + float num7 = 1f; + float num8 = 1f; + if (width > 0 && height > 0 && (mType == Type.Simple || mType == Type.Filled)) + { + if ((width & 1) != 0) + { + num5++; + } + if ((height & 1) != 0) + { + num6++; + } + num7 = 1f / (float)width * (float)mWidth; + num8 = 1f / (float)height * (float)mHeight; + } + if (mFlip == Flip.Horizontally || mFlip == Flip.Both) + { + num += (float)num5 * num7; + } + else + { + num3 -= (float)num5 * num7; + } + if (mFlip == Flip.Vertically || mFlip == Flip.Both) + { + num2 += (float)num6 * num8; + } + else + { + num4 -= (float)num6 * num8; + } + } + float num9; + float num10; + if (mFixedAspect) + { + num9 = 0f; + num10 = 0f; + } + else + { + Vector4 border = this.border; + num9 = border.x + border.z; + num10 = border.y + border.w; + } + float x = Mathf.Lerp(num, num3 - num9, mDrawRegion.x); + float y = Mathf.Lerp(num2, num4 - num10, mDrawRegion.y); + float z = Mathf.Lerp(num + num9, num3, mDrawRegion.z); + float w = Mathf.Lerp(num2 + num10, num4, mDrawRegion.w); + return new Vector4(x, y, z, w); + } + } + + public bool fixedAspect + { + get + { + return mFixedAspect; + } + set + { + if (mFixedAspect != value) + { + mFixedAspect = value; + mDrawRegion = new Vector4(0f, 0f, 1f, 1f); + MarkAsChanged(); + } + } + } + + public override void MakePixelPerfect() + { + base.MakePixelPerfect(); + if (mType != Type.Tiled) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null) && (mType == Type.Simple || mType == Type.Filled || !base.hasBorder) && mainTexture != null) + { + int num = mainTexture.width; + int num2 = mainTexture.height; + if ((num & 1) == 1) + { + num++; + } + if ((num2 & 1) == 1) + { + num2++; + } + base.width = num; + base.height = num2; + } + } + } + + protected override void OnUpdate() + { + base.OnUpdate(); + if (mFixedAspect) + { + Texture mainTexture = this.mainTexture; + if (mainTexture != null) + { + int num = mainTexture.width; + int num2 = mainTexture.height; + if ((num & 1) == 1) + { + num++; + } + if ((num2 & 1) == 1) + { + num2++; + } + float num3 = (float)mWidth; + float num4 = (float)mHeight; + float num5 = num3 / num4; + float num6 = (float)num / (float)num2; + if (num6 < num5) + { + float num7 = (num3 - num4 * num6) / num3 * 0.5f; + base.drawRegion = new Vector4(num7, 0f, 1f - num7, 1f); + } + else + { + float num8 = (num4 - num3 / num6) / num4 * 0.5f; + base.drawRegion = new Vector4(0f, num8, 1f, 1f - num8); + } + } + } + } + + public override void OnFill(BetterList verts, BetterList uvs, BetterList cols) + { + Texture mainTexture = this.mainTexture; + if (!(mainTexture == null)) + { + Rect rect = new Rect(mRect.x * (float)mainTexture.width, mRect.y * (float)mainTexture.height, (float)mainTexture.width * mRect.width, (float)mainTexture.height * mRect.height); + Rect inner = rect; + Vector4 border = this.border; + inner.xMin += border.x; + inner.yMin += border.y; + inner.xMax -= border.z; + inner.yMax -= border.w; + float num = 1f / (float)mainTexture.width; + float num2 = 1f / (float)mainTexture.height; + rect.xMin *= num; + rect.xMax *= num; + rect.yMin *= num2; + rect.yMax *= num2; + inner.xMin *= num; + inner.xMax *= num; + inner.yMin *= num2; + inner.yMax *= num2; + int size = verts.size; + Fill(verts, uvs, cols, rect, inner); + if (onPostFill != null) + { + onPostFill(this, size, verts, uvs, cols); + } + } + } +} diff --git a/UIToggle.cs b/UIToggle.cs new file mode 100644 index 00000000..3f0f90a9 --- /dev/null +++ b/UIToggle.cs @@ -0,0 +1,226 @@ +using AnimationOrTween; +using System; +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Toggle")] +[ExecuteInEditMode] +public class UIToggle : UIWidgetContainer +{ + public static BetterList list = new BetterList(); + + public static UIToggle current; + + public int group; + + public UIWidget activeSprite; + + public Animation activeAnimation; + + public bool startsActive; + + public bool instantTween; + + public bool optionCanBeNone; + + public List onChange = new List(); + + [HideInInspector] + [SerializeField] + private UISprite checkSprite; + + [HideInInspector] + [SerializeField] + private Animation checkAnimation; + + [HideInInspector] + [SerializeField] + private GameObject eventReceiver; + + [HideInInspector] + [SerializeField] + private string functionName = "OnActivate"; + + [HideInInspector] + [SerializeField] + private bool startsChecked; + + private bool mIsActive = true; + + private bool mStarted; + + public bool value + { + get + { + return (!mStarted) ? startsActive : mIsActive; + } + set + { + if (!mStarted) + { + startsActive = value; + } + else if (group == 0 || value || optionCanBeNone || !mStarted) + { + Set(value); + } + } + } + + [Obsolete("Use 'value' instead")] + public bool isChecked + { + get + { + return value; + } + set + { + this.value = value; + } + } + + public static UIToggle GetActiveToggle(int group) + { + for (int i = 0; i < list.size; i++) + { + UIToggle uIToggle = list[i]; + if (uIToggle != null && uIToggle.group == group && uIToggle.mIsActive) + { + return uIToggle; + } + } + return null; + } + + private void OnEnable() + { + list.Add(this); + } + + private void OnDisable() + { + list.Remove(this); + } + + private void Start() + { + if (startsChecked) + { + startsChecked = false; + startsActive = true; + } + if (!Application.isPlaying) + { + if (checkSprite != null && activeSprite == null) + { + activeSprite = checkSprite; + checkSprite = null; + } + if (checkAnimation != null && activeAnimation == null) + { + activeAnimation = checkAnimation; + checkAnimation = null; + } + if (Application.isPlaying && activeSprite != null) + { + activeSprite.alpha = ((!startsActive) ? 0f : 1f); + } + if (EventDelegate.IsValid(onChange)) + { + eventReceiver = null; + functionName = null; + } + } + else + { + mIsActive = !startsActive; + mStarted = true; + bool flag = instantTween; + instantTween = true; + Set(startsActive); + instantTween = flag; + } + } + + private void OnClick() + { + if (base.enabled) + { + value = !value; + } + } + + private void Set(bool state) + { + if (!mStarted) + { + mIsActive = state; + startsActive = state; + if (activeSprite != null) + { + activeSprite.alpha = ((!state) ? 0f : 1f); + } + } + else if (mIsActive != state) + { + if (group != 0 && state) + { + int num = 0; + int size = list.size; + while (num < size) + { + UIToggle uIToggle = list[num]; + if (uIToggle != this && uIToggle.group == group) + { + uIToggle.Set(state: false); + } + if (list.size != size) + { + size = list.size; + num = 0; + } + else + { + num++; + } + } + } + mIsActive = state; + if (activeSprite != null) + { + if (instantTween || !NGUITools.GetActive(this)) + { + activeSprite.alpha = ((!mIsActive) ? 0f : 1f); + } + else + { + TweenAlpha.Begin(activeSprite.gameObject, 0.15f, (!mIsActive) ? 0f : 1f); + } + } + if (current == null) + { + UIToggle uIToggle2 = current; + current = this; + if (EventDelegate.IsValid(onChange)) + { + EventDelegate.Execute(onChange); + } + else if (eventReceiver != null && !string.IsNullOrEmpty(functionName)) + { + eventReceiver.SendMessage(functionName, mIsActive, SendMessageOptions.DontRequireReceiver); + } + current = uIToggle2; + } + if (this.activeAnimation != null) + { + ActiveAnimation activeAnimation = ActiveAnimation.Play(this.activeAnimation, null, state ? Direction.Forward : Direction.Reverse, EnableCondition.IgnoreDisabledState, DisableCondition.DoNotDisable); + if (activeAnimation != null && (instantTween || !NGUITools.GetActive(this))) + { + activeAnimation.Finish(); + } + } + } + } +} diff --git a/UIToggledComponents.cs b/UIToggledComponents.cs new file mode 100644 index 00000000..e969b856 --- /dev/null +++ b/UIToggledComponents.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Toggled Components")] +[ExecuteInEditMode] +[RequireComponent(typeof(UIToggle))] +public class UIToggledComponents : MonoBehaviour +{ + public List activate; + + public List deactivate; + + [HideInInspector] + [SerializeField] + private MonoBehaviour target; + + [HideInInspector] + [SerializeField] + private bool inverse; + + private void Awake() + { + if (target != null) + { + if (activate.Count == 0 && deactivate.Count == 0) + { + if (inverse) + { + deactivate.Add(target); + } + else + { + activate.Add(target); + } + } + else + { + target = null; + } + } + UIToggle component = GetComponent(); + EventDelegate.Add(component.onChange, Toggle); + } + + public void Toggle() + { + if (base.enabled) + { + for (int i = 0; i < activate.Count; i++) + { + MonoBehaviour monoBehaviour = activate[i]; + monoBehaviour.enabled = UIToggle.current.value; + } + for (int j = 0; j < deactivate.Count; j++) + { + MonoBehaviour monoBehaviour2 = deactivate[j]; + monoBehaviour2.enabled = !UIToggle.current.value; + } + } + } +} diff --git a/UIToggledObjects.cs b/UIToggledObjects.cs new file mode 100644 index 00000000..17917c39 --- /dev/null +++ b/UIToggledObjects.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Toggled Objects")] +public class UIToggledObjects : MonoBehaviour +{ + public List activate; + + public List deactivate; + + [HideInInspector] + [SerializeField] + private GameObject target; + + [HideInInspector] + [SerializeField] + private bool inverse; + + private void Awake() + { + if (target != null) + { + if (activate.Count == 0 && deactivate.Count == 0) + { + if (inverse) + { + deactivate.Add(target); + } + else + { + activate.Add(target); + } + } + else + { + target = null; + } + } + UIToggle component = GetComponent(); + EventDelegate.Add(component.onChange, Toggle); + } + + public void Toggle() + { + bool value = UIToggle.current.value; + if (base.enabled) + { + for (int i = 0; i < activate.Count; i++) + { + Set(activate[i], value); + } + for (int j = 0; j < deactivate.Count; j++) + { + Set(deactivate[j], !value); + } + } + } + + private void Set(GameObject go, bool state) + { + if (go != null) + { + NGUITools.SetActive(go, state); + } + } +} diff --git a/UITooltip.cs b/UITooltip.cs new file mode 100644 index 00000000..686e2e87 --- /dev/null +++ b/UITooltip.cs @@ -0,0 +1,181 @@ +using System; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Tooltip")] +public class UITooltip : MonoBehaviour +{ + protected static UITooltip mInstance; + + public Camera uiCamera; + + public UILabel text; + + public UISprite background; + + public float appearSpeed = 10f; + + public bool scalingTransitions = true; + + protected GameObject mHover; + + protected Transform mTrans; + + protected float mTarget; + + protected float mCurrent; + + protected Vector3 mPos; + + protected Vector3 mSize = Vector3.zero; + + protected UIWidget[] mWidgets; + + public static bool isVisible => mInstance != null && mInstance.mTarget == 1f; + + private void Awake() + { + mInstance = this; + } + + private void OnDestroy() + { + mInstance = null; + } + + protected virtual void Start() + { + mTrans = base.transform; + mWidgets = GetComponentsInChildren(); + mPos = mTrans.localPosition; + if (uiCamera == null) + { + uiCamera = NGUITools.FindCameraForLayer(base.gameObject.layer); + } + SetAlpha(0f); + } + + protected virtual void Update() + { + if (mHover != UICamera.hoveredObject) + { + mHover = null; + mTarget = 0f; + } + if (mCurrent != mTarget) + { + mCurrent = Mathf.Lerp(mCurrent, mTarget, RealTime.deltaTime * appearSpeed); + if (Mathf.Abs(mCurrent - mTarget) < 0.001f) + { + mCurrent = mTarget; + } + SetAlpha(mCurrent * mCurrent); + if (scalingTransitions) + { + Vector3 b = mSize * 0.25f; + b.y = 0f - b.y; + Vector3 localScale = Vector3.one * (1.5f - mCurrent * 0.5f); + Vector3 localPosition = Vector3.Lerp(mPos - b, mPos, mCurrent); + mTrans.localPosition = localPosition; + mTrans.localScale = localScale; + } + } + } + + protected virtual void SetAlpha(float val) + { + int i = 0; + for (int num = mWidgets.Length; i < num; i++) + { + UIWidget uIWidget = mWidgets[i]; + Color color = uIWidget.color; + color.a = val; + uIWidget.color = color; + } + } + + protected virtual void SetText(string tooltipText) + { + if (text != null && !string.IsNullOrEmpty(tooltipText)) + { + mTarget = 1f; + mHover = UICamera.hoveredObject; + text.text = tooltipText; + mPos = Input.mousePosition; + Transform transform = text.transform; + Vector3 localPosition = transform.localPosition; + Vector3 localScale = transform.localScale; + mSize = text.printedSize; + mSize.x *= localScale.x; + mSize.y *= localScale.y; + if (background != null) + { + Vector4 border = background.border; + mSize.x += border.x + border.z + (localPosition.x - border.x) * 2f; + mSize.y += border.y + border.w + (0f - localPosition.y - border.y) * 2f; + background.width = Mathf.RoundToInt(mSize.x); + background.height = Mathf.RoundToInt(mSize.y); + } + if (uiCamera != null) + { + mPos.x = Mathf.Clamp01(mPos.x / (float)Screen.width); + mPos.y = Mathf.Clamp01(mPos.y / (float)Screen.height); + float orthographicSize = uiCamera.orthographicSize; + Vector3 lossyScale = mTrans.parent.lossyScale; + float num = orthographicSize / lossyScale.y; + float num2 = (float)Screen.height * 0.5f / num; + Vector2 vector = new Vector2(num2 * mSize.x / (float)Screen.width, num2 * mSize.y / (float)Screen.height); + mPos.x = Mathf.Min(mPos.x, 1f - vector.x); + mPos.y = Mathf.Max(mPos.y, vector.y); + mTrans.position = uiCamera.ViewportToWorldPoint(mPos); + mPos = mTrans.localPosition; + mPos.x = Mathf.Round(mPos.x); + mPos.y = Mathf.Round(mPos.y); + mTrans.localPosition = mPos; + } + else + { + if (mPos.x + mSize.x > (float)Screen.width) + { + mPos.x = (float)Screen.width - mSize.x; + } + if (mPos.y - mSize.y < 0f) + { + mPos.y = mSize.y; + } + mPos.x -= (float)Screen.width * 0.5f; + mPos.y -= (float)Screen.height * 0.5f; + } + } + else + { + mHover = null; + mTarget = 0f; + } + } + + [Obsolete("Use UITooltip.Show instead")] + public static void ShowText(string text) + { + if (mInstance != null) + { + mInstance.SetText(text); + } + } + + public static void Show(string text) + { + if (mInstance != null) + { + mInstance.SetText(text); + } + } + + public static void Hide() + { + if (mInstance != null) + { + mInstance.mHover = null; + mInstance.mTarget = 0f; + } + } +} diff --git a/UITweener.cs b/UITweener.cs new file mode 100644 index 00000000..3b13defc --- /dev/null +++ b/UITweener.cs @@ -0,0 +1,367 @@ +using AnimationOrTween; +using System; +using System.Collections.Generic; +using UnityEngine; + +public abstract class UITweener : MonoBehaviour +{ + public enum Method + { + Linear, + EaseIn, + EaseOut, + EaseInOut, + BounceIn, + BounceOut + } + + public enum Style + { + Once, + Loop, + PingPong + } + + public static UITweener current; + + [HideInInspector] + public Method method; + + [HideInInspector] + public Style style; + + [HideInInspector] + public AnimationCurve animationCurve = new AnimationCurve(new Keyframe(0f, 0f, 0f, 1f), new Keyframe(1f, 1f, 1f, 0f)); + + [HideInInspector] + public bool ignoreTimeScale = true; + + [HideInInspector] + public float delay; + + [HideInInspector] + public float duration = 1f; + + [HideInInspector] + public bool steeperCurves; + + [HideInInspector] + public int tweenGroup; + + [HideInInspector] + public List onFinished = new List(); + + [HideInInspector] + public GameObject eventReceiver; + + [HideInInspector] + public string callWhenFinished; + + private bool mStarted; + + private float mStartTime; + + private float mDuration; + + private float mAmountPerDelta = 1000f; + + private float mFactor; + + private List mTemp; + + public float amountPerDelta + { + get + { + if (mDuration != duration) + { + mDuration = duration; + mAmountPerDelta = Mathf.Abs((!(duration > 0f)) ? 1000f : (1f / duration)) * Mathf.Sign(mAmountPerDelta); + } + return mAmountPerDelta; + } + } + + public float tweenFactor + { + get + { + return mFactor; + } + set + { + mFactor = Mathf.Clamp01(value); + } + } + + public Direction direction => (!(amountPerDelta < 0f)) ? Direction.Forward : Direction.Reverse; + + private void Reset() + { + if (!mStarted) + { + SetStartToCurrentValue(); + SetEndToCurrentValue(); + } + } + + protected virtual void Start() + { + Update(); + } + + private void Update() + { + float num = (!ignoreTimeScale) ? Time.deltaTime : RealTime.deltaTime; + float num2 = (!ignoreTimeScale) ? Time.time : RealTime.time; + if (!mStarted) + { + mStarted = true; + mStartTime = num2 + delay; + } + if (!(num2 < mStartTime)) + { + mFactor += amountPerDelta * num; + if (style == Style.Loop) + { + if (mFactor > 1f) + { + mFactor -= Mathf.Floor(mFactor); + } + } + else if (style == Style.PingPong) + { + if (mFactor > 1f) + { + mFactor = 1f - (mFactor - Mathf.Floor(mFactor)); + mAmountPerDelta = 0f - mAmountPerDelta; + } + else if (mFactor < 0f) + { + mFactor = 0f - mFactor; + mFactor -= Mathf.Floor(mFactor); + mAmountPerDelta = 0f - mAmountPerDelta; + } + } + if (style == Style.Once && (duration == 0f || mFactor > 1f || mFactor < 0f)) + { + mFactor = Mathf.Clamp01(mFactor); + Sample(mFactor, isFinished: true); + if (duration == 0f || (mFactor == 1f && mAmountPerDelta > 0f) || (mFactor == 0f && mAmountPerDelta < 0f)) + { + base.enabled = false; + } + if (current == null) + { + current = this; + if (onFinished != null) + { + mTemp = onFinished; + onFinished = new List(); + EventDelegate.Execute(mTemp); + for (int i = 0; i < mTemp.Count; i++) + { + EventDelegate eventDelegate = mTemp[i]; + if (eventDelegate != null && !eventDelegate.oneShot) + { + EventDelegate.Add(onFinished, eventDelegate, eventDelegate.oneShot); + } + } + mTemp = null; + } + if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished)) + { + eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver); + } + current = null; + } + } + else + { + Sample(mFactor, isFinished: false); + } + } + } + + public void SetOnFinished(EventDelegate.Callback del) + { + EventDelegate.Set(onFinished, del); + } + + public void SetOnFinished(EventDelegate del) + { + EventDelegate.Set(onFinished, del); + } + + public void AddOnFinished(EventDelegate.Callback del) + { + EventDelegate.Add(onFinished, del); + } + + public void AddOnFinished(EventDelegate del) + { + EventDelegate.Add(onFinished, del); + } + + public void RemoveOnFinished(EventDelegate del) + { + if (onFinished != null) + { + onFinished.Remove(del); + } + if (mTemp != null) + { + mTemp.Remove(del); + } + } + + private void OnDisable() + { + mStarted = false; + } + + public void Sample(float factor, bool isFinished) + { + float num = Mathf.Clamp01(factor); + if (method == Method.EaseIn) + { + num = 1f - Mathf.Sin(1.57079637f * (1f - num)); + if (steeperCurves) + { + num *= num; + } + } + else if (method == Method.EaseOut) + { + num = Mathf.Sin(1.57079637f * num); + if (steeperCurves) + { + num = 1f - num; + num = 1f - num * num; + } + } + else if (method == Method.EaseInOut) + { + num -= Mathf.Sin(num * 6.28318548f) / 6.28318548f; + if (steeperCurves) + { + num = num * 2f - 1f; + float num2 = Mathf.Sign(num); + num = 1f - Mathf.Abs(num); + num = 1f - num * num; + num = num2 * num * 0.5f + 0.5f; + } + } + else if (method == Method.BounceIn) + { + num = BounceLogic(num); + } + else if (method == Method.BounceOut) + { + num = 1f - BounceLogic(1f - num); + } + OnUpdate((animationCurve == null) ? num : animationCurve.Evaluate(num), isFinished); + } + + private float BounceLogic(float val) + { + val = ((val < 0.363636f) ? (7.5685f * val * val) : ((val < 0.727272f) ? (7.5625f * (val -= 0.545454f) * val + 0.75f) : ((!(val < 0.90909f)) ? (7.5625f * (val -= 0.9545454f) * val + 0.984375f) : (7.5625f * (val -= 0.818181f) * val + 0.9375f)))); + return val; + } + + [Obsolete("Use PlayForward() instead")] + public void Play() + { + Play(forward: true); + } + + public void PlayForward() + { + Play(forward: true); + } + + public void PlayReverse() + { + Play(forward: false); + } + + public void Play(bool forward) + { + mAmountPerDelta = Mathf.Abs(amountPerDelta); + if (!forward) + { + mAmountPerDelta = 0f - mAmountPerDelta; + } + base.enabled = true; + Update(); + } + + public void ResetToBeginning() + { + mStarted = false; + mFactor = ((!(amountPerDelta < 0f)) ? 0f : 1f); + Sample(mFactor, isFinished: false); + } + + public void Toggle() + { + if (mFactor > 0f) + { + mAmountPerDelta = 0f - amountPerDelta; + } + else + { + mAmountPerDelta = Mathf.Abs(amountPerDelta); + } + base.enabled = true; + } + + protected abstract void OnUpdate(float factor, bool isFinished); + + public static T Begin(GameObject go, float duration) where T : UITweener + { + T val = go.GetComponent(); + if ((UnityEngine.Object)val != (UnityEngine.Object)null && val.tweenGroup != 0) + { + val = (T)null; + T[] components = go.GetComponents(); + int i = 0; + for (int num = components.Length; i < num; i++) + { + val = components[i]; + if ((UnityEngine.Object)val != (UnityEngine.Object)null && val.tweenGroup == 0) + { + break; + } + val = (T)null; + } + } + if ((UnityEngine.Object)val == (UnityEngine.Object)null) + { + val = go.AddComponent(); + if ((UnityEngine.Object)val == (UnityEngine.Object)null) + { + Debug.LogError("Unable to add " + typeof(T) + " to " + NGUITools.GetHierarchy(go), go); + return (T)null; + } + } + val.mStarted = false; + val.duration = duration; + val.mFactor = 0f; + val.mAmountPerDelta = Mathf.Abs(val.amountPerDelta); + val.style = Style.Once; + val.animationCurve = new AnimationCurve(new Keyframe(0f, 0f, 0f, 1f), new Keyframe(1f, 1f, 1f, 0f)); + val.eventReceiver = null; + val.callWhenFinished = null; + val.enabled = true; + return val; + } + + public virtual void SetStartToCurrentValue() + { + } + + public virtual void SetEndToCurrentValue() + { + } +} diff --git a/UIViewport.cs b/UIViewport.cs new file mode 100644 index 00000000..7cd0612f --- /dev/null +++ b/UIViewport.cs @@ -0,0 +1,45 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/UI/Viewport Camera")] +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +public class UIViewport : MonoBehaviour +{ + public Camera sourceCamera; + + public Transform topLeft; + + public Transform bottomRight; + + public float fullSize = 1f; + + private Camera mCam; + + private void Start() + { + mCam = GetComponent(); + if (sourceCamera == null) + { + sourceCamera = Camera.main; + } + } + + private void LateUpdate() + { + if (topLeft != null && bottomRight != null) + { + Vector3 vector = sourceCamera.WorldToScreenPoint(topLeft.position); + Vector3 vector2 = sourceCamera.WorldToScreenPoint(bottomRight.position); + Rect rect = new Rect(vector.x / (float)Screen.width, vector2.y / (float)Screen.height, (vector2.x - vector.x) / (float)Screen.width, (vector.y - vector2.y) / (float)Screen.height); + float num = fullSize * rect.height; + if (rect != mCam.rect) + { + mCam.rect = rect; + } + if (mCam.orthographicSize != num) + { + mCam.orthographicSize = num; + } + } + } +} diff --git a/UIWidget.cs b/UIWidget.cs new file mode 100644 index 00000000..df0427a1 --- /dev/null +++ b/UIWidget.cs @@ -0,0 +1,1164 @@ +using System; +using System.Diagnostics; +using UnityEngine; + +[AddComponentMenu("NGUI/UI/NGUI Widget")] +[ExecuteInEditMode] +public class UIWidget : UIRect +{ + public enum Pivot + { + TopLeft, + Top, + TopRight, + Left, + Center, + Right, + BottomLeft, + Bottom, + BottomRight + } + + public enum AspectRatioSource + { + Free, + BasedOnWidth, + BasedOnHeight + } + + public delegate void OnDimensionsChanged(); + + public delegate void OnPostFillCallback(UIWidget widget, int bufferOffset, BetterList verts, BetterList uvs, BetterList cols); + + public delegate bool HitCheck(Vector3 worldPos); + + [HideInInspector] + [SerializeField] + protected Color mColor = Color.white; + + [HideInInspector] + [SerializeField] + protected Pivot mPivot = Pivot.Center; + + [HideInInspector] + [SerializeField] + protected int mWidth = 100; + + [HideInInspector] + [SerializeField] + protected int mHeight = 100; + + [HideInInspector] + [SerializeField] + protected int mDepth; + + public OnDimensionsChanged onChange; + + public OnPostFillCallback onPostFill; + + public UIDrawCall.OnRenderCallback mOnRender; + + public bool autoResizeBoxCollider; + + public bool hideIfOffScreen; + + public AspectRatioSource keepAspectRatio; + + public float aspectRatio = 1f; + + public HitCheck hitCheck; + + [NonSerialized] + public UIPanel panel; + + [NonSerialized] + public UIGeometry geometry = new UIGeometry(); + + [NonSerialized] + public bool fillGeometry = true; + + [NonSerialized] + protected bool mPlayMode = true; + + [NonSerialized] + protected Vector4 mDrawRegion = new Vector4(0f, 0f, 1f, 1f); + + [NonSerialized] + private Matrix4x4 mLocalToPanel; + + [NonSerialized] + private bool mIsVisibleByAlpha = true; + + [NonSerialized] + private bool mIsVisibleByPanel = true; + + [NonSerialized] + private bool mIsInFront = true; + + [NonSerialized] + private float mLastAlpha; + + [NonSerialized] + private bool mMoved; + + [NonSerialized] + public UIDrawCall drawCall; + + [NonSerialized] + protected Vector3[] mCorners = new Vector3[4]; + + [NonSerialized] + private int mAlphaFrameID = -1; + + private int mMatrixFrame = -1; + + private Vector3 mOldV0; + + private Vector3 mOldV1; + + public UIDrawCall.OnRenderCallback onRender + { + get + { + return mOnRender; + } + set + { + if (mOnRender != value) + { + if (drawCall != null && drawCall.onRender != null && mOnRender != null) + { + UIDrawCall uIDrawCall = drawCall; + uIDrawCall.onRender = (UIDrawCall.OnRenderCallback)Delegate.Remove(uIDrawCall.onRender, mOnRender); + } + mOnRender = value; + if (drawCall != null) + { + UIDrawCall uIDrawCall2 = drawCall; + uIDrawCall2.onRender = (UIDrawCall.OnRenderCallback)Delegate.Combine(uIDrawCall2.onRender, value); + } + } + } + } + + public Vector4 drawRegion + { + get + { + return mDrawRegion; + } + set + { + if (mDrawRegion != value) + { + mDrawRegion = value; + if (autoResizeBoxCollider) + { + ResizeCollider(); + } + MarkAsChanged(); + } + } + } + + public Vector2 pivotOffset => NGUIMath.GetPivotOffset(pivot); + + public int width + { + get + { + return mWidth; + } + set + { + int minWidth = this.minWidth; + if (value < minWidth) + { + value = minWidth; + } + if (mWidth != value && keepAspectRatio != AspectRatioSource.BasedOnHeight) + { + if (isAnchoredHorizontally) + { + if (leftAnchor.target != null && rightAnchor.target != null) + { + if (mPivot == Pivot.BottomLeft || mPivot == Pivot.Left || mPivot == Pivot.TopLeft) + { + NGUIMath.AdjustWidget(this, 0f, 0f, (float)(value - mWidth), 0f); + } + else if (mPivot == Pivot.BottomRight || mPivot == Pivot.Right || mPivot == Pivot.TopRight) + { + NGUIMath.AdjustWidget(this, (float)(mWidth - value), 0f, 0f, 0f); + } + else + { + int num = value - mWidth; + num -= (num & 1); + if (num != 0) + { + NGUIMath.AdjustWidget(this, (float)(-num) * 0.5f, 0f, (float)num * 0.5f, 0f); + } + } + } + else if (leftAnchor.target != null) + { + NGUIMath.AdjustWidget(this, 0f, 0f, (float)(value - mWidth), 0f); + } + else + { + NGUIMath.AdjustWidget(this, (float)(mWidth - value), 0f, 0f, 0f); + } + } + else + { + SetDimensions(value, mHeight); + } + } + } + } + + public int height + { + get + { + return mHeight; + } + set + { + int minHeight = this.minHeight; + if (value < minHeight) + { + value = minHeight; + } + if (mHeight != value && keepAspectRatio != AspectRatioSource.BasedOnWidth) + { + if (isAnchoredVertically) + { + if (bottomAnchor.target != null && topAnchor.target != null) + { + if (mPivot == Pivot.BottomLeft || mPivot == Pivot.Bottom || mPivot == Pivot.BottomRight) + { + NGUIMath.AdjustWidget(this, 0f, 0f, 0f, (float)(value - mHeight)); + } + else if (mPivot == Pivot.TopLeft || mPivot == Pivot.Top || mPivot == Pivot.TopRight) + { + NGUIMath.AdjustWidget(this, 0f, (float)(mHeight - value), 0f, 0f); + } + else + { + int num = value - mHeight; + num -= (num & 1); + if (num != 0) + { + NGUIMath.AdjustWidget(this, 0f, (float)(-num) * 0.5f, 0f, (float)num * 0.5f); + } + } + } + else if (bottomAnchor.target != null) + { + NGUIMath.AdjustWidget(this, 0f, 0f, 0f, (float)(value - mHeight)); + } + else + { + NGUIMath.AdjustWidget(this, 0f, (float)(mHeight - value), 0f, 0f); + } + } + else + { + SetDimensions(mWidth, value); + } + } + } + } + + public Color color + { + get + { + return mColor; + } + set + { + if (mColor != value) + { + bool includeChildren = mColor.a != value.a; + mColor = value; + Invalidate(includeChildren); + } + } + } + + public override float alpha + { + get + { + return mColor.a; + } + set + { + if (mColor.a != value) + { + mColor.a = value; + Invalidate(includeChildren: true); + } + } + } + + public bool isVisible => mIsVisibleByPanel && mIsVisibleByAlpha && mIsInFront && finalAlpha > 0.001f && NGUITools.GetActive(this); + + public bool hasVertices => geometry != null && geometry.hasVertices; + + public Pivot rawPivot + { + get + { + return mPivot; + } + set + { + if (mPivot != value) + { + mPivot = value; + if (autoResizeBoxCollider) + { + ResizeCollider(); + } + MarkAsChanged(); + } + } + } + + public Pivot pivot + { + get + { + return mPivot; + } + set + { + if (mPivot != value) + { + Vector3 vector = worldCorners[0]; + mPivot = value; + mChanged = true; + Vector3 vector2 = worldCorners[0]; + Transform cachedTransform = base.cachedTransform; + Vector3 vector3 = cachedTransform.position; + Vector3 localPosition = cachedTransform.localPosition; + float z = localPosition.z; + vector3.x += vector.x - vector2.x; + vector3.y += vector.y - vector2.y; + base.cachedTransform.position = vector3; + vector3 = base.cachedTransform.localPosition; + vector3.x = Mathf.Round(vector3.x); + vector3.y = Mathf.Round(vector3.y); + vector3.z = z; + base.cachedTransform.localPosition = vector3; + } + } + } + + public int depth + { + get + { + return mDepth; + } + set + { + if (mDepth != value) + { + if (panel != null) + { + panel.RemoveWidget(this); + } + mDepth = value; + if (panel != null) + { + panel.AddWidget(this); + if (!Application.isPlaying) + { + panel.SortWidgets(); + panel.RebuildAllDrawCalls(); + } + } + } + } + } + + public int raycastDepth + { + get + { + if (panel == null) + { + CreatePanel(); + } + return (!(panel != null)) ? mDepth : (mDepth + panel.depth * 1000); + } + } + + public override Vector3[] localCorners + { + get + { + Vector2 pivotOffset = this.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float x = num + (float)mWidth; + float y = num2 + (float)mHeight; + mCorners[0] = new Vector3(num, num2); + mCorners[1] = new Vector3(num, y); + mCorners[2] = new Vector3(x, y); + mCorners[3] = new Vector3(x, num2); + return mCorners; + } + } + + public virtual Vector2 localSize + { + get + { + Vector3[] localCorners = this.localCorners; + return localCorners[2] - localCorners[0]; + } + } + + public Vector3 localCenter + { + get + { + Vector3[] localCorners = this.localCorners; + return Vector3.Lerp(localCorners[0], localCorners[2], 0.5f); + } + } + + public override Vector3[] worldCorners + { + get + { + Vector2 pivotOffset = this.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float x = num + (float)mWidth; + float y = num2 + (float)mHeight; + Transform cachedTransform = base.cachedTransform; + mCorners[0] = cachedTransform.TransformPoint(num, num2, 0f); + mCorners[1] = cachedTransform.TransformPoint(num, y, 0f); + mCorners[2] = cachedTransform.TransformPoint(x, y, 0f); + mCorners[3] = cachedTransform.TransformPoint(x, num2, 0f); + return mCorners; + } + } + + public Vector3 worldCenter => base.cachedTransform.TransformPoint(localCenter); + + public virtual Vector4 drawingDimensions + { + get + { + Vector2 pivotOffset = this.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float num3 = num + (float)mWidth; + float num4 = num2 + (float)mHeight; + return new Vector4((mDrawRegion.x != 0f) ? Mathf.Lerp(num, num3, mDrawRegion.x) : num, (mDrawRegion.y != 0f) ? Mathf.Lerp(num2, num4, mDrawRegion.y) : num2, (mDrawRegion.z != 1f) ? Mathf.Lerp(num, num3, mDrawRegion.z) : num3, (mDrawRegion.w != 1f) ? Mathf.Lerp(num2, num4, mDrawRegion.w) : num4); + } + } + + public virtual Material material + { + get + { + return null; + } + set + { + throw new NotImplementedException(GetType() + " has no material setter"); + } + } + + public virtual Texture mainTexture + { + get + { + Material material = this.material; + return (!(material != null)) ? null : material.mainTexture; + } + set + { + throw new NotImplementedException(GetType() + " has no mainTexture setter"); + } + } + + public virtual Shader shader + { + get + { + Material material = this.material; + return (!(material != null)) ? null : material.shader; + } + set + { + throw new NotImplementedException(GetType() + " has no shader setter"); + } + } + + [Obsolete("There is no relative scale anymore. Widgets now have width and height instead")] + public Vector2 relativeSize + { + get + { + return Vector2.one; + } + } + + public bool hasBoxCollider + { + get + { + BoxCollider x = GetComponent() as BoxCollider; + if (x != null) + { + return true; + } + return GetComponent() != null; + } + } + + public virtual int minWidth => 2; + + public virtual int minHeight => 2; + + public virtual Vector4 border + { + get + { + return Vector4.zero; + } + set + { + } + } + + public void SetDimensions(int w, int h) + { + if (mWidth != w || mHeight != h) + { + mWidth = w; + mHeight = h; + if (keepAspectRatio == AspectRatioSource.BasedOnWidth) + { + mHeight = Mathf.RoundToInt((float)mWidth / aspectRatio); + } + else if (keepAspectRatio == AspectRatioSource.BasedOnHeight) + { + mWidth = Mathf.RoundToInt((float)mHeight * aspectRatio); + } + else if (keepAspectRatio == AspectRatioSource.Free) + { + aspectRatio = (float)mWidth / (float)mHeight; + } + mMoved = true; + if (autoResizeBoxCollider) + { + ResizeCollider(); + } + MarkAsChanged(); + } + } + + public override Vector3[] GetSides(Transform relativeTo) + { + Vector2 pivotOffset = this.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float num3 = num + (float)mWidth; + float num4 = num2 + (float)mHeight; + float x = (num + num3) * 0.5f; + float y = (num2 + num4) * 0.5f; + Transform cachedTransform = base.cachedTransform; + mCorners[0] = cachedTransform.TransformPoint(num, y, 0f); + mCorners[1] = cachedTransform.TransformPoint(x, num4, 0f); + mCorners[2] = cachedTransform.TransformPoint(num3, y, 0f); + mCorners[3] = cachedTransform.TransformPoint(x, num2, 0f); + if (relativeTo != null) + { + for (int i = 0; i < 4; i++) + { + mCorners[i] = relativeTo.InverseTransformPoint(mCorners[i]); + } + } + return mCorners; + } + + public override float CalculateFinalAlpha(int frameID) + { + if (mAlphaFrameID != frameID) + { + mAlphaFrameID = frameID; + UpdateFinalAlpha(frameID); + } + return finalAlpha; + } + + protected void UpdateFinalAlpha(int frameID) + { + if (!mIsVisibleByAlpha || !mIsInFront) + { + finalAlpha = 0f; + } + else + { + UIRect parent = base.parent; + finalAlpha = ((!(base.parent != null)) ? mColor.a : (parent.CalculateFinalAlpha(frameID) * mColor.a)); + } + } + + public override void Invalidate(bool includeChildren) + { + mChanged = true; + mAlphaFrameID = -1; + if (panel != null) + { + bool visibleByPanel = (!hideIfOffScreen && !panel.hasCumulativeClipping) || panel.IsVisible(this); + UpdateVisibility(CalculateCumulativeAlpha(Time.frameCount) > 0.001f, visibleByPanel); + UpdateFinalAlpha(Time.frameCount); + if (includeChildren) + { + base.Invalidate(includeChildren: true); + } + } + } + + public float CalculateCumulativeAlpha(int frameID) + { + UIRect parent = base.parent; + return (!(parent != null)) ? mColor.a : (parent.CalculateFinalAlpha(frameID) * mColor.a); + } + + public override void SetRect(float x, float y, float width, float height) + { + Vector2 pivotOffset = this.pivotOffset; + float num = Mathf.Lerp(x, x + width, pivotOffset.x); + float num2 = Mathf.Lerp(y, y + height, pivotOffset.y); + int num3 = Mathf.FloorToInt(width + 0.5f); + int num4 = Mathf.FloorToInt(height + 0.5f); + if (pivotOffset.x == 0.5f) + { + num3 = num3 >> 1 << 1; + } + if (pivotOffset.y == 0.5f) + { + num4 = num4 >> 1 << 1; + } + Transform cachedTransform = base.cachedTransform; + Vector3 localPosition = cachedTransform.localPosition; + localPosition.x = Mathf.Floor(num + 0.5f); + localPosition.y = Mathf.Floor(num2 + 0.5f); + if (num3 < minWidth) + { + num3 = minWidth; + } + if (num4 < minHeight) + { + num4 = minHeight; + } + cachedTransform.localPosition = localPosition; + this.width = num3; + this.height = num4; + if (base.isAnchored) + { + cachedTransform = cachedTransform.parent; + if ((bool)leftAnchor.target) + { + leftAnchor.SetHorizontal(cachedTransform, x); + } + if ((bool)rightAnchor.target) + { + rightAnchor.SetHorizontal(cachedTransform, x + width); + } + if ((bool)bottomAnchor.target) + { + bottomAnchor.SetVertical(cachedTransform, y); + } + if ((bool)topAnchor.target) + { + topAnchor.SetVertical(cachedTransform, y + height); + } + } + } + + public void ResizeCollider() + { + if (NGUITools.GetActive(this)) + { + NGUITools.UpdateWidgetCollider(base.gameObject); + } + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static int FullCompareFunc(UIWidget left, UIWidget right) + { + int num = UIPanel.CompareFunc(left.panel, right.panel); + return (num != 0) ? num : PanelCompareFunc(left, right); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static int PanelCompareFunc(UIWidget left, UIWidget right) + { + if (left.mDepth < right.mDepth) + { + return -1; + } + if (left.mDepth > right.mDepth) + { + return 1; + } + Material material = left.material; + Material material2 = right.material; + if (material == material2) + { + return 0; + } + if (material != null) + { + return -1; + } + if (material2 != null) + { + return 1; + } + return (material.GetInstanceID() >= material2.GetInstanceID()) ? 1 : (-1); + } + + public Bounds CalculateBounds() + { + return CalculateBounds(null); + } + + public Bounds CalculateBounds(Transform relativeParent) + { + if (relativeParent == null) + { + Vector3[] localCorners = this.localCorners; + Bounds result = new Bounds(localCorners[0], Vector3.zero); + for (int i = 1; i < 4; i++) + { + result.Encapsulate(localCorners[i]); + } + return result; + } + Matrix4x4 worldToLocalMatrix = relativeParent.worldToLocalMatrix; + Vector3[] worldCorners = this.worldCorners; + Bounds result2 = new Bounds(worldToLocalMatrix.MultiplyPoint3x4(worldCorners[0]), Vector3.zero); + for (int j = 1; j < 4; j++) + { + result2.Encapsulate(worldToLocalMatrix.MultiplyPoint3x4(worldCorners[j])); + } + return result2; + } + + public void SetDirty() + { + if (drawCall != null) + { + drawCall.isDirty = true; + } + else if (isVisible && hasVertices) + { + CreatePanel(); + } + } + + public void RemoveFromPanel() + { + if (panel != null) + { + panel.RemoveWidget(this); + panel = null; + } + drawCall = null; + } + + public virtual void MarkAsChanged() + { + if (NGUITools.GetActive(this)) + { + mChanged = true; + if (panel != null && base.enabled && NGUITools.GetActive(base.gameObject) && !mPlayMode) + { + SetDirty(); + CheckLayer(); + } + } + } + + public UIPanel CreatePanel() + { + if (mStarted && panel == null && base.enabled && NGUITools.GetActive(base.gameObject)) + { + panel = UIPanel.Find(base.cachedTransform, /*createIfMissing:*/ true, base.cachedGameObject.layer); + if (panel != null) + { + mParentFound = false; + panel.AddWidget(this); + CheckLayer(); + Invalidate(includeChildren: true); + } + } + return panel; + } + + public void CheckLayer() + { + if (panel != null && panel.gameObject.layer != base.gameObject.layer) + { + UnityEngine.Debug.LogWarning("You can't place widgets on a layer different than the UIPanel that manages them.\nIf you want to move widgets to a different layer, parent them to a new panel instead.", this); + base.gameObject.layer = panel.gameObject.layer; + } + } + + public override void ParentHasChanged() + { + base.ParentHasChanged(); + if (panel != null) + { + UIPanel y = UIPanel.Find(base.cachedTransform, /*createIfMissing:*/ true, base.cachedGameObject.layer); + if (panel != y) + { + RemoveFromPanel(); + CreatePanel(); + } + } + } + + protected virtual void Awake() + { + mGo = base.gameObject; + mPlayMode = Application.isPlaying; + } + + protected override void OnInit() + { + base.OnInit(); + RemoveFromPanel(); + mMoved = true; + if (mWidth == 100 && mHeight == 100 && base.cachedTransform.localScale.magnitude > 8f) + { + UpgradeFrom265(); + base.cachedTransform.localScale = Vector3.one; + } + Update(); + } + + protected virtual void UpgradeFrom265() + { + Vector3 localScale = base.cachedTransform.localScale; + mWidth = Mathf.Abs(Mathf.RoundToInt(localScale.x)); + mHeight = Mathf.Abs(Mathf.RoundToInt(localScale.y)); + NGUITools.UpdateWidgetCollider(base.gameObject, considerInactive: true); + } + + protected override void OnStart() + { + CreatePanel(); + } + + protected override void OnAnchor() + { + Transform cachedTransform = base.cachedTransform; + Transform parent = cachedTransform.parent; + Vector3 localPosition = cachedTransform.localPosition; + Vector2 pivotOffset = this.pivotOffset; + float num; + float num2; + float num3; + float num4; + if (leftAnchor.target == bottomAnchor.target && leftAnchor.target == rightAnchor.target && leftAnchor.target == topAnchor.target) + { + Vector3[] sides = leftAnchor.GetSides(parent); + if (sides != null) + { + num = NGUIMath.Lerp(sides[0].x, sides[2].x, leftAnchor.relative) + (float)leftAnchor.absolute; + num2 = NGUIMath.Lerp(sides[0].x, sides[2].x, rightAnchor.relative) + (float)rightAnchor.absolute; + num3 = NGUIMath.Lerp(sides[3].y, sides[1].y, bottomAnchor.relative) + (float)bottomAnchor.absolute; + num4 = NGUIMath.Lerp(sides[3].y, sides[1].y, topAnchor.relative) + (float)topAnchor.absolute; + mIsInFront = true; + } + else + { + Vector3 localPos = GetLocalPos(leftAnchor, parent); + num = localPos.x + (float)leftAnchor.absolute; + num3 = localPos.y + (float)bottomAnchor.absolute; + num2 = localPos.x + (float)rightAnchor.absolute; + num4 = localPos.y + (float)topAnchor.absolute; + mIsInFront = (!hideIfOffScreen || localPos.z >= 0f); + } + } + else + { + mIsInFront = true; + if ((bool)leftAnchor.target) + { + Vector3[] sides2 = leftAnchor.GetSides(parent); + if (sides2 != null) + { + num = NGUIMath.Lerp(sides2[0].x, sides2[2].x, leftAnchor.relative) + (float)leftAnchor.absolute; + } + else + { + Vector3 localPos2 = GetLocalPos(leftAnchor, parent); + num = localPos2.x + (float)leftAnchor.absolute; + } + } + else + { + num = localPosition.x - pivotOffset.x * (float)mWidth; + } + if ((bool)rightAnchor.target) + { + Vector3[] sides3 = rightAnchor.GetSides(parent); + if (sides3 != null) + { + num2 = NGUIMath.Lerp(sides3[0].x, sides3[2].x, rightAnchor.relative) + (float)rightAnchor.absolute; + } + else + { + Vector3 localPos3 = GetLocalPos(rightAnchor, parent); + num2 = localPos3.x + (float)rightAnchor.absolute; + } + } + else + { + num2 = localPosition.x - pivotOffset.x * (float)mWidth + (float)mWidth; + } + if ((bool)bottomAnchor.target) + { + Vector3[] sides4 = bottomAnchor.GetSides(parent); + if (sides4 != null) + { + num3 = NGUIMath.Lerp(sides4[3].y, sides4[1].y, bottomAnchor.relative) + (float)bottomAnchor.absolute; + } + else + { + Vector3 localPos4 = GetLocalPos(bottomAnchor, parent); + num3 = localPos4.y + (float)bottomAnchor.absolute; + } + } + else + { + num3 = localPosition.y - pivotOffset.y * (float)mHeight; + } + if ((bool)topAnchor.target) + { + Vector3[] sides5 = topAnchor.GetSides(parent); + if (sides5 != null) + { + num4 = NGUIMath.Lerp(sides5[3].y, sides5[1].y, topAnchor.relative) + (float)topAnchor.absolute; + } + else + { + Vector3 localPos5 = GetLocalPos(topAnchor, parent); + num4 = localPos5.y + (float)topAnchor.absolute; + } + } + else + { + num4 = localPosition.y - pivotOffset.y * (float)mHeight + (float)mHeight; + } + } + Vector3 vector = new Vector3(Mathf.Lerp(num, num2, pivotOffset.x), Mathf.Lerp(num3, num4, pivotOffset.y), localPosition.z); + int num5 = Mathf.FloorToInt(num2 - num + 0.5f); + int num6 = Mathf.FloorToInt(num4 - num3 + 0.5f); + if (keepAspectRatio != 0 && aspectRatio != 0f) + { + if (keepAspectRatio == AspectRatioSource.BasedOnHeight) + { + num5 = Mathf.RoundToInt((float)num6 * aspectRatio); + } + else + { + num6 = Mathf.RoundToInt((float)num5 / aspectRatio); + } + } + if (num5 < minWidth) + { + num5 = minWidth; + } + if (num6 < minHeight) + { + num6 = minHeight; + } + if (Vector3.SqrMagnitude(localPosition - vector) > 0.001f) + { + base.cachedTransform.localPosition = vector; + if (mIsInFront) + { + mChanged = true; + } + } + if (mWidth != num5 || mHeight != num6) + { + mWidth = num5; + mHeight = num6; + if (mIsInFront) + { + mChanged = true; + } + if (autoResizeBoxCollider) + { + ResizeCollider(); + } + } + } + + protected override void OnUpdate() + { + if (panel == null) + { + CreatePanel(); + } + } + + private void OnApplicationPause(bool paused) + { + if (!paused) + { + MarkAsChanged(); + } + } + + protected override void OnDisable() + { + RemoveFromPanel(); + base.OnDisable(); + } + + private void OnDestroy() + { + RemoveFromPanel(); + } + + public bool UpdateVisibility(bool visibleByAlpha, bool visibleByPanel) + { + if (mIsVisibleByAlpha != visibleByAlpha || mIsVisibleByPanel != visibleByPanel) + { + mChanged = true; + mIsVisibleByAlpha = visibleByAlpha; + mIsVisibleByPanel = visibleByPanel; + return true; + } + return false; + } + + public bool UpdateTransform(int frame) + { + if (!mMoved && !panel.widgetsAreStatic && base.cachedTransform.hasChanged) + { + mTrans.hasChanged = false; + mLocalToPanel = panel.worldToLocal * base.cachedTransform.localToWorldMatrix; + mMatrixFrame = frame; + Vector2 pivotOffset = this.pivotOffset; + float num = (0f - pivotOffset.x) * (float)mWidth; + float num2 = (0f - pivotOffset.y) * (float)mHeight; + float x = num + (float)mWidth; + float y = num2 + (float)mHeight; + Transform cachedTransform = base.cachedTransform; + Vector3 v = cachedTransform.TransformPoint(num, num2, 0f); + Vector3 v2 = cachedTransform.TransformPoint(x, y, 0f); + v = panel.worldToLocal.MultiplyPoint3x4(v); + v2 = panel.worldToLocal.MultiplyPoint3x4(v2); + if (Vector3.SqrMagnitude(mOldV0 - v) > 1E-06f || Vector3.SqrMagnitude(mOldV1 - v2) > 1E-06f) + { + mMoved = true; + mOldV0 = v; + mOldV1 = v2; + } + } + if (mMoved && onChange != null) + { + onChange(); + } + return mMoved || mChanged; + } + + public bool UpdateGeometry(int frame) + { + float num = CalculateFinalAlpha(frame); + if (mIsVisibleByAlpha && mLastAlpha != num) + { + mChanged = true; + } + mLastAlpha = num; + if (mChanged) + { + mChanged = false; + if (mIsVisibleByAlpha && num > 0.001f && shader != null) + { + bool hasVertices = geometry.hasVertices; + if (fillGeometry) + { + geometry.Clear(); + OnFill(geometry.verts, geometry.uvs, geometry.cols); + } + if (geometry.hasVertices) + { + if (mMatrixFrame != frame) + { + mLocalToPanel = panel.worldToLocal * base.cachedTransform.localToWorldMatrix; + mMatrixFrame = frame; + } + geometry.ApplyTransform(mLocalToPanel); + mMoved = false; + return true; + } + return hasVertices; + } + if (geometry.hasVertices) + { + if (fillGeometry) + { + geometry.Clear(); + } + mMoved = false; + return true; + } + } + else if (mMoved && geometry.hasVertices) + { + if (mMatrixFrame != frame) + { + mLocalToPanel = panel.worldToLocal * base.cachedTransform.localToWorldMatrix; + mMatrixFrame = frame; + } + geometry.ApplyTransform(mLocalToPanel); + mMoved = false; + return true; + } + mMoved = false; + return false; + } + + public void WriteToBuffers(BetterList v, BetterList u, BetterList c, BetterList n, BetterList t) + { + geometry.WriteToBuffers(v, u, c, n, t); + } + + public virtual void MakePixelPerfect() + { + Vector3 localPosition = base.cachedTransform.localPosition; + localPosition.z = Mathf.Round(localPosition.z); + localPosition.x = Mathf.Round(localPosition.x); + localPosition.y = Mathf.Round(localPosition.y); + base.cachedTransform.localPosition = localPosition; + Vector3 localScale = base.cachedTransform.localScale; + base.cachedTransform.localScale = new Vector3(Mathf.Sign(localScale.x), Mathf.Sign(localScale.y), 1f); + } + + public virtual void OnFill(BetterList verts, BetterList uvs, BetterList cols) + { + } +} diff --git a/UIWidgetContainer.cs b/UIWidgetContainer.cs new file mode 100644 index 00000000..fb73362c --- /dev/null +++ b/UIWidgetContainer.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Widget Container")] +public class UIWidgetContainer : MonoBehaviour +{ +} diff --git a/UIWrapContent.cs b/UIWrapContent.cs new file mode 100644 index 00000000..c53e1281 --- /dev/null +++ b/UIWrapContent.cs @@ -0,0 +1,289 @@ +using System.Collections.Generic; +using UnityEngine; + +[AddComponentMenu("NGUI/Interaction/Wrap Content")] +public class UIWrapContent : MonoBehaviour +{ + public delegate void OnInitializeItem(GameObject go, int wrapIndex, int realIndex); + + public int itemSize = 100; + + public bool cullContent = true; + + public int minIndex; + + public int maxIndex; + + public OnInitializeItem onInitializeItem; + + private Transform mTrans; + + private UIPanel mPanel; + + private UIScrollView mScroll; + + private bool mHorizontal; + + private bool mFirstTime = true; + + private List mChildren = new List(); + + protected virtual void Start() + { + SortBasedOnScrollMovement(); + WrapContent(); + if (mScroll != null) + { + mScroll.GetComponent().onClipMove = OnMove; + } + mFirstTime = false; + } + + protected virtual void OnMove(UIPanel panel) + { + WrapContent(); + } + + [ContextMenu("Sort Based on Scroll Movement")] + public void SortBasedOnScrollMovement() + { + if (CacheScrollView()) + { + mChildren.Clear(); + for (int i = 0; i < mTrans.childCount; i++) + { + mChildren.Add(mTrans.GetChild(i)); + } + if (mHorizontal) + { + mChildren.Sort(UIGrid.SortHorizontal); + } + else + { + mChildren.Sort(UIGrid.SortVertical); + } + ResetChildPositions(); + } + } + + [ContextMenu("Sort Alphabetically")] + public void SortAlphabetically() + { + if (CacheScrollView()) + { + mChildren.Clear(); + for (int i = 0; i < mTrans.childCount; i++) + { + mChildren.Add(mTrans.GetChild(i)); + } + mChildren.Sort(UIGrid.SortByName); + ResetChildPositions(); + } + } + + protected bool CacheScrollView() + { + mTrans = base.transform; + mPanel = NGUITools.FindInParents(base.gameObject); + mScroll = mPanel.GetComponent(); + if (mScroll == null) + { + return false; + } + if (mScroll.movement == UIScrollView.Movement.Horizontal) + { + mHorizontal = true; + } + else + { + if (mScroll.movement != UIScrollView.Movement.Vertical) + { + return false; + } + mHorizontal = false; + } + return true; + } + + private void ResetChildPositions() + { + int i = 0; + for (int count = mChildren.Count; i < count; i++) + { + Transform transform = mChildren[i]; + transform.localPosition = ((!mHorizontal) ? new Vector3(0f, (float)(-i * itemSize), 0f) : new Vector3((float)(i * itemSize), 0f, 0f)); + } + } + + public void WrapContent() + { + float num = (float)(itemSize * mChildren.Count) * 0.5f; + Vector3[] worldCorners = mPanel.worldCorners; + for (int i = 0; i < 4; i++) + { + Vector3 position = worldCorners[i]; + position = mTrans.InverseTransformPoint(position); + worldCorners[i] = position; + } + Vector3 vector = Vector3.Lerp(worldCorners[0], worldCorners[2], 0.5f); + bool flag = true; + float num2 = num * 2f; + if (mHorizontal) + { + float num3 = worldCorners[0].x - (float)itemSize; + float num4 = worldCorners[2].x + (float)itemSize; + int j = 0; + for (int count = mChildren.Count; j < count; j++) + { + Transform transform = mChildren[j]; + Vector3 localPosition = transform.localPosition; + float num5 = localPosition.x - vector.x; + if (num5 < 0f - num) + { + Vector3 localPosition2 = transform.localPosition; + localPosition2.x += num2; + num5 = localPosition2.x - vector.x; + int num6 = Mathf.RoundToInt(localPosition2.x / (float)itemSize); + if (minIndex == maxIndex || (minIndex <= num6 && num6 <= maxIndex)) + { + transform.localPosition = localPosition2; + UpdateItem(transform, j); + transform.name = num6.ToString(); + } + else + { + flag = false; + } + } + else if (num5 > num) + { + Vector3 localPosition3 = transform.localPosition; + localPosition3.x -= num2; + num5 = localPosition3.x - vector.x; + int num7 = Mathf.RoundToInt(localPosition3.x / (float)itemSize); + if (minIndex == maxIndex || (minIndex <= num7 && num7 <= maxIndex)) + { + transform.localPosition = localPosition3; + UpdateItem(transform, j); + transform.name = num7.ToString(); + } + else + { + flag = false; + } + } + else if (mFirstTime) + { + UpdateItem(transform, j); + } + if (cullContent) + { + float num8 = num5; + Vector2 clipOffset = mPanel.clipOffset; + float x = clipOffset.x; + Vector3 localPosition4 = mTrans.localPosition; + num5 = num8 + (x - localPosition4.x); + if (!UICamera.IsPressed(transform.gameObject)) + { + NGUITools.SetActive(transform.gameObject, num5 > num3 && num5 < num4, compatibilityMode: false); + } + } + } + } + else + { + float num9 = worldCorners[0].y - (float)itemSize; + float num10 = worldCorners[2].y + (float)itemSize; + int k = 0; + for (int count2 = mChildren.Count; k < count2; k++) + { + Transform transform2 = mChildren[k]; + Vector3 localPosition5 = transform2.localPosition; + float num11 = localPosition5.y - vector.y; + if (num11 < 0f - num) + { + Vector3 localPosition6 = transform2.localPosition; + localPosition6.y += num2; + num11 = localPosition6.y - vector.y; + int num12 = Mathf.RoundToInt(localPosition6.y / (float)itemSize); + if (minIndex == maxIndex || (minIndex <= num12 && num12 <= maxIndex)) + { + transform2.localPosition = localPosition6; + UpdateItem(transform2, k); + transform2.name = num12.ToString(); + } + else + { + flag = false; + } + } + else if (num11 > num) + { + Vector3 localPosition7 = transform2.localPosition; + localPosition7.y -= num2; + num11 = localPosition7.y - vector.y; + int num13 = Mathf.RoundToInt(localPosition7.y / (float)itemSize); + if (minIndex == maxIndex || (minIndex <= num13 && num13 <= maxIndex)) + { + transform2.localPosition = localPosition7; + UpdateItem(transform2, k); + transform2.name = num13.ToString(); + } + else + { + flag = false; + } + } + else if (mFirstTime) + { + UpdateItem(transform2, k); + } + if (cullContent) + { + float num14 = num11; + Vector2 clipOffset2 = mPanel.clipOffset; + float y = clipOffset2.y; + Vector3 localPosition8 = mTrans.localPosition; + num11 = num14 + (y - localPosition8.y); + if (!UICamera.IsPressed(transform2.gameObject)) + { + NGUITools.SetActive(transform2.gameObject, num11 > num9 && num11 < num10, compatibilityMode: false); + } + } + } + } + mScroll.restrictWithinPanel = !flag; + } + + private void OnValidate() + { + if (maxIndex < minIndex) + { + maxIndex = minIndex; + } + if (minIndex > maxIndex) + { + maxIndex = minIndex; + } + } + + protected virtual void UpdateItem(Transform item, int index) + { + if (onInitializeItem != null) + { + int num; + if (mScroll.movement == UIScrollView.Movement.Vertical) + { + Vector3 localPosition = item.localPosition; + num = Mathf.RoundToInt(localPosition.y / (float)itemSize); + } + else + { + Vector3 localPosition2 = item.localPosition; + num = Mathf.RoundToInt(localPosition2.x / (float)itemSize); + } + int realIndex = num; + onInitializeItem(item.gameObject, index, realIndex); + } + } +} diff --git a/bin/Debug/Assembly-CSharp.dll b/bin/Debug/Assembly-CSharp.dll new file mode 100644 index 00000000..5e121d76 Binary files /dev/null and b/bin/Debug/Assembly-CSharp.dll differ diff --git a/iTween.cs b/iTween.cs new file mode 100644 index 00000000..1d02e774 --- /dev/null +++ b/iTween.cs @@ -0,0 +1,4830 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class iTween : MonoBehaviour +{ + public enum EaseType + { + easeInQuad, + easeOutQuad, + easeInOutQuad, + easeInCubic, + easeOutCubic, + easeInOutCubic, + easeInQuart, + easeOutQuart, + easeInOutQuart, + easeInQuint, + easeOutQuint, + easeInOutQuint, + easeInSine, + easeOutSine, + easeInOutSine, + easeInExpo, + easeOutExpo, + easeInOutExpo, + easeInCirc, + easeOutCirc, + easeInOutCirc, + linear, + spring, + easeInBounce, + easeOutBounce, + easeInOutBounce, + easeInBack, + easeOutBack, + easeInOutBack, + easeInElastic, + easeOutElastic, + easeInOutElastic, + punch + } + + public enum LoopType + { + none, + loop, + pingPong + } + + public enum NamedValueColor + { + _Color, + _SpecColor, + _Emission, + _ReflectColor + } + + public static class Defaults + { + public static float time = 1f; + + public static float delay = 0f; + + public static NamedValueColor namedColorValue = NamedValueColor._Color; + + public static LoopType loopType = LoopType.none; + + public static EaseType easeType = EaseType.easeOutExpo; + + public static float lookSpeed = 3f; + + public static bool isLocal = false; + + public static Space space = Space.Self; + + public static bool orientToPath = false; + + public static Color color = Color.white; + + public static float updateTimePercentage = 0.05f; + + public static float updateTime = 1f * updateTimePercentage; + + public static int cameraFadeDepth = 999999; + + public static float lookAhead = 0.05f; + + public static bool useRealTime = false; + + public static Vector3 up = Vector3.up; + } + + private class CRSpline + { + public Vector3[] pts; + + public CRSpline(params Vector3[] pts) + { + this.pts = new Vector3[pts.Length]; + Array.Copy(pts, this.pts, pts.Length); + } + + public Vector3 Interp(float t) + { + int num = pts.Length - 3; + int num2 = Mathf.Min(Mathf.FloorToInt(t * (float)num), num - 1); + float num3 = t * (float)num - (float)num2; + Vector3 a = pts[num2]; + Vector3 a2 = pts[num2 + 1]; + Vector3 vector = pts[num2 + 2]; + Vector3 b = pts[num2 + 3]; + return 0.5f * ((-a + 3f * a2 - 3f * vector + b) * (num3 * num3 * num3) + (2f * a - 5f * a2 + 4f * vector - b) * (num3 * num3) + (-a + vector) * num3 + 2f * a2); + } + } + + private delegate float EasingFunction(float start, float end, float Value); + + private delegate void ApplyTween(); + + public static List tweens = new List(); + + private static GameObject cameraFade; + + public string id; + + public string type; + + public string method; + + public EaseType easeType; + + public float time; + + public float delay; + + public LoopType loopType; + + public bool isRunning; + + public bool isPaused; + + public string _name; + + private float runningTime; + + private float percentage; + + private float delayStarted; + + private bool kinematic; + + private bool isLocal; + + private bool loop; + + private bool reverse; + + private bool wasPaused; + + private bool physics; + + private Hashtable tweenArguments; + + private Space space; + + private EasingFunction ease; + + private ApplyTween apply; + + private AudioSource audioSource; + + private Vector3[] vector3s; + + private Vector2[] vector2s; + + private Color[,] colors; + + private float[] floats; + + private Rect[] rects; + + private CRSpline path; + + private Vector3 preUpdate; + + private Vector3 postUpdate; + + private NamedValueColor namedcolorvalue; + + private float lastRealTime; + + private bool useRealTime; + + private Transform thisTransform; + + private iTween(Hashtable h) + { + tweenArguments = h; + } + + public static void Init(GameObject target) + { + MoveBy(target, Vector3.zero, 0f); + } + + public static void CameraFadeFrom(float amount, float time) + { + if ((bool)cameraFade) + { + CameraFadeFrom(Hash("amount", amount, "time", time)); + } + else + { + Debug.LogError("iTween Error: You must first add a camera fade object with CameraFadeAdd() before atttempting to use camera fading."); + } + } + + public static void CameraFadeFrom(Hashtable args) + { + if ((bool)cameraFade) + { + ColorFrom(cameraFade, args); + } + else + { + Debug.LogError("iTween Error: You must first add a camera fade object with CameraFadeAdd() before atttempting to use camera fading."); + } + } + + public static void CameraFadeTo(float amount, float time) + { + if ((bool)cameraFade) + { + CameraFadeTo(Hash("amount", amount, "time", time)); + } + else + { + Debug.LogError("iTween Error: You must first add a camera fade object with CameraFadeAdd() before atttempting to use camera fading."); + } + } + + public static void CameraFadeTo(Hashtable args) + { + if ((bool)cameraFade) + { + ColorTo(cameraFade, args); + } + else + { + Debug.LogError("iTween Error: You must first add a camera fade object with CameraFadeAdd() before atttempting to use camera fading."); + } + } + + public static void ValueTo(GameObject target, Hashtable args) + { + args = CleanArgs(args); + if (!args.Contains("onupdate") || !args.Contains("from") || !args.Contains("to")) + { + Debug.LogError("iTween Error: ValueTo() requires an 'onupdate' callback function and a 'from' and 'to' property. The supplied 'onupdate' callback must accept a single argument that is the same type as the supplied 'from' and 'to' properties!"); + } + else + { + args["type"] = "value"; + if (args["from"].GetType() == typeof(Vector2)) + { + args["method"] = "vector2"; + } + else if (args["from"].GetType() == typeof(Vector3)) + { + args["method"] = "vector3"; + } + else if (args["from"].GetType() == typeof(Rect)) + { + args["method"] = "rect"; + } + else if (args["from"].GetType() == typeof(float)) + { + args["method"] = "float"; + } + else + { + if (args["from"].GetType() != typeof(Color)) + { + Debug.LogError("iTween Error: ValueTo() only works with interpolating Vector3s, Vector2s, floats, ints, Rects and Colors!"); + return; + } + args["method"] = "color"; + } + if (!args.Contains("easetype")) + { + args.Add("easetype", EaseType.linear); + } + Launch(target, args); + } + } + + public static void FadeFrom(GameObject target, float alpha, float time) + { + FadeFrom(target, Hash("alpha", alpha, "time", time)); + } + + public static void FadeFrom(GameObject target, Hashtable args) + { + ColorFrom(target, args); + } + + public static void FadeTo(GameObject target, float alpha, float time) + { + FadeTo(target, Hash("alpha", alpha, "time", time)); + } + + public static void FadeTo(GameObject target, Hashtable args) + { + ColorTo(target, args); + } + + public static void ColorFrom(GameObject target, Color color, float time) + { + ColorFrom(target, Hash("color", color, "time", time)); + } + + public static void ColorFrom(GameObject target, Hashtable args) + { + Color color = default(Color); + Color color2 = default(Color); + args = CleanArgs(args); + if (!args.Contains("includechildren") || (bool)args["includechildren"]) + { + foreach (Transform item in target.transform) + { + Hashtable hashtable = (Hashtable)args.Clone(); + hashtable["ischild"] = true; + ColorFrom(item.gameObject, hashtable); + } + } + if (!args.Contains("easetype")) + { + args.Add("easetype", EaseType.linear); + } + if ((bool)target.GetComponent()) + { + color2 = (color = target.GetComponent().color); + } + else if ((bool)target.GetComponent()) + { + color2 = (color = target.GetComponent().material.color); + } + else if ((bool)target.GetComponent()) + { + color2 = (color = target.GetComponent().material.color); + } + else if ((bool)target.GetComponent()) + { + color2 = (color = target.GetComponent().color); + } + if (args.Contains("color")) + { + color = (Color)args["color"]; + } + else + { + if (args.Contains("r")) + { + color.r = (float)args["r"]; + } + if (args.Contains("g")) + { + color.g = (float)args["g"]; + } + if (args.Contains("b")) + { + color.b = (float)args["b"]; + } + if (args.Contains("a")) + { + color.a = (float)args["a"]; + } + } + if (args.Contains("amount")) + { + color.a = (float)args["amount"]; + args.Remove("amount"); + } + else if (args.Contains("alpha")) + { + color.a = (float)args["alpha"]; + args.Remove("alpha"); + } + if ((bool)target.GetComponent()) + { + target.GetComponent().color = color; + } + else if ((bool)target.GetComponent()) + { + target.GetComponent().material.color = color; + } + else if ((bool)target.GetComponent()) + { + target.GetComponent().material.color = color; + } + else if ((bool)target.GetComponent()) + { + target.GetComponent().color = color; + } + args["color"] = color2; + args["type"] = "color"; + args["method"] = "to"; + Launch(target, args); + } + + public static void ColorTo(GameObject target, Color color, float time) + { + ColorTo(target, Hash("color", color, "time", time)); + } + + public static void ColorTo(GameObject target, Hashtable args) + { + args = CleanArgs(args); + if (!args.Contains("includechildren") || (bool)args["includechildren"]) + { + foreach (Transform item in target.transform) + { + Hashtable hashtable = (Hashtable)args.Clone(); + hashtable["ischild"] = true; + ColorTo(item.gameObject, hashtable); + } + } + if (!args.Contains("easetype")) + { + args.Add("easetype", EaseType.linear); + } + args["type"] = "color"; + args["method"] = "to"; + Launch(target, args); + } + + public static void AudioFrom(GameObject target, float volume, float pitch, float time) + { + AudioFrom(target, Hash("volume", volume, "pitch", pitch, "time", time)); + } + + public static void AudioFrom(GameObject target, Hashtable args) + { + args = CleanArgs(args); + AudioSource audioSource; + if (args.Contains("audiosource")) + { + audioSource = (AudioSource)args["audiosource"]; + } + else + { + if (!(bool)target.GetComponent()) + { + Debug.LogError("iTween Error: AudioFrom requires an AudioSource."); + return; + } + audioSource = target.GetComponent(); + } + Vector2 vector = default(Vector2); + Vector2 vector2 = default(Vector2); + vector.x = (vector2.x = audioSource.volume); + vector.y = (vector2.y = audioSource.pitch); + if (args.Contains("volume")) + { + vector2.x = (float)args["volume"]; + } + if (args.Contains("pitch")) + { + vector2.y = (float)args["pitch"]; + } + audioSource.volume = vector2.x; + audioSource.pitch = vector2.y; + args["volume"] = vector.x; + args["pitch"] = vector.y; + if (!args.Contains("easetype")) + { + args.Add("easetype", EaseType.linear); + } + args["type"] = "audio"; + args["method"] = "to"; + Launch(target, args); + } + + public static void AudioTo(GameObject target, float volume, float pitch, float time) + { + AudioTo(target, Hash("volume", volume, "pitch", pitch, "time", time)); + } + + public static void AudioTo(GameObject target, Hashtable args) + { + args = CleanArgs(args); + if (!args.Contains("easetype")) + { + args.Add("easetype", EaseType.linear); + } + args["type"] = "audio"; + args["method"] = "to"; + Launch(target, args); + } + + public static void Stab(GameObject target, AudioClip audioclip, float delay) + { + Stab(target, Hash("audioclip", audioclip, "delay", delay)); + } + + public static void Stab(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "stab"; + Launch(target, args); + } + + public static void LookFrom(GameObject target, Vector3 looktarget, float time) + { + LookFrom(target, Hash("looktarget", looktarget, "time", time)); + } + + public static void LookFrom(GameObject target, Hashtable args) + { + args = CleanArgs(args); + Vector3 eulerAngles = target.transform.eulerAngles; + if (args["looktarget"].GetType() == typeof(Transform)) + { + Transform transform = target.transform; + Transform target2 = (Transform)args["looktarget"]; + Vector3? vector = (Vector3?)args["up"]; + transform.LookAt(target2, (!vector.HasValue) ? Defaults.up : vector.Value); + } + else if (args["looktarget"].GetType() == typeof(Vector3)) + { + Transform transform2 = target.transform; + Vector3 worldPosition = (Vector3)args["looktarget"]; + Vector3? vector2 = (Vector3?)args["up"]; + transform2.LookAt(worldPosition, (!vector2.HasValue) ? Defaults.up : vector2.Value); + } + if (args.Contains("axis")) + { + Vector3 eulerAngles2 = target.transform.eulerAngles; + switch ((string)args["axis"]) + { + case "x": + eulerAngles2.y = eulerAngles.y; + eulerAngles2.z = eulerAngles.z; + break; + case "y": + eulerAngles2.x = eulerAngles.x; + eulerAngles2.z = eulerAngles.z; + break; + case "z": + eulerAngles2.x = eulerAngles.x; + eulerAngles2.y = eulerAngles.y; + break; + } + target.transform.eulerAngles = eulerAngles2; + } + args["rotation"] = eulerAngles; + args["type"] = "rotate"; + args["method"] = "to"; + Launch(target, args); + } + + public static void LookTo(GameObject target, Vector3 looktarget, float time) + { + LookTo(target, Hash("looktarget", looktarget, "time", time)); + } + + public static void LookTo(GameObject target, Hashtable args) + { + args = CleanArgs(args); + if (args.Contains("looktarget") && args["looktarget"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["looktarget"]; + Hashtable hashtable = args; + Vector3 position = transform.position; + float x = position.x; + Vector3 position2 = transform.position; + float y = position2.y; + Vector3 position3 = transform.position; + hashtable["position"] = new Vector3(x, y, position3.z); + Hashtable hashtable2 = args; + Vector3 eulerAngles = transform.eulerAngles; + float x2 = eulerAngles.x; + Vector3 eulerAngles2 = transform.eulerAngles; + float y2 = eulerAngles2.y; + Vector3 eulerAngles3 = transform.eulerAngles; + hashtable2["rotation"] = new Vector3(x2, y2, eulerAngles3.z); + } + args["type"] = "look"; + args["method"] = "to"; + Launch(target, args); + } + + public static void MoveTo(GameObject target, Vector3 position, float time) + { + MoveTo(target, Hash("position", position, "time", time)); + } + + public static void MoveTo(GameObject target, Hashtable args) + { + args = CleanArgs(args); + if (args.Contains("position") && args["position"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["position"]; + Hashtable hashtable = args; + Vector3 position = transform.position; + float x = position.x; + Vector3 position2 = transform.position; + float y = position2.y; + Vector3 position3 = transform.position; + hashtable["position"] = new Vector3(x, y, position3.z); + Hashtable hashtable2 = args; + Vector3 eulerAngles = transform.eulerAngles; + float x2 = eulerAngles.x; + Vector3 eulerAngles2 = transform.eulerAngles; + float y2 = eulerAngles2.y; + Vector3 eulerAngles3 = transform.eulerAngles; + hashtable2["rotation"] = new Vector3(x2, y2, eulerAngles3.z); + Hashtable hashtable3 = args; + Vector3 localScale = transform.localScale; + float x3 = localScale.x; + Vector3 localScale2 = transform.localScale; + float y3 = localScale2.y; + Vector3 localScale3 = transform.localScale; + hashtable3["scale"] = new Vector3(x3, y3, localScale3.z); + } + args["type"] = "move"; + args["method"] = "to"; + Launch(target, args); + } + + public static void MoveFrom(GameObject target, Vector3 position, float time) + { + MoveFrom(target, Hash("position", position, "time", time)); + } + + public static void MoveFrom(GameObject target, Hashtable args) + { + args = CleanArgs(args); + bool flag = (!args.Contains("islocal")) ? Defaults.isLocal : ((bool)args["islocal"]); + if (args.Contains("path")) + { + Vector3[] array2; + if (args["path"].GetType() == typeof(Vector3[])) + { + Vector3[] array = (Vector3[])args["path"]; + array2 = new Vector3[array.Length]; + Array.Copy(array, array2, array.Length); + } + else + { + Transform[] array3 = (Transform[])args["path"]; + array2 = new Vector3[array3.Length]; + for (int i = 0; i < array3.Length; i++) + { + array2[i] = array3[i].position; + } + } + if (array2[array2.Length - 1] != target.transform.position) + { + Vector3[] array4 = new Vector3[array2.Length + 1]; + Array.Copy(array2, array4, array2.Length); + if (flag) + { + array4[array4.Length - 1] = target.transform.localPosition; + target.transform.localPosition = array4[0]; + } + else + { + array4[array4.Length - 1] = target.transform.position; + target.transform.position = array4[0]; + } + args["path"] = array4; + } + else + { + if (flag) + { + target.transform.localPosition = array2[0]; + } + else + { + target.transform.position = array2[0]; + } + args["path"] = array2; + } + } + else + { + Vector3 vector; + Vector3 vector2 = (!flag) ? (vector = target.transform.position) : (vector = target.transform.localPosition); + if (args.Contains("position")) + { + if (args["position"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["position"]; + vector = transform.position; + } + else if (args["position"].GetType() == typeof(Vector3)) + { + vector = (Vector3)args["position"]; + } + } + else + { + if (args.Contains("x")) + { + vector.x = (float)args["x"]; + } + if (args.Contains("y")) + { + vector.y = (float)args["y"]; + } + if (args.Contains("z")) + { + vector.z = (float)args["z"]; + } + } + if (flag) + { + target.transform.localPosition = vector; + } + else + { + target.transform.position = vector; + } + args["position"] = vector2; + } + args["type"] = "move"; + args["method"] = "to"; + Launch(target, args); + } + + public static void MoveAdd(GameObject target, Vector3 amount, float time) + { + MoveAdd(target, Hash("amount", amount, "time", time)); + } + + public static void MoveAdd(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "move"; + args["method"] = "add"; + Launch(target, args); + } + + public static void MoveBy(GameObject target, Vector3 amount, float time) + { + MoveBy(target, Hash("amount", amount, "time", time)); + } + + public static void MoveBy(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "move"; + args["method"] = "by"; + Launch(target, args); + } + + public static void ScaleTo(GameObject target, Vector3 scale, float time) + { + ScaleTo(target, Hash("scale", scale, "time", time)); + } + + public static void ScaleTo(GameObject target, Hashtable args) + { + args = CleanArgs(args); + if (args.Contains("scale") && args["scale"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["scale"]; + Hashtable hashtable = args; + Vector3 position = transform.position; + float x = position.x; + Vector3 position2 = transform.position; + float y = position2.y; + Vector3 position3 = transform.position; + hashtable["position"] = new Vector3(x, y, position3.z); + Hashtable hashtable2 = args; + Vector3 eulerAngles = transform.eulerAngles; + float x2 = eulerAngles.x; + Vector3 eulerAngles2 = transform.eulerAngles; + float y2 = eulerAngles2.y; + Vector3 eulerAngles3 = transform.eulerAngles; + hashtable2["rotation"] = new Vector3(x2, y2, eulerAngles3.z); + Hashtable hashtable3 = args; + Vector3 localScale = transform.localScale; + float x3 = localScale.x; + Vector3 localScale2 = transform.localScale; + float y3 = localScale2.y; + Vector3 localScale3 = transform.localScale; + hashtable3["scale"] = new Vector3(x3, y3, localScale3.z); + } + args["type"] = "scale"; + args["method"] = "to"; + Launch(target, args); + } + + public static void ScaleFrom(GameObject target, Vector3 scale, float time) + { + ScaleFrom(target, Hash("scale", scale, "time", time)); + } + + public static void ScaleFrom(GameObject target, Hashtable args) + { + args = CleanArgs(args); + Vector3 localScale; + Vector3 vector = localScale = target.transform.localScale; + if (args.Contains("scale")) + { + if (args["scale"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["scale"]; + localScale = transform.localScale; + } + else if (args["scale"].GetType() == typeof(Vector3)) + { + localScale = (Vector3)args["scale"]; + } + } + else + { + if (args.Contains("x")) + { + localScale.x = (float)args["x"]; + } + if (args.Contains("y")) + { + localScale.y = (float)args["y"]; + } + if (args.Contains("z")) + { + localScale.z = (float)args["z"]; + } + } + target.transform.localScale = localScale; + args["scale"] = vector; + args["type"] = "scale"; + args["method"] = "to"; + Launch(target, args); + } + + public static void ScaleAdd(GameObject target, Vector3 amount, float time) + { + ScaleAdd(target, Hash("amount", amount, "time", time)); + } + + public static void ScaleAdd(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "scale"; + args["method"] = "add"; + Launch(target, args); + } + + public static void ScaleBy(GameObject target, Vector3 amount, float time) + { + ScaleBy(target, Hash("amount", amount, "time", time)); + } + + public static void ScaleBy(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "scale"; + args["method"] = "by"; + Launch(target, args); + } + + public static void RotateTo(GameObject target, Vector3 rotation, float time) + { + RotateTo(target, Hash("rotation", rotation, "time", time)); + } + + public static void RotateTo(GameObject target, Hashtable args) + { + args = CleanArgs(args); + if (args.Contains("rotation") && args["rotation"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["rotation"]; + Hashtable hashtable = args; + Vector3 position = transform.position; + float x = position.x; + Vector3 position2 = transform.position; + float y = position2.y; + Vector3 position3 = transform.position; + hashtable["position"] = new Vector3(x, y, position3.z); + Hashtable hashtable2 = args; + Vector3 eulerAngles = transform.eulerAngles; + float x2 = eulerAngles.x; + Vector3 eulerAngles2 = transform.eulerAngles; + float y2 = eulerAngles2.y; + Vector3 eulerAngles3 = transform.eulerAngles; + hashtable2["rotation"] = new Vector3(x2, y2, eulerAngles3.z); + Hashtable hashtable3 = args; + Vector3 localScale = transform.localScale; + float x3 = localScale.x; + Vector3 localScale2 = transform.localScale; + float y3 = localScale2.y; + Vector3 localScale3 = transform.localScale; + hashtable3["scale"] = new Vector3(x3, y3, localScale3.z); + } + args["type"] = "rotate"; + args["method"] = "to"; + Launch(target, args); + } + + public static void RotateFrom(GameObject target, Vector3 rotation, float time) + { + RotateFrom(target, Hash("rotation", rotation, "time", time)); + } + + public static void RotateFrom(GameObject target, Hashtable args) + { + args = CleanArgs(args); + bool flag = (!args.Contains("islocal")) ? Defaults.isLocal : ((bool)args["islocal"]); + Vector3 vector; + Vector3 vector2 = (!flag) ? (vector = target.transform.eulerAngles) : (vector = target.transform.localEulerAngles); + if (args.Contains("rotation")) + { + if (args["rotation"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["rotation"]; + vector = transform.eulerAngles; + } + else if (args["rotation"].GetType() == typeof(Vector3)) + { + vector = (Vector3)args["rotation"]; + } + } + else + { + if (args.Contains("x")) + { + vector.x = (float)args["x"]; + } + if (args.Contains("y")) + { + vector.y = (float)args["y"]; + } + if (args.Contains("z")) + { + vector.z = (float)args["z"]; + } + } + if (flag) + { + target.transform.localEulerAngles = vector; + } + else + { + target.transform.eulerAngles = vector; + } + args["rotation"] = vector2; + args["type"] = "rotate"; + args["method"] = "to"; + Launch(target, args); + } + + public static void RotateAdd(GameObject target, Vector3 amount, float time) + { + RotateAdd(target, Hash("amount", amount, "time", time)); + } + + public static void RotateAdd(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "rotate"; + args["method"] = "add"; + Launch(target, args); + } + + public static void RotateBy(GameObject target, Vector3 amount, float time) + { + RotateBy(target, Hash("amount", amount, "time", time)); + } + + public static void RotateBy(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "rotate"; + args["method"] = "by"; + Launch(target, args); + } + + public static void ShakePosition(GameObject target, Vector3 amount, float time) + { + ShakePosition(target, Hash("amount", amount, "time", time)); + } + + public static void ShakePosition(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "shake"; + args["method"] = "position"; + Launch(target, args); + } + + public static void ShakeScale(GameObject target, Vector3 amount, float time) + { + ShakeScale(target, Hash("amount", amount, "time", time)); + } + + public static void ShakeScale(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "shake"; + args["method"] = "scale"; + Launch(target, args); + } + + public static void ShakeRotation(GameObject target, Vector3 amount, float time) + { + ShakeRotation(target, Hash("amount", amount, "time", time)); + } + + public static void ShakeRotation(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "shake"; + args["method"] = "rotation"; + Launch(target, args); + } + + public static void PunchPosition(GameObject target, Vector3 amount, float time) + { + PunchPosition(target, Hash("amount", amount, "time", time)); + } + + public static void PunchPosition(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "punch"; + args["method"] = "position"; + args["easetype"] = EaseType.punch; + Launch(target, args); + } + + public static void PunchRotation(GameObject target, Vector3 amount, float time) + { + PunchRotation(target, Hash("amount", amount, "time", time)); + } + + public static void PunchRotation(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "punch"; + args["method"] = "rotation"; + args["easetype"] = EaseType.punch; + Launch(target, args); + } + + public static void PunchScale(GameObject target, Vector3 amount, float time) + { + PunchScale(target, Hash("amount", amount, "time", time)); + } + + public static void PunchScale(GameObject target, Hashtable args) + { + args = CleanArgs(args); + args["type"] = "punch"; + args["method"] = "scale"; + args["easetype"] = EaseType.punch; + Launch(target, args); + } + + private void GenerateTargets() + { + switch (type) + { + case "value": + switch (method) + { + case "float": + GenerateFloatTargets(); + apply = ApplyFloatTargets; + break; + case "vector2": + GenerateVector2Targets(); + apply = ApplyVector2Targets; + break; + case "vector3": + GenerateVector3Targets(); + apply = ApplyVector3Targets; + break; + case "color": + GenerateColorTargets(); + apply = ApplyColorTargets; + break; + case "rect": + GenerateRectTargets(); + apply = ApplyRectTargets; + break; + } + break; + case "color": + switch (method) + { + case "to": + GenerateColorToTargets(); + apply = ApplyColorToTargets; + break; + } + break; + case "audio": + switch (method) + { + case "to": + GenerateAudioToTargets(); + apply = ApplyAudioToTargets; + break; + } + break; + case "move": + switch (method) + { + case "to": + if (tweenArguments.Contains("path")) + { + GenerateMoveToPathTargets(); + apply = ApplyMoveToPathTargets; + } + else + { + GenerateMoveToTargets(); + apply = ApplyMoveToTargets; + } + break; + case "by": + case "add": + GenerateMoveByTargets(); + apply = ApplyMoveByTargets; + break; + } + break; + case "scale": + switch (method) + { + case "to": + GenerateScaleToTargets(); + apply = ApplyScaleToTargets; + break; + case "by": + GenerateScaleByTargets(); + apply = ApplyScaleToTargets; + break; + case "add": + GenerateScaleAddTargets(); + apply = ApplyScaleToTargets; + break; + } + break; + case "rotate": + switch (method) + { + case "to": + GenerateRotateToTargets(); + apply = ApplyRotateToTargets; + break; + case "add": + GenerateRotateAddTargets(); + apply = ApplyRotateAddTargets; + break; + case "by": + GenerateRotateByTargets(); + apply = ApplyRotateAddTargets; + break; + } + break; + case "shake": + switch (method) + { + case "position": + GenerateShakePositionTargets(); + apply = ApplyShakePositionTargets; + break; + case "scale": + GenerateShakeScaleTargets(); + apply = ApplyShakeScaleTargets; + break; + case "rotation": + GenerateShakeRotationTargets(); + apply = ApplyShakeRotationTargets; + break; + } + break; + case "punch": + switch (method) + { + case "position": + GeneratePunchPositionTargets(); + apply = ApplyPunchPositionTargets; + break; + case "rotation": + GeneratePunchRotationTargets(); + apply = ApplyPunchRotationTargets; + break; + case "scale": + GeneratePunchScaleTargets(); + apply = ApplyPunchScaleTargets; + break; + } + break; + case "look": + switch (method) + { + case "to": + GenerateLookToTargets(); + apply = ApplyLookToTargets; + break; + } + break; + case "stab": + GenerateStabTargets(); + apply = ApplyStabTargets; + break; + } + } + + private void GenerateRectTargets() + { + rects = new Rect[3]; + rects[0] = (Rect)tweenArguments["from"]; + rects[1] = (Rect)tweenArguments["to"]; + } + + private void GenerateColorTargets() + { + colors = new Color[1, 3]; + Color[,] array = colors; + Color obj = (Color)tweenArguments["from"]; + array[0, 0] = obj; + Color[,] array2 = colors; + Color obj2 = (Color)tweenArguments["to"]; + array2[0, 1] = obj2; + } + + private void GenerateVector3Targets() + { + vector3s = new Vector3[3]; + vector3s[0] = (Vector3)tweenArguments["from"]; + vector3s[1] = (Vector3)tweenArguments["to"]; + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateVector2Targets() + { + vector2s = new Vector2[3]; + vector2s[0] = (Vector2)tweenArguments["from"]; + vector2s[1] = (Vector2)tweenArguments["to"]; + if (tweenArguments.Contains("speed")) + { + Vector3 a = new Vector3(vector2s[0].x, vector2s[0].y, 0f); + Vector3 b = new Vector3(vector2s[1].x, vector2s[1].y, 0f); + float num = Math.Abs(Vector3.Distance(a, b)); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateFloatTargets() + { + floats = new float[3]; + floats[0] = (float)tweenArguments["from"]; + floats[1] = (float)tweenArguments["to"]; + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(floats[0] - floats[1]); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateColorToTargets() + { + if ((bool)GetComponent()) + { + colors = new Color[1, 3]; + Color[,] array = colors; + Color[,] array2 = colors; + Color color; + Color color2 = color = GetComponent().color; + array2[0, 1] = color2; + array[0, 0] = color; + } + else if ((bool)GetComponent()) + { + colors = new Color[1, 3]; + Color[,] array3 = colors; + Color[,] array4 = colors; + Color color; + Color color3 = color = GetComponent().material.color; + array4[0, 1] = color3; + array3[0, 0] = color; + } + else if ((bool)GetComponent()) + { + colors = new Color[GetComponent().materials.Length, 3]; + for (int i = 0; i < GetComponent().materials.Length; i++) + { + Color[,] array5 = colors; + int num = i; + Color color4 = GetComponent().materials[i].GetColor(namedcolorvalue.ToString()); + array5[num, 0] = color4; + Color[,] array6 = colors; + int num2 = i; + Color color5 = GetComponent().materials[i].GetColor(namedcolorvalue.ToString()); + array6[num2, 1] = color5; + } + } + else if ((bool)GetComponent()) + { + colors = new Color[1, 3]; + Color[,] array7 = colors; + Color[,] array8 = colors; + Color color; + Color color6 = color = GetComponent().color; + array8[0, 1] = color6; + array7[0, 0] = color; + } + else + { + colors = new Color[1, 3]; + } + if (tweenArguments.Contains("color")) + { + for (int j = 0; j < colors.GetLength(0); j++) + { + Color[,] array9 = colors; + int num3 = j; + Color obj = (Color)tweenArguments["color"]; + array9[num3, 1] = obj; + } + } + else + { + if (tweenArguments.Contains("r")) + { + for (int k = 0; k < colors.GetLength(0); k++) + { + colors[k, 1].r = (float)tweenArguments["r"]; + } + } + if (tweenArguments.Contains("g")) + { + for (int l = 0; l < colors.GetLength(0); l++) + { + colors[l, 1].g = (float)tweenArguments["g"]; + } + } + if (tweenArguments.Contains("b")) + { + for (int m = 0; m < colors.GetLength(0); m++) + { + colors[m, 1].b = (float)tweenArguments["b"]; + } + } + if (tweenArguments.Contains("a")) + { + for (int n = 0; n < colors.GetLength(0); n++) + { + colors[n, 1].a = (float)tweenArguments["a"]; + } + } + } + if (tweenArguments.Contains("amount")) + { + for (int num4 = 0; num4 < colors.GetLength(0); num4++) + { + colors[num4, 1].a = (float)tweenArguments["amount"]; + } + } + else if (tweenArguments.Contains("alpha")) + { + for (int num5 = 0; num5 < colors.GetLength(0); num5++) + { + colors[num5, 1].a = (float)tweenArguments["alpha"]; + } + } + } + + private void GenerateAudioToTargets() + { + vector2s = new Vector2[3]; + if (tweenArguments.Contains("audiosource")) + { + audioSource = (AudioSource)tweenArguments["audiosource"]; + } + else if ((bool)GetComponent()) + { + audioSource = GetComponent(); + } + else + { + Debug.LogError("iTween Error: AudioTo requires an AudioSource."); + Dispose(); + } + vector2s[0] = (vector2s[1] = new Vector2(audioSource.volume, audioSource.pitch)); + if (tweenArguments.Contains("volume")) + { + vector2s[1].x = (float)tweenArguments["volume"]; + } + if (tweenArguments.Contains("pitch")) + { + vector2s[1].y = (float)tweenArguments["pitch"]; + } + } + + private void GenerateStabTargets() + { + if (tweenArguments.Contains("audiosource")) + { + audioSource = (AudioSource)tweenArguments["audiosource"]; + } + else if ((bool)GetComponent()) + { + audioSource = GetComponent(); + } + else + { + base.gameObject.AddComponent(); + audioSource = GetComponent(); + audioSource.playOnAwake = false; + } + audioSource.clip = (AudioClip)tweenArguments["audioclip"]; + if (tweenArguments.Contains("pitch")) + { + audioSource.pitch = (float)tweenArguments["pitch"]; + } + if (tweenArguments.Contains("volume")) + { + audioSource.volume = (float)tweenArguments["volume"]; + } + time = audioSource.clip.length / audioSource.pitch; + } + + private void GenerateLookToTargets() + { + vector3s = new Vector3[3]; + vector3s[0] = thisTransform.eulerAngles; + if (tweenArguments.Contains("looktarget")) + { + if (tweenArguments["looktarget"].GetType() == typeof(Transform)) + { + Transform transform = thisTransform; + Transform target = (Transform)tweenArguments["looktarget"]; + Vector3? vector = (Vector3?)tweenArguments["up"]; + transform.LookAt(target, (!vector.HasValue) ? Defaults.up : vector.Value); + } + else if (tweenArguments["looktarget"].GetType() == typeof(Vector3)) + { + Transform transform2 = thisTransform; + Vector3 worldPosition = (Vector3)tweenArguments["looktarget"]; + Vector3? vector2 = (Vector3?)tweenArguments["up"]; + transform2.LookAt(worldPosition, (!vector2.HasValue) ? Defaults.up : vector2.Value); + } + } + else + { + Debug.LogError("iTween Error: LookTo needs a 'looktarget' property!"); + Dispose(); + } + vector3s[1] = thisTransform.eulerAngles; + thisTransform.eulerAngles = vector3s[0]; + if (tweenArguments.Contains("axis")) + { + switch ((string)tweenArguments["axis"]) + { + case "x": + vector3s[1].y = vector3s[0].y; + vector3s[1].z = vector3s[0].z; + break; + case "y": + vector3s[1].x = vector3s[0].x; + vector3s[1].z = vector3s[0].z; + break; + case "z": + vector3s[1].x = vector3s[0].x; + vector3s[1].y = vector3s[0].y; + break; + } + } + vector3s[1] = new Vector3(clerp(vector3s[0].x, vector3s[1].x, 1f), clerp(vector3s[0].y, vector3s[1].y, 1f), clerp(vector3s[0].z, vector3s[1].z, 1f)); + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateMoveToPathTargets() + { + Vector3[] array2; + if (tweenArguments["path"].GetType() == typeof(Vector3[])) + { + Vector3[] array = (Vector3[])tweenArguments["path"]; + if (array.Length == 1) + { + Debug.LogError("iTween Error: Attempting a path movement with MoveTo requires an array of more than 1 entry!"); + Dispose(); + } + array2 = new Vector3[array.Length]; + Array.Copy(array, array2, array.Length); + } + else + { + Transform[] array3 = (Transform[])tweenArguments["path"]; + if (array3.Length == 1) + { + Debug.LogError("iTween Error: Attempting a path movement with MoveTo requires an array of more than 1 entry!"); + Dispose(); + } + array2 = new Vector3[array3.Length]; + for (int i = 0; i < array3.Length; i++) + { + array2[i] = array3[i].position; + } + } + bool flag; + int num; + if (thisTransform.position != array2[0]) + { + if (!tweenArguments.Contains("movetopath") || (bool)tweenArguments["movetopath"]) + { + flag = true; + num = 3; + } + else + { + flag = false; + num = 2; + } + } + else + { + flag = false; + num = 2; + } + vector3s = new Vector3[array2.Length + num]; + if (flag) + { + vector3s[1] = thisTransform.position; + num = 2; + } + else + { + num = 1; + } + Array.Copy(array2, 0, vector3s, num, array2.Length); + vector3s[0] = vector3s[1] + (vector3s[1] - vector3s[2]); + vector3s[vector3s.Length - 1] = vector3s[vector3s.Length - 2] + (vector3s[vector3s.Length - 2] - vector3s[vector3s.Length - 3]); + if (vector3s[1] == vector3s[vector3s.Length - 2]) + { + Vector3[] array4 = new Vector3[vector3s.Length]; + Array.Copy(vector3s, array4, vector3s.Length); + array4[0] = array4[array4.Length - 3]; + array4[array4.Length - 1] = array4[2]; + vector3s = new Vector3[array4.Length]; + Array.Copy(array4, vector3s, array4.Length); + } + path = new CRSpline(vector3s); + if (tweenArguments.Contains("speed")) + { + float num2 = PathLength(vector3s); + time = num2 / (float)tweenArguments["speed"]; + } + } + + private void GenerateMoveToTargets() + { + vector3s = new Vector3[3]; + if (isLocal) + { + vector3s[0] = (vector3s[1] = thisTransform.localPosition); + } + else + { + vector3s[0] = (vector3s[1] = thisTransform.position); + } + if (tweenArguments.Contains("position")) + { + if (tweenArguments["position"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)tweenArguments["position"]; + vector3s[1] = transform.position; + } + else if (tweenArguments["position"].GetType() == typeof(Vector3)) + { + vector3s[1] = (Vector3)tweenArguments["position"]; + } + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + if (tweenArguments.Contains("orienttopath") && (bool)tweenArguments["orienttopath"]) + { + tweenArguments["looktarget"] = vector3s[1]; + } + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateMoveByTargets() + { + vector3s = new Vector3[6]; + vector3s[4] = thisTransform.eulerAngles; + vector3s[0] = (vector3s[1] = (vector3s[3] = thisTransform.position)); + if (tweenArguments.Contains("amount")) + { + vector3s[1] = vector3s[0] + (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = vector3s[0].x + (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = vector3s[0].y + (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = vector3s[0].z + (float)tweenArguments["z"]; + } + } + thisTransform.Translate(vector3s[1], space); + vector3s[5] = thisTransform.position; + thisTransform.position = vector3s[0]; + if (tweenArguments.Contains("orienttopath") && (bool)tweenArguments["orienttopath"]) + { + tweenArguments["looktarget"] = vector3s[1]; + } + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateScaleToTargets() + { + vector3s = new Vector3[3]; + vector3s[0] = (vector3s[1] = thisTransform.localScale); + if (tweenArguments.Contains("scale")) + { + if (tweenArguments["scale"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)tweenArguments["scale"]; + vector3s[1] = transform.localScale; + } + else if (tweenArguments["scale"].GetType() == typeof(Vector3)) + { + vector3s[1] = (Vector3)tweenArguments["scale"]; + } + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateScaleByTargets() + { + vector3s = new Vector3[3]; + vector3s[0] = (vector3s[1] = thisTransform.localScale); + if (tweenArguments.Contains("amount")) + { + vector3s[1] = Vector3.Scale(vector3s[1], (Vector3)tweenArguments["amount"]); + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x *= (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y *= (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z *= (float)tweenArguments["z"]; + } + } + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateScaleAddTargets() + { + vector3s = new Vector3[3]; + vector3s[0] = (vector3s[1] = thisTransform.localScale); + if (tweenArguments.Contains("amount")) + { + vector3s[1] += (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x += (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y += (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z += (float)tweenArguments["z"]; + } + } + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateRotateToTargets() + { + vector3s = new Vector3[3]; + if (isLocal) + { + vector3s[0] = (vector3s[1] = thisTransform.localEulerAngles); + } + else + { + vector3s[0] = (vector3s[1] = thisTransform.eulerAngles); + } + if (tweenArguments.Contains("rotation")) + { + if (tweenArguments["rotation"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)tweenArguments["rotation"]; + vector3s[1] = transform.eulerAngles; + } + else if (tweenArguments["rotation"].GetType() == typeof(Vector3)) + { + vector3s[1] = (Vector3)tweenArguments["rotation"]; + } + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + vector3s[1] = new Vector3(clerp(vector3s[0].x, vector3s[1].x, 1f), clerp(vector3s[0].y, vector3s[1].y, 1f), clerp(vector3s[0].z, vector3s[1].z, 1f)); + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateRotateAddTargets() + { + vector3s = new Vector3[5]; + vector3s[0] = (vector3s[1] = (vector3s[3] = thisTransform.eulerAngles)); + if (tweenArguments.Contains("amount")) + { + vector3s[1] += (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x += (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y += (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z += (float)tweenArguments["z"]; + } + } + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateRotateByTargets() + { + vector3s = new Vector3[4]; + vector3s[0] = (vector3s[1] = (vector3s[3] = thisTransform.eulerAngles)); + if (tweenArguments.Contains("amount")) + { + vector3s[1] += Vector3.Scale((Vector3)tweenArguments["amount"], new Vector3(360f, 360f, 360f)); + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x += 360f * (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y += 360f * (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z += 360f * (float)tweenArguments["z"]; + } + } + if (tweenArguments.Contains("speed")) + { + float num = Math.Abs(Vector3.Distance(vector3s[0], vector3s[1])); + time = num / (float)tweenArguments["speed"]; + } + } + + private void GenerateShakePositionTargets() + { + vector3s = new Vector3[4]; + vector3s[3] = thisTransform.eulerAngles; + vector3s[0] = thisTransform.position; + if (tweenArguments.Contains("amount")) + { + vector3s[1] = (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + } + + private void GenerateShakeScaleTargets() + { + vector3s = new Vector3[3]; + vector3s[0] = thisTransform.localScale; + if (tweenArguments.Contains("amount")) + { + vector3s[1] = (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + } + + private void GenerateShakeRotationTargets() + { + vector3s = new Vector3[3]; + vector3s[0] = thisTransform.eulerAngles; + if (tweenArguments.Contains("amount")) + { + vector3s[1] = (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + } + + private void GeneratePunchPositionTargets() + { + vector3s = new Vector3[5]; + vector3s[4] = thisTransform.eulerAngles; + vector3s[0] = thisTransform.position; + vector3s[1] = (vector3s[3] = Vector3.zero); + if (tweenArguments.Contains("amount")) + { + vector3s[1] = (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + } + + private void GeneratePunchRotationTargets() + { + vector3s = new Vector3[4]; + vector3s[0] = thisTransform.eulerAngles; + vector3s[1] = (vector3s[3] = Vector3.zero); + if (tweenArguments.Contains("amount")) + { + vector3s[1] = (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + } + + private void GeneratePunchScaleTargets() + { + vector3s = new Vector3[3]; + vector3s[0] = thisTransform.localScale; + vector3s[1] = Vector3.zero; + if (tweenArguments.Contains("amount")) + { + vector3s[1] = (Vector3)tweenArguments["amount"]; + } + else + { + if (tweenArguments.Contains("x")) + { + vector3s[1].x = (float)tweenArguments["x"]; + } + if (tweenArguments.Contains("y")) + { + vector3s[1].y = (float)tweenArguments["y"]; + } + if (tweenArguments.Contains("z")) + { + vector3s[1].z = (float)tweenArguments["z"]; + } + } + } + + private void ApplyRectTargets() + { + rects[2].x = ease(rects[0].x, rects[1].x, percentage); + rects[2].y = ease(rects[0].y, rects[1].y, percentage); + rects[2].width = ease(rects[0].width, rects[1].width, percentage); + rects[2].height = ease(rects[0].height, rects[1].height, percentage); + tweenArguments["onupdateparams"] = rects[2]; + if (percentage == 1f) + { + tweenArguments["onupdateparams"] = rects[1]; + } + } + + private void ApplyColorTargets() + { + colors[0, 2].r = ease(colors[0, 0].r, colors[0, 1].r, percentage); + colors[0, 2].g = ease(colors[0, 0].g, colors[0, 1].g, percentage); + colors[0, 2].b = ease(colors[0, 0].b, colors[0, 1].b, percentage); + colors[0, 2].a = ease(colors[0, 0].a, colors[0, 1].a, percentage); + tweenArguments["onupdateparams"] = colors[0, 2]; + if (percentage == 1f) + { + tweenArguments["onupdateparams"] = colors[0, 1]; + } + } + + private void ApplyVector3Targets() + { + vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); + vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); + vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); + tweenArguments["onupdateparams"] = vector3s[2]; + if (percentage == 1f) + { + tweenArguments["onupdateparams"] = vector3s[1]; + } + } + + private void ApplyVector2Targets() + { + vector2s[2].x = ease(vector2s[0].x, vector2s[1].x, percentage); + vector2s[2].y = ease(vector2s[0].y, vector2s[1].y, percentage); + tweenArguments["onupdateparams"] = vector2s[2]; + if (percentage == 1f) + { + tweenArguments["onupdateparams"] = vector2s[1]; + } + } + + private void ApplyFloatTargets() + { + floats[2] = ease(floats[0], floats[1], percentage); + tweenArguments["onupdateparams"] = floats[2]; + if (percentage == 1f) + { + tweenArguments["onupdateparams"] = floats[1]; + } + } + + private void ApplyColorToTargets() + { + for (int i = 0; i < colors.GetLength(0); i++) + { + colors[i, 2].r = ease(colors[i, 0].r, colors[i, 1].r, percentage); + colors[i, 2].g = ease(colors[i, 0].g, colors[i, 1].g, percentage); + colors[i, 2].b = ease(colors[i, 0].b, colors[i, 1].b, percentage); + colors[i, 2].a = ease(colors[i, 0].a, colors[i, 1].a, percentage); + } + if ((bool)GetComponent()) + { + GetComponent().color = colors[0, 2]; + } + else if ((bool)GetComponent()) + { + GetComponent().material.color = colors[0, 2]; + } + else if ((bool)GetComponent()) + { + for (int j = 0; j < colors.GetLength(0); j++) + { + GetComponent().materials[j].SetColor(namedcolorvalue.ToString(), colors[j, 2]); + } + } + else if ((bool)GetComponent()) + { + GetComponent().color = colors[0, 2]; + } + if (percentage == 1f) + { + if ((bool)GetComponent()) + { + GetComponent().color = colors[0, 1]; + } + else if ((bool)GetComponent()) + { + GetComponent().material.color = colors[0, 1]; + } + else if ((bool)GetComponent()) + { + for (int k = 0; k < colors.GetLength(0); k++) + { + GetComponent().materials[k].SetColor(namedcolorvalue.ToString(), colors[k, 1]); + } + } + else if ((bool)GetComponent()) + { + GetComponent().color = colors[0, 1]; + } + } + } + + private void ApplyAudioToTargets() + { + vector2s[2].x = ease(vector2s[0].x, vector2s[1].x, percentage); + vector2s[2].y = ease(vector2s[0].y, vector2s[1].y, percentage); + audioSource.volume = vector2s[2].x; + audioSource.pitch = vector2s[2].y; + if (percentage == 1f) + { + audioSource.volume = vector2s[1].x; + audioSource.pitch = vector2s[1].y; + } + } + + private void ApplyStabTargets() + { + } + + private void ApplyMoveToPathTargets() + { + preUpdate = thisTransform.position; + float value = ease(0f, 1f, percentage); + if (isLocal) + { + thisTransform.localPosition = path.Interp(Mathf.Clamp(value, 0f, 1f)); + } + else + { + thisTransform.position = path.Interp(Mathf.Clamp(value, 0f, 1f)); + } + if (tweenArguments.Contains("orienttopath") && (bool)tweenArguments["orienttopath"]) + { + float num = (!tweenArguments.Contains("lookahead")) ? Defaults.lookAhead : ((float)tweenArguments["lookahead"]); + float value2 = ease(0f, 1f, Mathf.Min(1f, percentage + num)); + tweenArguments["looktarget"] = path.Interp(Mathf.Clamp(value2, 0f, 1f)); + } + postUpdate = thisTransform.position; + if (physics) + { + thisTransform.position = preUpdate; + GetComponent().MovePosition(postUpdate); + } + } + + private void ApplyMoveToTargets() + { + preUpdate = thisTransform.position; + vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); + vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); + vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); + if (isLocal) + { + thisTransform.localPosition = vector3s[2]; + } + else + { + thisTransform.position = vector3s[2]; + } + if (percentage == 1f) + { + if (isLocal) + { + thisTransform.localPosition = vector3s[1]; + } + else + { + thisTransform.position = vector3s[1]; + } + } + postUpdate = thisTransform.position; + if (physics) + { + thisTransform.position = preUpdate; + GetComponent().MovePosition(postUpdate); + } + } + + private void ApplyMoveByTargets() + { + preUpdate = thisTransform.position; + Vector3 eulerAngles = default(Vector3); + if (tweenArguments.Contains("looktarget")) + { + eulerAngles = thisTransform.eulerAngles; + thisTransform.eulerAngles = vector3s[4]; + } + vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); + vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); + vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); + thisTransform.Translate(vector3s[2] - vector3s[3], space); + vector3s[3] = vector3s[2]; + if (tweenArguments.Contains("looktarget")) + { + thisTransform.eulerAngles = eulerAngles; + } + postUpdate = thisTransform.position; + if (physics) + { + thisTransform.position = preUpdate; + GetComponent().MovePosition(postUpdate); + } + } + + private void ApplyScaleToTargets() + { + vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); + vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); + vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); + thisTransform.localScale = vector3s[2]; + if (percentage == 1f) + { + thisTransform.localScale = vector3s[1]; + } + } + + private void ApplyLookToTargets() + { + vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); + vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); + vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); + if (isLocal) + { + thisTransform.localRotation = Quaternion.Euler(vector3s[2]); + } + else + { + thisTransform.rotation = Quaternion.Euler(vector3s[2]); + } + } + + private void ApplyRotateToTargets() + { + preUpdate = thisTransform.eulerAngles; + vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); + vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); + vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); + if (isLocal) + { + thisTransform.localRotation = Quaternion.Euler(vector3s[2]); + } + else + { + thisTransform.rotation = Quaternion.Euler(vector3s[2]); + } + if (percentage == 1f) + { + if (isLocal) + { + thisTransform.localRotation = Quaternion.Euler(vector3s[1]); + } + else + { + thisTransform.rotation = Quaternion.Euler(vector3s[1]); + } + } + postUpdate = thisTransform.eulerAngles; + if (physics) + { + thisTransform.eulerAngles = preUpdate; + GetComponent().MoveRotation(Quaternion.Euler(postUpdate)); + } + } + + private void ApplyRotateAddTargets() + { + preUpdate = thisTransform.eulerAngles; + vector3s[2].x = ease(vector3s[0].x, vector3s[1].x, percentage); + vector3s[2].y = ease(vector3s[0].y, vector3s[1].y, percentage); + vector3s[2].z = ease(vector3s[0].z, vector3s[1].z, percentage); + thisTransform.Rotate(vector3s[2] - vector3s[3], space); + vector3s[3] = vector3s[2]; + postUpdate = thisTransform.eulerAngles; + if (physics) + { + thisTransform.eulerAngles = preUpdate; + GetComponent().MoveRotation(Quaternion.Euler(postUpdate)); + } + } + + private void ApplyShakePositionTargets() + { + if (isLocal) + { + preUpdate = thisTransform.localPosition; + } + else + { + preUpdate = thisTransform.position; + } + Vector3 eulerAngles = default(Vector3); + if (tweenArguments.Contains("looktarget")) + { + eulerAngles = thisTransform.eulerAngles; + thisTransform.eulerAngles = vector3s[3]; + } + if (percentage == 0f) + { + thisTransform.Translate(vector3s[1], space); + } + if (isLocal) + { + thisTransform.localPosition = vector3s[0]; + } + else + { + thisTransform.position = vector3s[0]; + } + float num = 1f - percentage; + vector3s[2].x = UnityEngine.Random.Range((0f - vector3s[1].x) * num, vector3s[1].x * num); + vector3s[2].y = UnityEngine.Random.Range((0f - vector3s[1].y) * num, vector3s[1].y * num); + vector3s[2].z = UnityEngine.Random.Range((0f - vector3s[1].z) * num, vector3s[1].z * num); + if (isLocal) + { + thisTransform.localPosition += vector3s[2]; + } + else + { + thisTransform.position += vector3s[2]; + } + if (tweenArguments.Contains("looktarget")) + { + thisTransform.eulerAngles = eulerAngles; + } + postUpdate = thisTransform.position; + if (physics) + { + thisTransform.position = preUpdate; + GetComponent().MovePosition(postUpdate); + } + } + + private void ApplyShakeScaleTargets() + { + if (percentage == 0f) + { + thisTransform.localScale = vector3s[1]; + } + thisTransform.localScale = vector3s[0]; + float num = 1f - percentage; + vector3s[2].x = UnityEngine.Random.Range((0f - vector3s[1].x) * num, vector3s[1].x * num); + vector3s[2].y = UnityEngine.Random.Range((0f - vector3s[1].y) * num, vector3s[1].y * num); + vector3s[2].z = UnityEngine.Random.Range((0f - vector3s[1].z) * num, vector3s[1].z * num); + thisTransform.localScale += vector3s[2]; + } + + private void ApplyShakeRotationTargets() + { + preUpdate = thisTransform.eulerAngles; + if (percentage == 0f) + { + thisTransform.Rotate(vector3s[1], space); + } + thisTransform.eulerAngles = vector3s[0]; + float num = 1f - percentage; + vector3s[2].x = UnityEngine.Random.Range((0f - vector3s[1].x) * num, vector3s[1].x * num); + vector3s[2].y = UnityEngine.Random.Range((0f - vector3s[1].y) * num, vector3s[1].y * num); + vector3s[2].z = UnityEngine.Random.Range((0f - vector3s[1].z) * num, vector3s[1].z * num); + thisTransform.Rotate(vector3s[2], space); + postUpdate = thisTransform.eulerAngles; + if (physics) + { + thisTransform.eulerAngles = preUpdate; + GetComponent().MoveRotation(Quaternion.Euler(postUpdate)); + } + } + + private void ApplyPunchPositionTargets() + { + preUpdate = thisTransform.position; + Vector3 eulerAngles = default(Vector3); + if (tweenArguments.Contains("looktarget")) + { + eulerAngles = thisTransform.eulerAngles; + thisTransform.eulerAngles = vector3s[4]; + } + if (vector3s[1].x > 0f) + { + vector3s[2].x = punch(vector3s[1].x, percentage); + } + else if (vector3s[1].x < 0f) + { + vector3s[2].x = 0f - punch(Mathf.Abs(vector3s[1].x), percentage); + } + if (vector3s[1].y > 0f) + { + vector3s[2].y = punch(vector3s[1].y, percentage); + } + else if (vector3s[1].y < 0f) + { + vector3s[2].y = 0f - punch(Mathf.Abs(vector3s[1].y), percentage); + } + if (vector3s[1].z > 0f) + { + vector3s[2].z = punch(vector3s[1].z, percentage); + } + else if (vector3s[1].z < 0f) + { + vector3s[2].z = 0f - punch(Mathf.Abs(vector3s[1].z), percentage); + } + thisTransform.Translate(vector3s[2] - vector3s[3], space); + vector3s[3] = vector3s[2]; + if (tweenArguments.Contains("looktarget")) + { + thisTransform.eulerAngles = eulerAngles; + } + postUpdate = thisTransform.position; + if (physics) + { + thisTransform.position = preUpdate; + GetComponent().MovePosition(postUpdate); + } + } + + private void ApplyPunchRotationTargets() + { + preUpdate = thisTransform.eulerAngles; + if (vector3s[1].x > 0f) + { + vector3s[2].x = punch(vector3s[1].x, percentage); + } + else if (vector3s[1].x < 0f) + { + vector3s[2].x = 0f - punch(Mathf.Abs(vector3s[1].x), percentage); + } + if (vector3s[1].y > 0f) + { + vector3s[2].y = punch(vector3s[1].y, percentage); + } + else if (vector3s[1].y < 0f) + { + vector3s[2].y = 0f - punch(Mathf.Abs(vector3s[1].y), percentage); + } + if (vector3s[1].z > 0f) + { + vector3s[2].z = punch(vector3s[1].z, percentage); + } + else if (vector3s[1].z < 0f) + { + vector3s[2].z = 0f - punch(Mathf.Abs(vector3s[1].z), percentage); + } + thisTransform.Rotate(vector3s[2] - vector3s[3], space); + vector3s[3] = vector3s[2]; + postUpdate = thisTransform.eulerAngles; + if (physics) + { + thisTransform.eulerAngles = preUpdate; + GetComponent().MoveRotation(Quaternion.Euler(postUpdate)); + } + } + + private void ApplyPunchScaleTargets() + { + if (vector3s[1].x > 0f) + { + vector3s[2].x = punch(vector3s[1].x, percentage); + } + else if (vector3s[1].x < 0f) + { + vector3s[2].x = 0f - punch(Mathf.Abs(vector3s[1].x), percentage); + } + if (vector3s[1].y > 0f) + { + vector3s[2].y = punch(vector3s[1].y, percentage); + } + else if (vector3s[1].y < 0f) + { + vector3s[2].y = 0f - punch(Mathf.Abs(vector3s[1].y), percentage); + } + if (vector3s[1].z > 0f) + { + vector3s[2].z = punch(vector3s[1].z, percentage); + } + else if (vector3s[1].z < 0f) + { + vector3s[2].z = 0f - punch(Mathf.Abs(vector3s[1].z), percentage); + } + thisTransform.localScale = vector3s[0] + vector3s[2]; + } + + private IEnumerator TweenDelay() + { + delayStarted = Time.time; + yield return (object)new WaitForSeconds(delay); + if (wasPaused) + { + wasPaused = false; + TweenStart(); + } + } + + private void TweenStart() + { + CallBack("onstart"); + if (!loop) + { + ConflictCheck(); + GenerateTargets(); + } + if (type == "stab") + { + audioSource.PlayOneShot(audioSource.clip); + } + if (type == "move" || type == "scale" || type == "rotate" || type == "punch" || type == "shake" || type == "curve" || type == "look") + { + EnableKinematic(); + } + isRunning = true; + } + + private IEnumerator TweenRestart() + { + if (delay > 0f) + { + delayStarted = Time.time; + yield return (object)new WaitForSeconds(delay); + } + loop = true; + TweenStart(); + } + + private void TweenUpdate() + { + apply(); + CallBack("onupdate"); + UpdatePercentage(); + } + + private void TweenComplete() + { + isRunning = false; + if (percentage > 0.5f) + { + percentage = 1f; + } + else + { + percentage = 0f; + } + apply(); + if (type == "value") + { + CallBack("onupdate"); + } + if (loopType == LoopType.none) + { + Dispose(); + } + else + { + TweenLoop(); + } + CallBack("oncomplete"); + } + + private void TweenLoop() + { + DisableKinematic(); + switch (loopType) + { + case LoopType.loop: + percentage = 0f; + runningTime = 0f; + apply(); + StartCoroutine("TweenRestart"); + break; + case LoopType.pingPong: + reverse = !reverse; + runningTime = 0f; + StartCoroutine("TweenRestart"); + break; + } + } + + public static Rect RectUpdate(Rect currentValue, Rect targetValue, float speed) + { + return new Rect(FloatUpdate(currentValue.x, targetValue.x, speed), FloatUpdate(currentValue.y, targetValue.y, speed), FloatUpdate(currentValue.width, targetValue.width, speed), FloatUpdate(currentValue.height, targetValue.height, speed)); + } + + public static Vector3 Vector3Update(Vector3 currentValue, Vector3 targetValue, float speed) + { + Vector3 a = targetValue - currentValue; + currentValue += a * speed * Time.deltaTime; + return currentValue; + } + + public static Vector2 Vector2Update(Vector2 currentValue, Vector2 targetValue, float speed) + { + Vector2 a = targetValue - currentValue; + currentValue += a * speed * Time.deltaTime; + return currentValue; + } + + public static float FloatUpdate(float currentValue, float targetValue, float speed) + { + float num = targetValue - currentValue; + currentValue += num * speed * Time.deltaTime; + return currentValue; + } + + public static void FadeUpdate(GameObject target, Hashtable args) + { + args["a"] = args["alpha"]; + ColorUpdate(target, args); + } + + public static void FadeUpdate(GameObject target, float alpha, float time) + { + FadeUpdate(target, Hash("alpha", alpha, "time", time)); + } + + public static void ColorUpdate(GameObject target, Hashtable args) + { + CleanArgs(args); + Color[] array = new Color[4]; + if (!args.Contains("includechildren") || (bool)args["includechildren"]) + { + foreach (Transform item in target.transform) + { + ColorUpdate(item.gameObject, args); + } + } + float num; + if (args.Contains("time")) + { + num = (float)args["time"]; + num *= Defaults.updateTimePercentage; + } + else + { + num = Defaults.updateTime; + } + if ((bool)target.GetComponent()) + { + array[0] = (array[1] = target.GetComponent().color); + } + else if ((bool)target.GetComponent()) + { + array[0] = (array[1] = target.GetComponent().material.color); + } + else if ((bool)target.GetComponent()) + { + array[0] = (array[1] = target.GetComponent().material.color); + } + else if ((bool)target.GetComponent()) + { + array[0] = (array[1] = target.GetComponent().color); + } + if (args.Contains("color")) + { + array[1] = (Color)args["color"]; + } + else + { + if (args.Contains("r")) + { + array[1].r = (float)args["r"]; + } + if (args.Contains("g")) + { + array[1].g = (float)args["g"]; + } + if (args.Contains("b")) + { + array[1].b = (float)args["b"]; + } + if (args.Contains("a")) + { + array[1].a = (float)args["a"]; + } + } + array[3].r = Mathf.SmoothDamp(array[0].r, array[1].r, ref array[2].r, num); + array[3].g = Mathf.SmoothDamp(array[0].g, array[1].g, ref array[2].g, num); + array[3].b = Mathf.SmoothDamp(array[0].b, array[1].b, ref array[2].b, num); + array[3].a = Mathf.SmoothDamp(array[0].a, array[1].a, ref array[2].a, num); + if ((bool)target.GetComponent()) + { + target.GetComponent().color = array[3]; + } + else if ((bool)target.GetComponent()) + { + target.GetComponent().material.color = array[3]; + } + else if ((bool)target.GetComponent()) + { + target.GetComponent().material.color = array[3]; + } + else if ((bool)target.GetComponent()) + { + target.GetComponent().color = array[3]; + } + } + + public static void ColorUpdate(GameObject target, Color color, float time) + { + ColorUpdate(target, Hash("color", color, "time", time)); + } + + public static void AudioUpdate(GameObject target, Hashtable args) + { + CleanArgs(args); + Vector2[] array = new Vector2[4]; + float num; + if (args.Contains("time")) + { + num = (float)args["time"]; + num *= Defaults.updateTimePercentage; + } + else + { + num = Defaults.updateTime; + } + AudioSource audioSource; + if (args.Contains("audiosource")) + { + audioSource = (AudioSource)args["audiosource"]; + } + else + { + if (!(bool)target.GetComponent()) + { + Debug.LogError("iTween Error: AudioUpdate requires an AudioSource."); + return; + } + audioSource = target.GetComponent(); + } + array[0] = (array[1] = new Vector2(audioSource.volume, audioSource.pitch)); + if (args.Contains("volume")) + { + array[1].x = (float)args["volume"]; + } + if (args.Contains("pitch")) + { + array[1].y = (float)args["pitch"]; + } + array[3].x = Mathf.SmoothDampAngle(array[0].x, array[1].x, ref array[2].x, num); + array[3].y = Mathf.SmoothDampAngle(array[0].y, array[1].y, ref array[2].y, num); + audioSource.volume = array[3].x; + audioSource.pitch = array[3].y; + } + + public static void AudioUpdate(GameObject target, float volume, float pitch, float time) + { + AudioUpdate(target, Hash("volume", volume, "pitch", pitch, "time", time)); + } + + public static void RotateUpdate(GameObject target, Hashtable args) + { + CleanArgs(args); + Vector3[] array = new Vector3[4]; + Vector3 eulerAngles = target.transform.eulerAngles; + float num; + if (args.Contains("time")) + { + num = (float)args["time"]; + num *= Defaults.updateTimePercentage; + } + else + { + num = Defaults.updateTime; + } + bool flag = (!args.Contains("islocal")) ? Defaults.isLocal : ((bool)args["islocal"]); + if (flag) + { + array[0] = target.transform.localEulerAngles; + } + else + { + array[0] = target.transform.eulerAngles; + } + if (args.Contains("rotation")) + { + if (args["rotation"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["rotation"]; + array[1] = transform.eulerAngles; + } + else if (args["rotation"].GetType() == typeof(Vector3)) + { + array[1] = (Vector3)args["rotation"]; + } + } + array[3].x = Mathf.SmoothDampAngle(array[0].x, array[1].x, ref array[2].x, num); + array[3].y = Mathf.SmoothDampAngle(array[0].y, array[1].y, ref array[2].y, num); + array[3].z = Mathf.SmoothDampAngle(array[0].z, array[1].z, ref array[2].z, num); + if (flag) + { + target.transform.localEulerAngles = array[3]; + } + else + { + target.transform.eulerAngles = array[3]; + } + if (target.GetComponent() != null) + { + Vector3 eulerAngles2 = target.transform.eulerAngles; + target.transform.eulerAngles = eulerAngles; + target.GetComponent().MoveRotation(Quaternion.Euler(eulerAngles2)); + } + } + + public static void RotateUpdate(GameObject target, Vector3 rotation, float time) + { + RotateUpdate(target, Hash("rotation", rotation, "time", time)); + } + + public static void ScaleUpdate(GameObject target, Hashtable args) + { + CleanArgs(args); + Vector3[] array = new Vector3[4]; + float num; + if (args.Contains("time")) + { + num = (float)args["time"]; + num *= Defaults.updateTimePercentage; + } + else + { + num = Defaults.updateTime; + } + array[0] = (array[1] = target.transform.localScale); + if (args.Contains("scale")) + { + if (args["scale"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["scale"]; + array[1] = transform.localScale; + } + else if (args["scale"].GetType() == typeof(Vector3)) + { + array[1] = (Vector3)args["scale"]; + } + } + else + { + if (args.Contains("x")) + { + array[1].x = (float)args["x"]; + } + if (args.Contains("y")) + { + array[1].y = (float)args["y"]; + } + if (args.Contains("z")) + { + array[1].z = (float)args["z"]; + } + } + array[3].x = Mathf.SmoothDamp(array[0].x, array[1].x, ref array[2].x, num); + array[3].y = Mathf.SmoothDamp(array[0].y, array[1].y, ref array[2].y, num); + array[3].z = Mathf.SmoothDamp(array[0].z, array[1].z, ref array[2].z, num); + target.transform.localScale = array[3]; + } + + public static void ScaleUpdate(GameObject target, Vector3 scale, float time) + { + ScaleUpdate(target, Hash("scale", scale, "time", time)); + } + + public static void MoveUpdate(GameObject target, Hashtable args) + { + CleanArgs(args); + Vector3[] array = new Vector3[4]; + Vector3 position = target.transform.position; + float num; + if (args.Contains("time")) + { + num = (float)args["time"]; + num *= Defaults.updateTimePercentage; + } + else + { + num = Defaults.updateTime; + } + bool flag = (!args.Contains("islocal")) ? Defaults.isLocal : ((bool)args["islocal"]); + if (flag) + { + array[0] = (array[1] = target.transform.localPosition); + } + else + { + array[0] = (array[1] = target.transform.position); + } + if (args.Contains("position")) + { + if (args["position"].GetType() == typeof(Transform)) + { + Transform transform = (Transform)args["position"]; + array[1] = transform.position; + } + else if (args["position"].GetType() == typeof(Vector3)) + { + array[1] = (Vector3)args["position"]; + } + } + else + { + if (args.Contains("x")) + { + array[1].x = (float)args["x"]; + } + if (args.Contains("y")) + { + array[1].y = (float)args["y"]; + } + if (args.Contains("z")) + { + array[1].z = (float)args["z"]; + } + } + array[3].x = Mathf.SmoothDamp(array[0].x, array[1].x, ref array[2].x, num); + array[3].y = Mathf.SmoothDamp(array[0].y, array[1].y, ref array[2].y, num); + array[3].z = Mathf.SmoothDamp(array[0].z, array[1].z, ref array[2].z, num); + if (args.Contains("orienttopath") && (bool)args["orienttopath"]) + { + args["looktarget"] = array[3]; + } + if (args.Contains("looktarget")) + { + LookUpdate(target, args); + } + if (flag) + { + target.transform.localPosition = array[3]; + } + else + { + target.transform.position = array[3]; + } + if (target.GetComponent() != null) + { + Vector3 position2 = target.transform.position; + target.transform.position = position; + target.GetComponent().MovePosition(position2); + } + } + + public static void MoveUpdate(GameObject target, Vector3 position, float time) + { + MoveUpdate(target, Hash("position", position, "time", time)); + } + + public static void LookUpdate(GameObject target, Hashtable args) + { + CleanArgs(args); + Vector3[] array = new Vector3[5]; + float num; + if (args.Contains("looktime")) + { + num = (float)args["looktime"]; + num *= Defaults.updateTimePercentage; + } + else if (args.Contains("time")) + { + num = (float)args["time"] * 0.15f; + num *= Defaults.updateTimePercentage; + } + else + { + num = Defaults.updateTime; + } + array[0] = target.transform.eulerAngles; + if (args.Contains("looktarget")) + { + if (args["looktarget"].GetType() == typeof(Transform)) + { + Transform transform = target.transform; + Transform target2 = (Transform)args["looktarget"]; + Vector3? vector = (Vector3?)args["up"]; + transform.LookAt(target2, (!vector.HasValue) ? Defaults.up : vector.Value); + } + else if (args["looktarget"].GetType() == typeof(Vector3)) + { + Transform transform2 = target.transform; + Vector3 worldPosition = (Vector3)args["looktarget"]; + Vector3? vector2 = (Vector3?)args["up"]; + transform2.LookAt(worldPosition, (!vector2.HasValue) ? Defaults.up : vector2.Value); + } + array[1] = target.transform.eulerAngles; + target.transform.eulerAngles = array[0]; + array[3].x = Mathf.SmoothDampAngle(array[0].x, array[1].x, ref array[2].x, num); + array[3].y = Mathf.SmoothDampAngle(array[0].y, array[1].y, ref array[2].y, num); + array[3].z = Mathf.SmoothDampAngle(array[0].z, array[1].z, ref array[2].z, num); + target.transform.eulerAngles = array[3]; + if (args.Contains("axis")) + { + array[4] = target.transform.eulerAngles; + switch ((string)args["axis"]) + { + case "x": + array[4].y = array[0].y; + array[4].z = array[0].z; + break; + case "y": + array[4].x = array[0].x; + array[4].z = array[0].z; + break; + case "z": + array[4].x = array[0].x; + array[4].y = array[0].y; + break; + } + target.transform.eulerAngles = array[4]; + } + } + else + { + Debug.LogError("iTween Error: LookUpdate needs a 'looktarget' property!"); + } + } + + public static void LookUpdate(GameObject target, Vector3 looktarget, float time) + { + LookUpdate(target, Hash("looktarget", looktarget, "time", time)); + } + + public static float PathLength(Transform[] path) + { + Vector3[] array = new Vector3[path.Length]; + float num = 0f; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + Vector3[] pts = PathControlPointGenerator(array); + Vector3 a = Interp(pts, 0f); + int num2 = path.Length * 20; + for (int j = 1; j <= num2; j++) + { + float t = (float)j / (float)num2; + Vector3 vector = Interp(pts, t); + num += Vector3.Distance(a, vector); + a = vector; + } + return num; + } + + public static float PathLength(Vector3[] path) + { + float num = 0f; + Vector3[] pts = PathControlPointGenerator(path); + Vector3 a = Interp(pts, 0f); + int num2 = path.Length * 20; + for (int i = 1; i <= num2; i++) + { + float t = (float)i / (float)num2; + Vector3 vector = Interp(pts, t); + num += Vector3.Distance(a, vector); + a = vector; + } + return num; + } + + public static Texture2D CameraTexture(Color color) + { + Texture2D texture2D = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, mipmap: false); + Color[] array = new Color[Screen.width * Screen.height]; + for (int i = 0; i < array.Length; i++) + { + array[i] = color; + } + texture2D.SetPixels(array); + texture2D.Apply(); + return texture2D; + } + + public static void PutOnPath(GameObject target, Vector3[] path, float percent) + { + target.transform.position = Interp(PathControlPointGenerator(path), percent); + } + + public static void PutOnPath(Transform target, Vector3[] path, float percent) + { + target.position = Interp(PathControlPointGenerator(path), percent); + } + + public static void PutOnPath(GameObject target, Transform[] path, float percent) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + target.transform.position = Interp(PathControlPointGenerator(array), percent); + } + + public static void PutOnPath(Transform target, Transform[] path, float percent) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + target.position = Interp(PathControlPointGenerator(array), percent); + } + + public static Vector3 PointOnPath(Transform[] path, float percent) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + return Interp(PathControlPointGenerator(array), percent); + } + + public static void DrawLine(Vector3[] line) + { + if (line.Length > 0) + { + DrawLineHelper(line, Defaults.color, "gizmos"); + } + } + + public static void DrawLine(Vector3[] line, Color color) + { + if (line.Length > 0) + { + DrawLineHelper(line, color, "gizmos"); + } + } + + public static void DrawLine(Transform[] line) + { + if (line.Length > 0) + { + Vector3[] array = new Vector3[line.Length]; + for (int i = 0; i < line.Length; i++) + { + array[i] = line[i].position; + } + DrawLineHelper(array, Defaults.color, "gizmos"); + } + } + + public static void DrawLine(Transform[] line, Color color) + { + if (line.Length > 0) + { + Vector3[] array = new Vector3[line.Length]; + for (int i = 0; i < line.Length; i++) + { + array[i] = line[i].position; + } + DrawLineHelper(array, color, "gizmos"); + } + } + + public static void DrawLineGizmos(Vector3[] line) + { + if (line.Length > 0) + { + DrawLineHelper(line, Defaults.color, "gizmos"); + } + } + + public static void DrawLineGizmos(Vector3[] line, Color color) + { + if (line.Length > 0) + { + DrawLineHelper(line, color, "gizmos"); + } + } + + public static void DrawLineGizmos(Transform[] line) + { + if (line.Length > 0) + { + Vector3[] array = new Vector3[line.Length]; + for (int i = 0; i < line.Length; i++) + { + array[i] = line[i].position; + } + DrawLineHelper(array, Defaults.color, "gizmos"); + } + } + + public static void DrawLineGizmos(Transform[] line, Color color) + { + if (line.Length > 0) + { + Vector3[] array = new Vector3[line.Length]; + for (int i = 0; i < line.Length; i++) + { + array[i] = line[i].position; + } + DrawLineHelper(array, color, "gizmos"); + } + } + + public static void DrawLineHandles(Vector3[] line) + { + if (line.Length > 0) + { + DrawLineHelper(line, Defaults.color, "handles"); + } + } + + public static void DrawLineHandles(Vector3[] line, Color color) + { + if (line.Length > 0) + { + DrawLineHelper(line, color, "handles"); + } + } + + public static void DrawLineHandles(Transform[] line) + { + if (line.Length > 0) + { + Vector3[] array = new Vector3[line.Length]; + for (int i = 0; i < line.Length; i++) + { + array[i] = line[i].position; + } + DrawLineHelper(array, Defaults.color, "handles"); + } + } + + public static void DrawLineHandles(Transform[] line, Color color) + { + if (line.Length > 0) + { + Vector3[] array = new Vector3[line.Length]; + for (int i = 0; i < line.Length; i++) + { + array[i] = line[i].position; + } + DrawLineHelper(array, color, "handles"); + } + } + + public static Vector3 PointOnPath(Vector3[] path, float percent) + { + return Interp(PathControlPointGenerator(path), percent); + } + + public static void DrawPath(Vector3[] path) + { + if (path.Length > 0) + { + DrawPathHelper(path, Defaults.color, "gizmos"); + } + } + + public static void DrawPath(Vector3[] path, Color color) + { + if (path.Length > 0) + { + DrawPathHelper(path, color, "gizmos"); + } + } + + public static void DrawPath(Transform[] path) + { + if (path.Length > 0) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + DrawPathHelper(array, Defaults.color, "gizmos"); + } + } + + public static void DrawPath(Transform[] path, Color color) + { + if (path.Length > 0) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + DrawPathHelper(array, color, "gizmos"); + } + } + + public static void DrawPathGizmos(Vector3[] path) + { + if (path.Length > 0) + { + DrawPathHelper(path, Defaults.color, "gizmos"); + } + } + + public static void DrawPathGizmos(Vector3[] path, Color color) + { + if (path.Length > 0) + { + DrawPathHelper(path, color, "gizmos"); + } + } + + public static void DrawPathGizmos(Transform[] path) + { + if (path.Length > 0) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + DrawPathHelper(array, Defaults.color, "gizmos"); + } + } + + public static void DrawPathGizmos(Transform[] path, Color color) + { + if (path.Length > 0) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + DrawPathHelper(array, color, "gizmos"); + } + } + + public static void DrawPathHandles(Vector3[] path) + { + if (path.Length > 0) + { + DrawPathHelper(path, Defaults.color, "handles"); + } + } + + public static void DrawPathHandles(Vector3[] path, Color color) + { + if (path.Length > 0) + { + DrawPathHelper(path, color, "handles"); + } + } + + public static void DrawPathHandles(Transform[] path) + { + if (path.Length > 0) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + DrawPathHelper(array, Defaults.color, "handles"); + } + } + + public static void DrawPathHandles(Transform[] path, Color color) + { + if (path.Length > 0) + { + Vector3[] array = new Vector3[path.Length]; + for (int i = 0; i < path.Length; i++) + { + array[i] = path[i].position; + } + DrawPathHelper(array, color, "handles"); + } + } + + public static void CameraFadeDepth(int depth) + { + if ((bool)cameraFade) + { + Transform transform = cameraFade.transform; + Vector3 position = cameraFade.transform.position; + float x = position.x; + Vector3 position2 = cameraFade.transform.position; + transform.position = new Vector3(x, position2.y, (float)depth); + } + } + + public static void CameraFadeDestroy() + { + if ((bool)cameraFade) + { + UnityEngine.Object.Destroy(cameraFade); + } + } + + public static void CameraFadeSwap(Texture2D texture) + { + if ((bool)cameraFade) + { + cameraFade.GetComponent().texture = texture; + } + } + + public static GameObject CameraFadeAdd(Texture2D texture, int depth) + { + if ((bool)cameraFade) + { + return null; + } + cameraFade = new GameObject("iTween Camera Fade"); + cameraFade.transform.position = new Vector3(0.5f, 0.5f, (float)depth); + cameraFade.AddComponent(); + cameraFade.GetComponent().texture = texture; + cameraFade.GetComponent().color = new Color(0.5f, 0.5f, 0.5f, 0f); + return cameraFade; + } + + public static GameObject CameraFadeAdd(Texture2D texture) + { + if ((bool)cameraFade) + { + return null; + } + cameraFade = new GameObject("iTween Camera Fade"); + cameraFade.transform.position = new Vector3(0.5f, 0.5f, (float)Defaults.cameraFadeDepth); + cameraFade.AddComponent(); + cameraFade.GetComponent().texture = texture; + cameraFade.GetComponent().color = new Color(0.5f, 0.5f, 0.5f, 0f); + return cameraFade; + } + + public static GameObject CameraFadeAdd() + { + if ((bool)cameraFade) + { + return null; + } + cameraFade = new GameObject("iTween Camera Fade"); + cameraFade.transform.position = new Vector3(0.5f, 0.5f, (float)Defaults.cameraFadeDepth); + cameraFade.AddComponent(); + cameraFade.GetComponent().texture = CameraTexture(Color.black); + cameraFade.GetComponent().color = new Color(0.5f, 0.5f, 0.5f, 0f); + return cameraFade; + } + + public static void Resume(GameObject target) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + iTween.enabled = true; + } + } + + public static void Resume(GameObject target, bool includechildren) + { + Resume(target); + if (includechildren) + { + foreach (Transform item in target.transform) + { + Resume(item.gameObject, includechildren: true); + } + } + } + + public static void Resume(GameObject target, string type) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + string text = iTween.type + iTween.method; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + iTween.enabled = true; + } + } + } + + public static void Resume(GameObject target, string type, bool includechildren) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + string text = iTween.type + iTween.method; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + iTween.enabled = true; + } + } + if (includechildren) + { + foreach (Transform item in target.transform) + { + Resume(item.gameObject, type, includechildren: true); + } + } + } + + public static void Resume() + { + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + GameObject target = (GameObject)hashtable["target"]; + Resume(target); + } + } + + public static void Resume(string type) + { + ArrayList arrayList = new ArrayList(); + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + GameObject value = (GameObject)hashtable["target"]; + arrayList.Insert(arrayList.Count, value); + } + for (int j = 0; j < arrayList.Count; j++) + { + Resume((GameObject)arrayList[j], type); + } + } + + public static void Pause(GameObject target) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + if (iTween.delay > 0f) + { + iTween.delay -= Time.time - iTween.delayStarted; + iTween.StopCoroutine("TweenDelay"); + } + iTween.isPaused = true; + iTween.enabled = false; + } + } + + public static void Pause(GameObject target, bool includechildren) + { + Pause(target); + if (includechildren) + { + foreach (Transform item in target.transform) + { + Pause(item.gameObject, includechildren: true); + } + } + } + + public static void Pause(GameObject target, string type) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + string text = iTween.type + iTween.method; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + if (iTween.delay > 0f) + { + iTween.delay -= Time.time - iTween.delayStarted; + iTween.StopCoroutine("TweenDelay"); + } + iTween.isPaused = true; + iTween.enabled = false; + } + } + } + + public static void Pause(GameObject target, string type, bool includechildren) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + string text = iTween.type + iTween.method; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + if (iTween.delay > 0f) + { + iTween.delay -= Time.time - iTween.delayStarted; + iTween.StopCoroutine("TweenDelay"); + } + iTween.isPaused = true; + iTween.enabled = false; + } + } + if (includechildren) + { + foreach (Transform item in target.transform) + { + Pause(item.gameObject, type, includechildren: true); + } + } + } + + public static void Pause() + { + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + GameObject target = (GameObject)hashtable["target"]; + Pause(target); + } + } + + public static void Pause(string type) + { + ArrayList arrayList = new ArrayList(); + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + GameObject value = (GameObject)hashtable["target"]; + arrayList.Insert(arrayList.Count, value); + } + for (int j = 0; j < arrayList.Count; j++) + { + Pause((GameObject)arrayList[j], type); + } + } + + public static int Count() + { + return tweens.Count; + } + + public static int Count(string type) + { + int num = 0; + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + string text = (string)hashtable["type"] + (string)hashtable["method"]; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + num++; + } + } + return num; + } + + public static int Count(GameObject target) + { + Component[] components = target.GetComponents(); + return components.Length; + } + + public static int Count(GameObject target, string type) + { + int num = 0; + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + string text = iTween.type + iTween.method; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + num++; + } + } + return num; + } + + public static void Stop() + { + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + GameObject target = (GameObject)hashtable["target"]; + Stop(target); + } + tweens.Clear(); + } + + public static void Stop(string type) + { + ArrayList arrayList = new ArrayList(); + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + GameObject value = (GameObject)hashtable["target"]; + arrayList.Insert(arrayList.Count, value); + } + for (int j = 0; j < arrayList.Count; j++) + { + Stop((GameObject)arrayList[j], type); + } + } + + public static void StopByName(string name) + { + ArrayList arrayList = new ArrayList(); + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + GameObject value = (GameObject)hashtable["target"]; + arrayList.Insert(arrayList.Count, value); + } + for (int j = 0; j < arrayList.Count; j++) + { + StopByName((GameObject)arrayList[j], name); + } + } + + public static void Stop(GameObject target) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + iTween.Dispose(); + } + } + + public static void Stop(GameObject target, bool includechildren) + { + Stop(target); + if (includechildren) + { + foreach (Transform item in target.transform) + { + Stop(item.gameObject, includechildren: true); + } + } + } + + public static void Stop(GameObject target, string type) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + string text = iTween.type + iTween.method; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + iTween.Dispose(); + } + } + } + + public static void StopByName(GameObject target, string name) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + if (iTween._name == name) + { + iTween.Dispose(); + } + } + } + + public static void Stop(GameObject target, string type, bool includechildren) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + string text = iTween.type + iTween.method; + text = text.Substring(0, type.Length); + if (text.ToLower() == type.ToLower()) + { + iTween.Dispose(); + } + } + if (includechildren) + { + foreach (Transform item in target.transform) + { + Stop(item.gameObject, type, includechildren: true); + } + } + } + + public static void StopByName(GameObject target, string name, bool includechildren) + { + Component[] components = target.GetComponents(); + Component[] array = components; + for (int i = 0; i < array.Length; i++) + { + iTween iTween = (iTween)array[i]; + if (iTween._name == name) + { + iTween.Dispose(); + } + } + if (includechildren) + { + foreach (Transform item in target.transform) + { + StopByName(item.gameObject, name, includechildren: true); + } + } + } + + public static Hashtable Hash(params object[] args) + { + Hashtable hashtable = new Hashtable(args.Length / 2); + if (args.Length % 2 != 0) + { + Debug.LogError("Tween Error: Hash requires an even number of arguments!"); + return null; + } + for (int i = 0; i < args.Length - 1; i += 2) + { + hashtable.Add(args[i], args[i + 1]); + } + return hashtable; + } + + private void Awake() + { + thisTransform = base.transform; + RetrieveArgs(); + lastRealTime = Time.realtimeSinceStartup; + } + + private IEnumerator Start() + { + if (delay > 0f) + { + yield return (object)StartCoroutine("TweenDelay"); + } + TweenStart(); + } + + private void Update() + { + if (isRunning && !physics) + { + if (!reverse) + { + if (percentage < 1f) + { + TweenUpdate(); + } + else + { + TweenComplete(); + } + } + else if (percentage > 0f) + { + TweenUpdate(); + } + else + { + TweenComplete(); + } + } + } + + private void FixedUpdate() + { + if (isRunning && physics) + { + if (!reverse) + { + if (percentage < 1f) + { + TweenUpdate(); + } + else + { + TweenComplete(); + } + } + else if (percentage > 0f) + { + TweenUpdate(); + } + else + { + TweenComplete(); + } + } + } + + private void LateUpdate() + { + if (tweenArguments.Contains("looktarget") && isRunning && (type == "move" || type == "shake" || type == "punch")) + { + LookUpdate(base.gameObject, tweenArguments); + } + } + + private void OnEnable() + { + if (isRunning) + { + EnableKinematic(); + } + if (isPaused) + { + isPaused = false; + if (delay > 0f) + { + wasPaused = true; + ResumeDelay(); + } + } + } + + private void OnDisable() + { + DisableKinematic(); + } + + private static void DrawLineHelper(Vector3[] line, Color color, string method) + { + Gizmos.color = color; + for (int i = 0; i < line.Length - 1; i++) + { + if (method == "gizmos") + { + Gizmos.DrawLine(line[i], line[i + 1]); + } + else if (method == "handles") + { + Debug.LogError("iTween Error: Drawing a line with Handles is temporarily disabled because of compatability issues with Unity 2.6!"); + } + } + } + + private static void DrawPathHelper(Vector3[] path, Color color, string method) + { + Vector3[] pts = PathControlPointGenerator(path); + Vector3 to = Interp(pts, 0f); + Gizmos.color = color; + int num = path.Length * 20; + for (int i = 1; i <= num; i++) + { + float t = (float)i / (float)num; + Vector3 vector = Interp(pts, t); + if (method == "gizmos") + { + Gizmos.DrawLine(vector, to); + } + else if (method == "handles") + { + Debug.LogError("iTween Error: Drawing a path with Handles is temporarily disabled because of compatability issues with Unity 2.6!"); + } + to = vector; + } + } + + private static Vector3[] PathControlPointGenerator(Vector3[] path) + { + int num = 2; + Vector3[] array = new Vector3[path.Length + num]; + Array.Copy(path, 0, array, 1, path.Length); + array[0] = array[1] + (array[1] - array[2]); + array[array.Length - 1] = array[array.Length - 2] + (array[array.Length - 2] - array[array.Length - 3]); + if (array[1] == array[array.Length - 2]) + { + Vector3[] array2 = new Vector3[array.Length]; + Array.Copy(array, array2, array.Length); + array2[0] = array2[array2.Length - 3]; + array2[array2.Length - 1] = array2[2]; + array = new Vector3[array2.Length]; + Array.Copy(array2, array, array2.Length); + } + return array; + } + + private static Vector3 Interp(Vector3[] pts, float t) + { + int num = pts.Length - 3; + int num2 = Mathf.Min(Mathf.FloorToInt(t * (float)num), num - 1); + float num3 = t * (float)num - (float)num2; + Vector3 a = pts[num2]; + Vector3 a2 = pts[num2 + 1]; + Vector3 vector = pts[num2 + 2]; + Vector3 b = pts[num2 + 3]; + return 0.5f * ((-a + 3f * a2 - 3f * vector + b) * (num3 * num3 * num3) + (2f * a - 5f * a2 + 4f * vector - b) * (num3 * num3) + (-a + vector) * num3 + 2f * a2); + } + + private static void Launch(GameObject target, Hashtable args) + { + if (!args.Contains("id")) + { + args["id"] = GenerateID(); + } + if (!args.Contains("target")) + { + args["target"] = target; + } + tweens.Insert(0, args); + target.AddComponent(); + } + + private static Hashtable CleanArgs(Hashtable args) + { + Hashtable hashtable = new Hashtable(args.Count); + Hashtable hashtable2 = new Hashtable(args.Count); + IDictionaryEnumerator enumerator = args.GetEnumerator(); + try + { + while (enumerator.MoveNext()) + { + DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current; + hashtable.Add(dictionaryEntry.Key, dictionaryEntry.Value); + } + } + finally + { + (enumerator as IDisposable)?.Dispose(); + } + IDictionaryEnumerator enumerator2 = hashtable.GetEnumerator(); + try + { + while (enumerator2.MoveNext()) + { + DictionaryEntry dictionaryEntry2 = (DictionaryEntry)enumerator2.Current; + if (dictionaryEntry2.Value.GetType() == typeof(int)) + { + int num = (int)dictionaryEntry2.Value; + float num2 = (float)num; + args[dictionaryEntry2.Key] = num2; + } + if (dictionaryEntry2.Value.GetType() == typeof(double)) + { + double num3 = (double)dictionaryEntry2.Value; + float num4 = (float)num3; + args[dictionaryEntry2.Key] = num4; + } + } + } + finally + { + (enumerator2 as IDisposable)?.Dispose(); + } + IDictionaryEnumerator enumerator3 = args.GetEnumerator(); + try + { + while (enumerator3.MoveNext()) + { + DictionaryEntry dictionaryEntry3 = (DictionaryEntry)enumerator3.Current; + hashtable2.Add(dictionaryEntry3.Key.ToString().ToLower(), dictionaryEntry3.Value); + } + } + finally + { + (enumerator3 as IDisposable)?.Dispose(); + } + args = hashtable2; + return args; + } + + private static string GenerateID() + { + return Guid.NewGuid().ToString(); + } + + private void RetrieveArgs() + { + foreach (Hashtable tween in tweens) + { + if ((GameObject)tween["target"] == base.gameObject) + { + tweenArguments = tween; + break; + } + } + id = (string)tweenArguments["id"]; + type = (string)tweenArguments["type"]; + _name = (string)tweenArguments["name"]; + method = (string)tweenArguments["method"]; + if (tweenArguments.Contains("time")) + { + time = (float)tweenArguments["time"]; + } + else + { + time = Defaults.time; + } + if (GetComponent() != null) + { + physics = true; + } + if (tweenArguments.Contains("delay")) + { + delay = (float)tweenArguments["delay"]; + } + else + { + delay = Defaults.delay; + } + if (tweenArguments.Contains("namedcolorvalue")) + { + if (tweenArguments["namedcolorvalue"].GetType() != typeof(NamedValueColor)) + { + try + { + namedcolorvalue = (NamedValueColor)(int)Enum.Parse(typeof(NamedValueColor), (string)tweenArguments["namedcolorvalue"], ignoreCase: true); + } + catch + { + Debug.LogWarning("iTween: Unsupported namedcolorvalue supplied! Default will be used."); + namedcolorvalue = NamedValueColor._Color; + } + } + else + { + namedcolorvalue = (NamedValueColor)(int)tweenArguments["namedcolorvalue"]; + } + } + else + { + namedcolorvalue = Defaults.namedColorValue; + } + if (tweenArguments.Contains("looptype")) + { + if (tweenArguments["looptype"].GetType() != typeof(LoopType)) + { + try + { + loopType = (LoopType)(int)Enum.Parse(typeof(LoopType), (string)tweenArguments["looptype"], ignoreCase: true); + } + catch + { + Debug.LogWarning("iTween: Unsupported loopType supplied! Default will be used."); + loopType = LoopType.none; + } + } + else + { + loopType = (LoopType)(int)tweenArguments["looptype"]; + } + } + else + { + loopType = LoopType.none; + } + if (tweenArguments.Contains("easetype")) + { + if (tweenArguments["easetype"].GetType() != typeof(EaseType)) + { + try + { + easeType = (EaseType)(int)Enum.Parse(typeof(EaseType), (string)tweenArguments["easetype"], ignoreCase: true); + } + catch + { + Debug.LogWarning("iTween: Unsupported easeType supplied! Default will be used."); + easeType = Defaults.easeType; + } + } + else + { + easeType = (EaseType)(int)tweenArguments["easetype"]; + } + } + else + { + easeType = Defaults.easeType; + } + if (tweenArguments.Contains("space")) + { + if (tweenArguments["space"].GetType() != typeof(Space)) + { + try + { + space = (Space)(int)Enum.Parse(typeof(Space), (string)tweenArguments["space"], ignoreCase: true); + } + catch + { + Debug.LogWarning("iTween: Unsupported space supplied! Default will be used."); + space = Defaults.space; + } + } + else + { + space = (Space)(int)tweenArguments["space"]; + } + } + else + { + space = Defaults.space; + } + if (tweenArguments.Contains("islocal")) + { + isLocal = (bool)tweenArguments["islocal"]; + } + else + { + isLocal = Defaults.isLocal; + } + if (tweenArguments.Contains("ignoretimescale")) + { + useRealTime = (bool)tweenArguments["ignoretimescale"]; + } + else + { + useRealTime = Defaults.useRealTime; + } + GetEasingFunction(); + } + + private void GetEasingFunction() + { + switch (easeType) + { + case EaseType.easeInQuad: + ease = easeInQuad; + break; + case EaseType.easeOutQuad: + ease = easeOutQuad; + break; + case EaseType.easeInOutQuad: + ease = easeInOutQuad; + break; + case EaseType.easeInCubic: + ease = easeInCubic; + break; + case EaseType.easeOutCubic: + ease = easeOutCubic; + break; + case EaseType.easeInOutCubic: + ease = easeInOutCubic; + break; + case EaseType.easeInQuart: + ease = easeInQuart; + break; + case EaseType.easeOutQuart: + ease = easeOutQuart; + break; + case EaseType.easeInOutQuart: + ease = easeInOutQuart; + break; + case EaseType.easeInQuint: + ease = easeInQuint; + break; + case EaseType.easeOutQuint: + ease = easeOutQuint; + break; + case EaseType.easeInOutQuint: + ease = easeInOutQuint; + break; + case EaseType.easeInSine: + ease = easeInSine; + break; + case EaseType.easeOutSine: + ease = easeOutSine; + break; + case EaseType.easeInOutSine: + ease = easeInOutSine; + break; + case EaseType.easeInExpo: + ease = easeInExpo; + break; + case EaseType.easeOutExpo: + ease = easeOutExpo; + break; + case EaseType.easeInOutExpo: + ease = easeInOutExpo; + break; + case EaseType.easeInCirc: + ease = easeInCirc; + break; + case EaseType.easeOutCirc: + ease = easeOutCirc; + break; + case EaseType.easeInOutCirc: + ease = easeInOutCirc; + break; + case EaseType.linear: + ease = linear; + break; + case EaseType.spring: + ease = spring; + break; + case EaseType.easeInBounce: + ease = easeInBounce; + break; + case EaseType.easeOutBounce: + ease = easeOutBounce; + break; + case EaseType.easeInOutBounce: + ease = easeInOutBounce; + break; + case EaseType.easeInBack: + ease = easeInBack; + break; + case EaseType.easeOutBack: + ease = easeOutBack; + break; + case EaseType.easeInOutBack: + ease = easeInOutBack; + break; + case EaseType.easeInElastic: + ease = easeInElastic; + break; + case EaseType.easeOutElastic: + ease = easeOutElastic; + break; + case EaseType.easeInOutElastic: + ease = easeInOutElastic; + break; + } + } + + private void UpdatePercentage() + { + if (useRealTime) + { + runningTime += Time.realtimeSinceStartup - lastRealTime; + } + else + { + runningTime += Time.deltaTime; + } + if (reverse) + { + percentage = 1f - runningTime / time; + } + else + { + percentage = runningTime / time; + } + lastRealTime = Time.realtimeSinceStartup; + } + + private void CallBack(string callbackType) + { + if (tweenArguments.Contains(callbackType) && !tweenArguments.Contains("ischild")) + { + GameObject gameObject = (!tweenArguments.Contains(callbackType + "target")) ? base.gameObject : ((GameObject)tweenArguments[callbackType + "target"]); + if (tweenArguments[callbackType].GetType() == typeof(string)) + { + gameObject.SendMessage((string)tweenArguments[callbackType], tweenArguments[callbackType + "params"], SendMessageOptions.DontRequireReceiver); + } + else + { + Debug.LogError("iTween Error: Callback method references must be passed as a String!"); + UnityEngine.Object.Destroy(this); + } + } + } + + private void Dispose() + { + for (int i = 0; i < tweens.Count; i++) + { + Hashtable hashtable = tweens[i]; + if ((string)hashtable["id"] == id) + { + tweens.RemoveAt(i); + break; + } + } + UnityEngine.Object.Destroy(this); + } + + private void ConflictCheck() + { + Component[] components = GetComponents(); + Component[] array = components; + int num = 0; + iTween iTween; + while (true) + { + if (num >= array.Length) + { + return; + } + iTween = (iTween)array[num]; + if (iTween.type == "value") + { + return; + } + if (iTween.isRunning && iTween.type == type) + { + if (iTween.method != method) + { + return; + } + if (iTween.tweenArguments.Count != tweenArguments.Count) + { + break; + } + IDictionaryEnumerator enumerator = tweenArguments.GetEnumerator(); + try + { + while (enumerator.MoveNext()) + { + DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current; + if (!iTween.tweenArguments.Contains(dictionaryEntry.Key)) + { + iTween.Dispose(); + return; + } + if (!iTween.tweenArguments[dictionaryEntry.Key].Equals(tweenArguments[dictionaryEntry.Key]) && (string)dictionaryEntry.Key != "id") + { + iTween.Dispose(); + return; + } + } + } + finally + { + (enumerator as IDisposable)?.Dispose(); + } + Dispose(); + } + num++; + } + iTween.Dispose(); + } + + private void EnableKinematic() + { + } + + private void DisableKinematic() + { + } + + private void ResumeDelay() + { + StartCoroutine("TweenDelay"); + } + + private float linear(float start, float end, float value) + { + return Mathf.Lerp(start, end, value); + } + + private float clerp(float start, float end, float value) + { + float num = 0f; + float num2 = 360f; + float num3 = Mathf.Abs((num2 - num) * 0.5f); + float num4 = 0f; + float num5 = 0f; + if (end - start < 0f - num3) + { + num5 = (num2 - start + end) * value; + return start + num5; + } + if (end - start > num3) + { + num5 = (0f - (num2 - end + start)) * value; + return start + num5; + } + return start + (end - start) * value; + } + + private float spring(float start, float end, float value) + { + value = Mathf.Clamp01(value); + value = (Mathf.Sin(value * 3.14159274f * (0.2f + 2.5f * value * value * value)) * Mathf.Pow(1f - value, 2.2f) + value) * (1f + 1.2f * (1f - value)); + return start + (end - start) * value; + } + + private float easeInQuad(float start, float end, float value) + { + end -= start; + return end * value * value + start; + } + + private float easeOutQuad(float start, float end, float value) + { + end -= start; + return (0f - end) * value * (value - 2f) + start; + } + + private float easeInOutQuad(float start, float end, float value) + { + value /= 0.5f; + end -= start; + if (value < 1f) + { + return end * 0.5f * value * value + start; + } + value -= 1f; + return (0f - end) * 0.5f * (value * (value - 2f) - 1f) + start; + } + + private float easeInCubic(float start, float end, float value) + { + end -= start; + return end * value * value * value + start; + } + + private float easeOutCubic(float start, float end, float value) + { + value -= 1f; + end -= start; + return end * (value * value * value + 1f) + start; + } + + private float easeInOutCubic(float start, float end, float value) + { + value /= 0.5f; + end -= start; + if (value < 1f) + { + return end * 0.5f * value * value * value + start; + } + value -= 2f; + return end * 0.5f * (value * value * value + 2f) + start; + } + + private float easeInQuart(float start, float end, float value) + { + end -= start; + return end * value * value * value * value + start; + } + + private float easeOutQuart(float start, float end, float value) + { + value -= 1f; + end -= start; + return (0f - end) * (value * value * value * value - 1f) + start; + } + + private float easeInOutQuart(float start, float end, float value) + { + value /= 0.5f; + end -= start; + if (value < 1f) + { + return end * 0.5f * value * value * value * value + start; + } + value -= 2f; + return (0f - end) * 0.5f * (value * value * value * value - 2f) + start; + } + + private float easeInQuint(float start, float end, float value) + { + end -= start; + return end * value * value * value * value * value + start; + } + + private float easeOutQuint(float start, float end, float value) + { + value -= 1f; + end -= start; + return end * (value * value * value * value * value + 1f) + start; + } + + private float easeInOutQuint(float start, float end, float value) + { + value /= 0.5f; + end -= start; + if (value < 1f) + { + return end * 0.5f * value * value * value * value * value + start; + } + value -= 2f; + return end * 0.5f * (value * value * value * value * value + 2f) + start; + } + + private float easeInSine(float start, float end, float value) + { + end -= start; + return (0f - end) * Mathf.Cos(value * 1.57079637f) + end + start; + } + + private float easeOutSine(float start, float end, float value) + { + end -= start; + return end * Mathf.Sin(value * 1.57079637f) + start; + } + + private float easeInOutSine(float start, float end, float value) + { + end -= start; + return (0f - end) * 0.5f * (Mathf.Cos(3.14159274f * value) - 1f) + start; + } + + private float easeInExpo(float start, float end, float value) + { + end -= start; + return end * Mathf.Pow(2f, 10f * (value - 1f)) + start; + } + + private float easeOutExpo(float start, float end, float value) + { + end -= start; + return end * (0f - Mathf.Pow(2f, -10f * value) + 1f) + start; + } + + private float easeInOutExpo(float start, float end, float value) + { + value /= 0.5f; + end -= start; + if (value < 1f) + { + return end * 0.5f * Mathf.Pow(2f, 10f * (value - 1f)) + start; + } + value -= 1f; + return end * 0.5f * (0f - Mathf.Pow(2f, -10f * value) + 2f) + start; + } + + private float easeInCirc(float start, float end, float value) + { + end -= start; + return (0f - end) * (Mathf.Sqrt(1f - value * value) - 1f) + start; + } + + private float easeOutCirc(float start, float end, float value) + { + value -= 1f; + end -= start; + return end * Mathf.Sqrt(1f - value * value) + start; + } + + private float easeInOutCirc(float start, float end, float value) + { + value /= 0.5f; + end -= start; + if (value < 1f) + { + return (0f - end) * 0.5f * (Mathf.Sqrt(1f - value * value) - 1f) + start; + } + value -= 2f; + return end * 0.5f * (Mathf.Sqrt(1f - value * value) + 1f) + start; + } + + private float easeInBounce(float start, float end, float value) + { + end -= start; + float num = 1f; + return end - easeOutBounce(0f, end, num - value) + start; + } + + private float easeOutBounce(float start, float end, float value) + { + value /= 1f; + end -= start; + if (value < 0.363636374f) + { + return end * (7.5625f * value * value) + start; + } + if (value < 0.727272749f) + { + value -= 0.545454562f; + return end * (7.5625f * value * value + 0.75f) + start; + } + if ((double)value < 0.90909090909090906) + { + value -= 0.8181818f; + return end * (7.5625f * value * value + 0.9375f) + start; + } + value -= 0.954545438f; + return end * (7.5625f * value * value + 0.984375f) + start; + } + + private float easeInOutBounce(float start, float end, float value) + { + end -= start; + float num = 1f; + if (value < num * 0.5f) + { + return easeInBounce(0f, end, value * 2f) * 0.5f + start; + } + return easeOutBounce(0f, end, value * 2f - num) * 0.5f + end * 0.5f + start; + } + + private float easeInBack(float start, float end, float value) + { + end -= start; + value /= 1f; + float num = 1.70158f; + return end * value * value * ((num + 1f) * value - num) + start; + } + + private float easeOutBack(float start, float end, float value) + { + float num = 1.70158f; + end -= start; + value -= 1f; + return end * (value * value * ((num + 1f) * value + num) + 1f) + start; + } + + private float easeInOutBack(float start, float end, float value) + { + float num = 1.70158f; + end -= start; + value /= 0.5f; + if (value < 1f) + { + num *= 1.525f; + return end * 0.5f * (value * value * ((num + 1f) * value - num)) + start; + } + value -= 2f; + num *= 1.525f; + return end * 0.5f * (value * value * ((num + 1f) * value + num) + 2f) + start; + } + + private float punch(float amplitude, float value) + { + float num = 9f; + if (value == 0f) + { + return 0f; + } + if (value == 1f) + { + return 0f; + } + float num2 = 0.3f; + num = num2 / 6.28318548f * Mathf.Asin(0f); + return amplitude * Mathf.Pow(2f, -10f * value) * Mathf.Sin((value * 1f - num) * 6.28318548f / num2); + } + + private float easeInElastic(float start, float end, float value) + { + end -= start; + float num = 1f; + float num2 = num * 0.3f; + float num3 = 0f; + float num4 = 0f; + if (value == 0f) + { + return start; + } + if ((value /= num) == 1f) + { + return start + end; + } + if (num4 == 0f || num4 < Mathf.Abs(end)) + { + num4 = end; + num3 = num2 / 4f; + } + else + { + num3 = num2 / 6.28318548f * Mathf.Asin(end / num4); + } + return 0f - num4 * Mathf.Pow(2f, 10f * (value -= 1f)) * Mathf.Sin((value * num - num3) * 6.28318548f / num2) + start; + } + + private float easeOutElastic(float start, float end, float value) + { + end -= start; + float num = 1f; + float num2 = num * 0.3f; + float num3 = 0f; + float num4 = 0f; + if (value == 0f) + { + return start; + } + if ((value /= num) == 1f) + { + return start + end; + } + if (num4 == 0f || num4 < Mathf.Abs(end)) + { + num4 = end; + num3 = num2 * 0.25f; + } + else + { + num3 = num2 / 6.28318548f * Mathf.Asin(end / num4); + } + return num4 * Mathf.Pow(2f, -10f * value) * Mathf.Sin((value * num - num3) * 6.28318548f / num2) + end + start; + } + + private float easeInOutElastic(float start, float end, float value) + { + end -= start; + float num = 1f; + float num2 = num * 0.3f; + float num3 = 0f; + float num4 = 0f; + if (value == 0f) + { + return start; + } + if ((value /= num * 0.5f) == 2f) + { + return start + end; + } + if (num4 == 0f || num4 < Mathf.Abs(end)) + { + num4 = end; + num3 = num2 / 4f; + } + else + { + num3 = num2 / 6.28318548f * Mathf.Asin(end / num4); + } + if (value < 1f) + { + return -0.5f * (num4 * Mathf.Pow(2f, 10f * (value -= 1f)) * Mathf.Sin((value * num - num3) * 6.28318548f / num2)) + start; + } + return num4 * Mathf.Pow(2f, -10f * (value -= 1f)) * Mathf.Sin((value * num - num3) * 6.28318548f / num2) * 0.5f + end + start; + } +}