@@ -6,7 +6,7 @@ String StackDataCopyFormat;
66
77StackDataType GetType (this StackData*) {
88 if (this .Length < (StackDataFormat.Length - 1 )) return eStackDataInvalid;
9- StackData type = this .Substring (0 , StackDataFormat.Length - 1 );
9+ String type = this .Substring (0 , StackDataFormat.Length - 1 );
1010 int i = type.IndexOf (" :" );
1111 if (i == -1 ) return eStackDataInvalid;
1212 char c = type.Chars [i + 1 ];
@@ -70,48 +70,48 @@ GUIControl* GetAsGUIControl(this StackData*) {
7070}
7171
7272static StackData Stack::IntToData (int theInt) {
73- StackData type = StackData .Format (StackDataFormat, eStackDataInt);
74- return StackData .Format (" %s%d" , type, theInt);
73+ String type = String .Format (StackDataFormat, eStackDataInt);
74+ return String .Format (" %s%d" , type, theInt);
7575}
7676
7777static StackData Stack::FloatToData (float theFloat) {
78- StackData type = StackData .Format (StackDataFormat, eStackDataFloat);
79- return StackData .Format (" %s%f" , type, theFloat);
78+ String type = String .Format (StackDataFormat, eStackDataFloat);
79+ return String .Format (" %s%f" , type, theFloat);
8080}
8181
8282static StackData Stack::StringToData (String theString) {
83- StackData type = StackData .Format (StackDataFormat, eStackDataString);
83+ String type = String .Format (StackDataFormat, eStackDataString);
8484 return type.Append (theString);
8585}
8686
8787static StackData Stack::CharacterToData (Character *theCharacter) {
8888 if (theCharacter == null) return null;
89- StackData type = StackData .Format (StackDataFormat, eStackDataCharacter);
90- return StackData .Format (" %s%d" , type, theCharacter.ID );
89+ String type = String .Format (StackDataFormat, eStackDataCharacter);
90+ return String .Format (" %s%d" , type, theCharacter.ID );
9191}
9292
9393static StackData Stack::InventoryItemToData (InventoryItem *theItem) {
9494 if (theItem == null) return null;
95- StackData type = StackData .Format (StackDataFormat, eStackDataInventoryItem);
96- return StackData .Format (" %s%d" , type, theItem.ID );
95+ String type = String .Format (StackDataFormat, eStackDataInventoryItem);
96+ return String .Format (" %s%d" , type, theItem.ID );
9797}
9898
9999static StackData Stack::GUIToData (GUI *theGUI) {
100100 if (theGUI == null) return null;
101- StackData type = StackData .Format (StackDataFormat, eStackDataGUI);
102- return StackData .Format (" %s%d" , type, theGUI.ID );
101+ String type = String .Format (StackDataFormat, eStackDataGUI);
102+ return String .Format (" %s%d" , type, theGUI.ID );
103103}
104104
105105static StackData Stack::GUIControlToData (GUIControl *theControl) {
106106 if (theControl == null) return null;
107- StackData type = StackData .Format (StackDataFormat, eStackDataGUIControl);
108- return StackData .Format (" %s%d" , type, ((theControl.OwningGUI .ID * AGS_MAX_CONTROLS_PER_GUI) + theControl.ID ));
107+ String type = String .Format (StackDataFormat, eStackDataGUIControl);
108+ return String .Format (" %s%d" , type, ((theControl.OwningGUI .ID * AGS_MAX_CONTROLS_PER_GUI) + theControl.ID ));
109109}
110110
111111StackData MergeArray (this Stack*, StackData array[]) {
112112 if (array == null) return null;
113- StackData glue = StackDataDelimiter;
114- StackData buffer = " " ;
113+ String glue = StackDataDelimiter;
114+ String buffer = " " ;
115115 int i = 0 ;
116116 int size = this .ItemCount ;
117117 while (i < size) {
@@ -124,16 +124,16 @@ StackData MergeArray(this Stack*, StackData array[]) {
124124
125125StackData[] GetItemsArray(this Stack*) {
126126 if ((this .Data == null) || (!this .ItemCount )) return null;
127- StackData items[] = new StackData [this .ItemCount ];
128- StackData buffer = this .Data ;
127+ String items[] = new String [this .ItemCount ];
128+ String buffer = this .Data ;
129129 String format = StackDataFormat.Substring (0 , StackDataFormat.IndexOf (" :" ) + 1 );
130130 int i = buffer.IndexOf (format);
131131 int j = 0 ;
132132 while ((i != -1 ) && (j < this .ItemCount )) {
133133 StackDataType type = buffer.Chars [format.Length ];
134134 if (type == eStackDataStack) {
135- StackData temp = buffer.Substring (StackDataFormat.Length - 1 , buffer.Length );
136- StackData stamp = temp.Substring (0 , StackDataCopyFormat.Length + 14 ); // format + 16 byte key - %s
135+ String temp = buffer.Substring (StackDataFormat.Length - 1 , buffer.Length );
136+ String stamp = temp.Substring (0 , StackDataCopyFormat.Length + 14 ); // format + 16 byte key - %s
137137 temp = temp.Substring (stamp.Length , temp.Length );
138138 i = temp.IndexOf (stamp);
139139 if (i != -1 ) items[j] = buffer.Truncate (i + (StackDataFormat.Length - 1 ) + (stamp.Length * 2 ));
@@ -160,15 +160,108 @@ StackData[] GetItemsArray(this Stack*) {
160160 return items;
161161}
162162
163+ #ifndef StringPlus_VERSION
164+ String[] SplitByString(this String*, String otherString) {
165+ String s[];
166+ int i = this .IndexOf (otherString);
167+ if ((String.IsNullOrEmpty (otherString)) || (i == -1 )) {
168+ s = new String[2 ];
169+ s[0 ] = " 1" ;
170+ s[1 ] = this ;
171+ return s;
172+ }
173+ s = new String[this .Length + 1 ];
174+ String buffer = this ;
175+ int lineCount = 0 ;
176+ while (i != -1 ) {
177+ lineCount++;
178+ s[lineCount] = buffer.Substring (0 , i);
179+ i += otherString.Length ;
180+ if (i < buffer.Length ) {
181+ buffer = buffer.Substring (i, buffer.Length );
182+ i = buffer.IndexOf (otherString);
183+ }
184+ else i = -1 ;
185+ }
186+ lineCount++;
187+ s[lineCount] = buffer;
188+ String t[] = new String[lineCount + 1 ];
189+ i = 1 ;
190+ while (i <= lineCount) {
191+ t[i] = s[i];
192+ i++;
193+ }
194+ t[0 ] = String.Format (" %d" , lineCount);
195+ return t;
196+ }
197+
198+ String StringMergeArray (String array[], String glue) {
199+ if ((array == null) || (String.IsNullOrEmpty (array[0 ])) || (array[0 ].AsInt <= 0 )) return null;
200+ if (glue == null) glue = " " ;
201+ String buffer = " " ;
202+ int i = 1 ;
203+ int size = array[0 ].AsInt ;
204+ while (i <= size) {
205+ buffer = buffer.Append (array[i]);
206+ if (i < size) buffer = buffer.Append (glue);
207+ i++;
208+ }
209+ return buffer;
210+ }
211+ #endif
212+
213+ StackData BuildKey (this Stack*) { // returns a 128-bit (16-byte) key for Stack::Copy
214+ String key = " " ;
215+ int i = 0 ;
216+ while (i < 16 ) {
217+ char c = 0 ;
218+ int j = 7 ;
219+ while (j >= 0 ) { // build-a-byte
220+ DateTime *now = DateTime.Now ;
221+ bool bit = (Random (now.RawTime ) % 2 ); // returns either 1 or 0
222+ c += (bit << j); // then we shift that bit into place
223+ j--;
224+ }
225+ if (c) {
226+ key = key.AppendChar (c);
227+ i++;
228+ }
229+ }
230+ return key;
231+ }
232+
233+ StackData MaskStacksForCopy (this Stack*) {
234+ // regenerates any existing Stack keys (see BuildKey) when pushing a Stack object (copy) onto this stack
235+ // prevents issues with the data structure
236+ if (String.IsNullOrEmpty (this .Data )) return this .Data ;
237+ String s[] = this .Data .SplitByString (StackDataCopyFormat.Substring (0 , 18 )); // split the data by the stacks within it
238+ if (s[0 ].AsInt == 1 ) return this .Data ;
239+ int size = s[0 ].AsInt ;
240+ // structure of S will be:
241+ // 1: **STACKDATA:k** - the data type, a stack
242+ // 2: XXXXXXXXXXXXXXXX**DATA - the 128-bit (16-byte) key originally assigned here followed by the stack's data
243+ // 3: XXXXXXXXXXXXXXXX** - the same key
244+ // the rest of StackDataCopyFormat is removed by SplitByString
245+ int i = 2 ; // start at the first available key
246+ while (i < size) {
247+ String key = this .BuildKey (); // grab a new key
248+ s[i] = key.Append (s[i].Substring (16 , s[i].Length )); // replace both instances
249+ s[i + 1 ] = key.Append (s[i + 1 ].Substring (16 , s[i + 1 ].Length ));
250+ i += 3 ; // increasing by 3 sets I to the next "2" index in the structure
251+ }
252+ return StringMergeArray (s, StackDataCopyFormat.Substring (0 , 18 ));
253+ }
254+
163255bool Stack::Push (StackData data, int index) {
164256 if ((index == SCR_NO_VALUE) || (index > this .ItemCount )) index = this .ItemCount ;
165257 if ((index < 0 ) || (data == null)) return false ;
166- if (StackData .IsNullOrEmpty (this .Data )) {
258+ if (String .IsNullOrEmpty (this .Data )) {
167259 this .Data = data;
168260 this .ItemCount ++;
169261 return true ;
170262 }
171- StackData items[] = this .GetItemsArray ();
263+ if (data.GetType () == eStackDataStack) this .Data = this .MaskStacksForCopy (); // prevent issues if pushing the same stack multiple times
264+ String items[] = this .GetItemsArray ();
172265 int size = this .ItemCount ;
173266 if (index < size) items[index] = data;
174267 this .Data = this .MergeArray (items);
@@ -186,18 +279,18 @@ StackData Stack::Pop(bool remove, int index) {
186279 else if (this .PopType == eStackPopRandom) index = Random (this .ItemCount - 1 );
187280 }
188281 if ((index < 0 ) || (index >= this .ItemCount ) || (!this .ItemCount ) ||
189- (StackData .IsNullOrEmpty (this .Data ))) return null;
190- StackData items[] = this .GetItemsArray ();
282+ (String .IsNullOrEmpty (this .Data ))) return null;
283+ String items[] = this .GetItemsArray ();
191284 int size = this .ItemCount ;
192- StackData data = items[index];
285+ String data = items[index];
193286 if (remove) {
194287 this .ItemCount --;
195288 if ((!this .ItemCount ) || (size == 1 )) {
196289 this .Data = null;
197290 items = null; // prevent AGS 3.1.2 bug - Object not in managed pool.
198291 return data;
199292 }
200- StackData buffer[] = new StackData [this .ItemCount ];
293+ String buffer[] = new String [this .ItemCount ];
201294 int i = 0 ;
202295 while (i < this .ItemCount ) {
203296 if (i < index) buffer[i] = items[i];
@@ -220,42 +313,23 @@ bool Stack::IsEmpty() {
220313 return (!this .ItemCount );
221314}
222315
223- StackData BuildKey (this Stack*) { // returns a 128-bit (16-byte) key for Stack::Copy
224- StackData key = " " ;
225- int i = 0 ;
226- while (i < 16 ) {
227- char c = 0 ;
228- int j = 7 ;
229- while (j >= 0 ) { // build-a-byte
230- DateTime *now = DateTime.Now ;
231- bool bit = (Random (now.RawTime ) % 2 ); // returns either 1 or 0
232- c += (bit << j); // then we shift that bit into place
233- j--;
234- }
235- if (c) {
236- key = key.AppendChar (c);
237- i++;
238- }
239- }
240- return key;
241- }
242-
243316StackData Stack::Copy () {
244- StackData type = StackData .Format (StackDataFormat, eStackDataStack);
245- StackData key = this .BuildKey ();
246- StackData stamp = StackData .Format (StackDataCopyFormat, key);
247- StackData data = this .Data ;
317+ String type = String .Format (StackDataFormat, eStackDataStack);
318+ String key = this .BuildKey ();
319+ String stamp = String .Format (StackDataCopyFormat, key);
320+ String data = this .Data ;
248321 if (data == null) data = " " ;
249- return StackData.Format (" %s%s%d,%d,%s%s" , type, stamp, this .ItemCount , this .PopType , data, stamp);
322+ String s = type.Append (stamp.Append (String.Format (" %d,%d," , this .ItemCount , this .PopType )));
323+ return s.Append (data.Append (stamp));
250324}
251325
252326bool Stack::LoadFromStack (StackData otherStack) {
253327 if ((otherStack == null) || (otherStack.GetType () != eStackDataStack)) return false ;
254- StackData data = otherStack.Substring (StackDataFormat.Length - 1 , otherStack.Length );
255- StackData stamp = data.Substring (0 , StackDataCopyFormat.Length + 14 ); // format + 16 byte key - %s
328+ String data = otherStack.Substring (StackDataFormat.Length - 1 , otherStack.Length );
329+ String stamp = data.Substring (0 , StackDataCopyFormat.Length + 14 ); // format + 16 byte key - %s
256330 data = data.Substring (stamp.Length , data.Length );
257331 data = data.Truncate (data.IndexOf (stamp));
258- StackData buffer = data.Substring (0 , data.IndexOf (" ," ));
332+ String buffer = data.Substring (0 , data.IndexOf (" ," ));
259333 this .ItemCount = buffer.AsInt ;
260334 data = data.Substring (buffer.Length + 1 , data.Length );
261335 buffer = data.Substring (0 , data.IndexOf (" ," ));
@@ -272,7 +346,7 @@ bool WriteStack(this File*, StackData stackCopy) {
272346
273347StackData ReadStackBack (this File*) {
274348 if ((this .Error ) || (this .EOF )) AbortGame (" File::ReadStackBack: File was not written by File::WriteStack." );
275- StackData data = this .ReadStringBack ();
349+ String data = this .ReadStringBack ();
276350 if ((data == null) || (data.GetType () != eStackDataStack) || (this .Error )) AbortGame (" File::ReadStackBack: File was not written by File::WriteStack." );
277351 return data;
278352}
0 commit comments