@@ -17,6 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
17
using System ;
18
18
using System . Diagnostics ;
19
19
using System . IO ;
20
+ using System . Runtime . CompilerServices ;
20
21
using System . Text ;
21
22
using MapleLib . MapleCryptoLib ;
22
23
using MapleLib . PacketLib ;
@@ -78,68 +79,73 @@ public string ReadStringAtOffset(long Offset, bool readByte)
78
79
return ReturnString ;
79
80
}
80
81
82
+ /// <summary>
83
+ /// Reads a string from the buffer
84
+ /// </summary>
85
+ /// <returns></returns>
81
86
public override string ReadString ( )
82
87
{
83
88
sbyte smallLength = base . ReadSByte ( ) ;
84
-
85
89
if ( smallLength == 0 )
86
- {
87
90
return string . Empty ;
88
- }
89
91
90
92
int length ;
91
- StringBuilder retString = new StringBuilder ( ) ;
92
93
if ( smallLength > 0 ) // Unicode
94
+ length = smallLength == sbyte . MaxValue ? ReadInt32 ( ) : smallLength ;
95
+ else // ASCII
96
+ length = smallLength == sbyte . MinValue ? ReadInt32 ( ) : - smallLength ;
97
+
98
+ if ( length <= 0 )
99
+ return string . Empty ;
100
+
101
+ if ( smallLength > 0 ) // Unicode
102
+ return DecodeUnicode ( length ) ;
103
+ else
104
+ return DecodeAscii ( length ) ;
105
+ }
106
+
107
+ /// <summary>
108
+ /// Decodes unicode string
109
+ /// </summary>
110
+ /// <param name="length"></param>
111
+ /// <returns></returns>
112
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
113
+ private string DecodeUnicode ( int length )
114
+ {
115
+ Span < char > chars = length <= 1024 ? stackalloc char [ length ] : new char [ length ] ;
116
+ ushort mask = 0xAAAA ;
117
+
118
+ for ( int i = 0 ; i < length ; i ++ )
93
119
{
94
- ushort mask = 0xAAAA ;
95
- if ( smallLength == sbyte . MaxValue )
96
- {
97
- length = ReadInt32 ( ) ;
98
- }
99
- else
100
- {
101
- length = ( int ) smallLength ;
102
- }
103
- if ( length <= 0 )
104
- {
105
- return string . Empty ;
106
- }
107
-
108
- for ( int i = 0 ; i < length ; i ++ )
109
- {
110
- ushort encryptedChar = ReadUInt16 ( ) ;
111
- encryptedChar ^= mask ;
112
- encryptedChar ^= ( ushort ) ( ( WzKey [ ( i * 2 + 1 ) ] << 8 ) + WzKey [ ( i * 2 ) ] ) ;
113
- retString . Append ( ( char ) encryptedChar ) ;
114
- mask ++ ;
115
- }
120
+ ushort encryptedChar = ReadUInt16 ( ) ;
121
+ encryptedChar ^= mask ;
122
+ encryptedChar ^= ( ushort ) ( ( WzKey [ ( i * 2 + 1 ) ] << 8 ) + WzKey [ ( i * 2 ) ] ) ;
123
+ chars [ i ] = ( char ) encryptedChar ;
124
+ mask ++ ;
116
125
}
117
- else
118
- { // ASCII
119
- byte mask = 0xAA ;
120
- if ( smallLength == sbyte . MinValue )
121
- {
122
- length = ReadInt32 ( ) ;
123
- }
124
- else
125
- {
126
- length = ( int ) ( - smallLength ) ;
127
- }
128
- if ( length <= 0 )
129
- {
130
- return string . Empty ;
131
- }
126
+ return new string ( chars ) ;
127
+ }
132
128
133
- for ( int i = 0 ; i < length ; i ++ )
134
- {
135
- byte encryptedChar = ReadByte ( ) ;
136
- encryptedChar ^= mask ;
137
- encryptedChar ^= ( byte ) WzKey [ i ] ;
138
- retString . Append ( ( char ) encryptedChar ) ;
139
- mask ++ ;
140
- }
129
+ /// <summary>
130
+ /// Decodes Ascii string
131
+ /// </summary>
132
+ /// <param name="length"></param>
133
+ /// <returns></returns>
134
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
135
+ private string DecodeAscii ( int length )
136
+ {
137
+ Span < byte > bytes = length <= 1024 ? stackalloc byte [ length ] : new byte [ length ] ;
138
+ byte mask = 0xAA ;
139
+
140
+ for ( int i = 0 ; i < length ; i ++ )
141
+ {
142
+ byte encryptedChar = ReadByte ( ) ;
143
+ encryptedChar ^= mask ;
144
+ encryptedChar ^= ( byte ) WzKey [ i ] ;
145
+ bytes [ i ] = encryptedChar ;
146
+ mask ++ ;
141
147
}
142
- return retString . ToString ( ) ;
148
+ return Encoding . ASCII . GetString ( bytes ) ;
143
149
}
144
150
145
151
/// <summary>
@@ -153,14 +159,15 @@ public string ReadString(int length)
153
159
154
160
public string ReadNullTerminatedString ( )
155
161
{
156
- StringBuilder retString = new StringBuilder ( ) ;
157
- byte b = ReadByte ( ) ;
158
- while ( b != 0 )
162
+ using ( var memoryStream = new MemoryStream ( ) )
159
163
{
160
- retString . Append ( ( char ) b ) ;
161
- b = ReadByte ( ) ;
164
+ byte b ;
165
+ while ( ( b = ReadByte ( ) ) != 0 )
166
+ {
167
+ memoryStream . WriteByte ( b ) ;
168
+ }
169
+ return Encoding . UTF8 . GetString ( memoryStream . GetBuffer ( ) , 0 , ( int ) memoryStream . Length ) ;
162
170
}
163
- return retString . ToString ( ) ;
164
171
}
165
172
166
173
public int ReadCompressedInt ( )
@@ -206,33 +213,38 @@ public long ReadOffset()
206
213
return ( offset + startOffset ) ;
207
214
}
208
215
216
+ /// <summary>
217
+ /// Decrypts List.wz string without mask
218
+ /// </summary>
219
+ /// <param name="stringToDecrypt"></param>
220
+ /// <returns></returns>
209
221
public string DecryptString ( char [ ] stringToDecrypt )
210
222
{
211
- StringBuilder outputString = new StringBuilder ( ) ;
223
+ Span < char > outputChars = stringToDecrypt . Length <= 1024
224
+ ? stackalloc char [ stringToDecrypt . Length ]
225
+ : new char [ stringToDecrypt . Length ] ;
212
226
213
- int i = 0 ;
214
- foreach ( char c in stringToDecrypt )
227
+ for ( int i = 0 ; i < stringToDecrypt . Length ; i ++ )
215
228
{
216
- outputString . Append ( ( char ) ( c ^ ( ( char ) ( ( WzKey [ i * 2 + 1 ] << 8 ) + WzKey [ i * 2 ] ) ) ) ) ;
217
- i ++ ;
229
+ outputChars [ i ] = ( char ) ( stringToDecrypt [ i ] ^ ( ( char ) ( ( WzKey [ i * 2 + 1 ] << 8 ) + WzKey [ i * 2 ] ) ) ) ;
218
230
}
219
- return outputString . ToString ( ) ;
231
+
232
+ return new string ( outputChars ) ;
220
233
}
221
234
222
235
223
236
public string DecryptNonUnicodeString ( char [ ] stringToDecrypt )
224
237
{
225
- // Initialize the output string with the correct capacity
226
- StringBuilder outputString = new StringBuilder ( stringToDecrypt . Length ) ;
238
+ Span < char > outputChars = stringToDecrypt . Length <= 1024
239
+ ? stackalloc char [ stringToDecrypt . Length ]
240
+ : new char [ stringToDecrypt . Length ] ;
227
241
228
242
for ( int i = 0 ; i < stringToDecrypt . Length ; i ++ )
229
243
{
230
- // Append the decrypted character to the StringBuilder object
231
- outputString . Append ( ( char ) ( stringToDecrypt [ i ] ^ WzKey [ i ] ) ) ;
244
+ outputChars [ i ] = ( char ) ( stringToDecrypt [ i ] ^ WzKey [ i ] ) ;
232
245
}
233
246
234
- // Convert the StringBuilder object to a string and return it
235
- return outputString . ToString ( ) ;
247
+ return new string ( outputChars ) ;
236
248
}
237
249
238
250
public string ReadStringBlock ( long offset )
@@ -306,8 +318,8 @@ public void PrintHexBytes(int numberOfBytes)
306
318
this . BaseStream . Position -= numberOfBytes ;
307
319
#endif
308
320
}
309
- #endregion
310
-
321
+ #endregion
322
+
311
323
#region Overrides
312
324
public override void Close ( )
313
325
{
0 commit comments