-
Notifications
You must be signed in to change notification settings - Fork 4
/
SafeInt.cs
170 lines (165 loc) · 3.49 KB
/
SafeInt.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class SafeInt {
[System.Serializable]
public class SafeValue
{
public int sv = 0;
}
[SerializeField]
private SafeValue _safeIntValue;
[SafeField("EncryptInEditor")]
public int safeInt;
//在editor里测试时更改safeInt的值即可,不要更改_safeIntValue和 _hash,真机运行时一定要在使用前重新生成实例,不能直接使用editor里的设置
//例如,在editor里设置了safeInt为10,真机时,一定要在start或awake中重新赋值,safeInt=10,否则会闪退
private int _safeInt{
get{
return (_safeIntValue.sv+5)^_key;
}
set{
SafeValue sh = GetSafeValue ();
sh.sv = (value^_key)-5;
if(_safeIntValue!=null)
safeValueStack.Push (_safeIntValue);
_safeIntValue = sh;
}
}
[SerializeField]
private int _hash;
private static int _key;
private static Stack<SafeValue> safeValueStack = new Stack<SafeValue>();
private static int zeroCipher;
private static int zeroHash;
static SafeInt()
{
_key = Random.Range (76005,5313000);
#if UNITY_EDITOR
_key = 15731;
#endif
zeroCipher = (0^_key)-5;
int x = 0;
x = (x << 13) ^ x;
zeroHash = (int)((1f - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824f)*10000000f)^_key;
}
public static SafeInt zero()
{
return new SafeInt(0);
}
private static SafeValue GetSafeValue()
{
if (safeValueStack.Count > 0)
return safeValueStack.Pop ();
return new SafeValue ();
}
public SafeInt(int i)
{
safeInt = Random.Range (76005,5313000);
_safeInt = i;
Encrypt ();
}
/// <summary>
/// Check if the int is zero.
/// </summary>
public bool IsZero()
{
if (_safeIntValue.sv == zeroCipher && _hash == zeroHash)
return true;
return false;
}
public bool IsCheat()
{
if (_hash == Noise(_safeInt))
return false;
Debug.Log ("cheat!You cant init safeInt value in the inspector,init this value in the \"Start\" func instead");
return true;
}
public int Noise(int x)
{
x = (x << 13) ^ x;
return (int)((1f - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824f)*10000000f)^_key;
}
public void Encrypt()
{
#if UNITY_EDITOR
safeInt = _safeInt;
#endif
_hash = Noise (_safeInt);
}
public void EncryptInEditor()
{
#if UNITY_EDITOR
_safeInt = safeInt;
#endif
_hash = Noise (_safeInt);
}
public int Get()
{
if (IsCheat ())
Application.Quit ();
return _safeInt;
}
public void Add(int i)
{
if (IsCheat ())
Application.Quit ();
_safeInt += i;
Encrypt ();
}
public void Decrease(int i)
{
if (IsCheat ())
Application.Quit ();
_safeInt -= i;
Encrypt ();
}
public void Multiply(int i)
{
if (IsCheat ())
Application.Quit ();
_safeInt *= i;
Encrypt ();
}
public void Divided(int i)
{
if (IsCheat ())
Application.Quit ();
_safeInt /= i;
Encrypt ();
}
public static int operator +(SafeInt lhs,int rhs)
{
return lhs.Get()+rhs;
}
public static int operator -(SafeInt lhs,int rhs)
{
return lhs.Get()-rhs;
}
public static int operator *(SafeInt lhs,int rhs)
{
return lhs.Get()*rhs;
}
public static int operator /(SafeInt lhs,int rhs)
{
return lhs.Get()/rhs;
}
public static SafeInt operator ++(SafeInt i)
{
i.Add (1);
return i;
}
public static SafeInt operator --(SafeInt i)
{
i.Decrease (1);
return i;
}
public static implicit operator int(SafeInt i)
{
return i.Get();
}
public static implicit operator SafeInt(int i)
{
return new SafeInt (i);
}
}