/[MorrowindCustomClothingSlotCreator]/trunk/libTES3FileFormat/PlugingClothing.cs
ViewVC logotype

Contents of /trunk/libTES3FileFormat/PlugingClothing.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations) (download)
Sat Jul 30 09:15:16 2011 UTC (8 years, 6 months ago) by william
File size: 16640 byte(s)
*** Change ClothingEntries make it Dictionary<string, ClothingEntry> ClothingEntries { get; }

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.IO;
6 using System.Diagnostics;
7 using System.Windows.Forms;
8
9 namespace libTES3FileFormat
10 {
11
12 public enum ClothingTypes
13 {
14 Pants, /* 0 */
15 Shoes, /* 1 */
16 Shirt, /* 2 */
17 Belt, /* 3 */
18 Robe, /* 4 */
19 RightGlove, /* 5 */
20 LeftGlove, /* 6 */
21 Skirt, /* 7 */
22 Ring, /* 8 */
23 Amulet, /* 9 */
24 }
25
26 public interface IClothingEntry : IOffset
27 {
28 byte[] CLOT_MAGIC { get; } // 4bytes, CLOT
29 byte[] CLOT_SIZE { get; set; } // 12 bytes
30
31 byte[] CLOT_NAME_MAGIC { get; } // 4bytes, NAME
32 int CLOT_NAME_LENGTH { get; }//4 bytes, name length
33 string CLOT_NAME { get; set; } // variable length, null terminated
34
35 byte[] CLOT_MODL_MAGIC { get; } // 4bytes, MODL
36 int CLOT_MODL_LENGTH { get; }//4 bytes, MODL length
37 string CLOT_MODL { get; set; } // variable length, null terminated
38
39 byte[] CLOT_FULLNAME_MAGIC { get; } // 4bytes, FNAM
40 int CLOT_FULLNAME_LENGTH { get; }//4 bytes, FNAM length
41 string CLOT_FULLNAME { get; set; } // variable length, null terminated
42
43 byte[] CLOT_CTDT_MAGIC { get; } // 4bytes, CTDT
44 int CLOT_CTDT_TYPE { get; set; }//4 bytes
45 float CLOT_CTDT_WEIGHT { get; set; }//4 bytes
46 short CLOT_CTDT_VALUE { get; set; }//2 bytes
47 short CLOT_CTDT_ENCHANTPTS { get; set; }//2 bytes
48
49 byte[] CLOT_OTHER_DATA { get; set; } // the rest of the clothing data entry
50 }
51 public class ClothingEntry : IClothingEntry, IComparable
52 {
53 #region IComparable Members
54
55 public int CompareTo(object obj) { return this.CLOT_NAME.CompareTo((obj as ClothingEntry).CLOT_NAME); }
56
57 #endregion
58 public ClothingEntry()
59 {
60 this.Offset = 0;
61 this.CLOT_SIZE = new byte[12];
62 this.CLOT_NAME = "";
63 this.CLOT_MODL = "";
64 this.CLOT_FULLNAME = "";
65 this.CLOT_CTDT_TYPE = (int)ClothingTypes.Amulet;
66 this.CLOT_CTDT_WEIGHT = 0;
67 this.CLOT_CTDT_VALUE = 0;
68 this.CLOT_CTDT_ENCHANTPTS = 0;
69 this.CLOT_OTHER_DATA = new byte[0];
70 }
71 #region IOffset Members
72 private int _Offset;
73 public int Offset { get { return _Offset; } set { _Offset = value; } }
74 #endregion
75 #region IClothingEntry Members
76 public byte[] CLOT_MAGIC { get { return ASCIIEncoding.ASCII.GetBytes("CLOT"); } } // 4bytes, CLOT
77 private byte[] _CLOT_SIZE;
78 public byte[] CLOT_SIZE { get { return _CLOT_SIZE; } set { _CLOT_SIZE = value; Debug.Assert(value.Length == 12, "Excepted CLOT_SIZE of 12 bytes. Found: " + value.Length + " bytes"); } }// 12 bytes
79
80 public byte[] CLOT_NAME_MAGIC { get { return ASCIIEncoding.ASCII.GetBytes("NAME"); } } // 4bytes, NAME
81 public int CLOT_NAME_LENGTH { get { return CLOT_NAME.Length; } }//4 bytes, name length
82 private string _CLOT_NAME;
83 public string CLOT_NAME { get { return _CLOT_NAME; } set { _CLOT_NAME = value; } } // variable length, null terminated
84
85 public byte[] CLOT_MODL_MAGIC { get { return ASCIIEncoding.ASCII.GetBytes("MODL"); } } // 4bytes, MODL
86 public int CLOT_MODL_LENGTH { get { return CLOT_MODL.Length; } }//4 bytes, MODL length
87 private string _CLOT_MODL;
88 public string CLOT_MODL { get { return _CLOT_MODL; } set { _CLOT_MODL = value; } } // variable length, null terminated
89
90 public byte[] CLOT_FULLNAME_MAGIC { get { return ASCIIEncoding.ASCII.GetBytes("FNAM"); } } // 4bytes, FNAM
91 public int CLOT_FULLNAME_LENGTH { get { return CLOT_FULLNAME.Length; } }//4 bytes, FNAM length
92 private string _CLOT_FULLNAME;
93 public string CLOT_FULLNAME { get { return _CLOT_FULLNAME; } set { _CLOT_FULLNAME = value; } } // variable length, null terminated
94
95 public byte[] CLOT_CTDT_MAGIC { get { return ASCIIEncoding.ASCII.GetBytes("CTDT"); } } // 4bytes, CTDT
96
97 private int _CLOT_CTDT_SIZE;
98 private int _CLOT_CTDT_TYPE;
99 private float _CLOT_CTDT_WEIGHT;
100 private short _CLOT_CTDT_VALUE;
101 private short _CLOT_CTDT_ENCHANTPTS;
102
103 public int CLOT_CTDT_SIZE { get { return _CLOT_CTDT_SIZE; } set { _CLOT_CTDT_SIZE = value; } }//4 bytes
104
105 public int CLOT_CTDT_TYPE { get { return _CLOT_CTDT_TYPE; } set { _CLOT_CTDT_TYPE = value; } }//4 bytes
106 public float CLOT_CTDT_WEIGHT { get { return _CLOT_CTDT_WEIGHT; } set { _CLOT_CTDT_WEIGHT = value; } }//4 bytes
107 public short CLOT_CTDT_VALUE { get { return _CLOT_CTDT_VALUE; } set { _CLOT_CTDT_VALUE = value; } }//2 bytes
108 public short CLOT_CTDT_ENCHANTPTS { get { return _CLOT_CTDT_ENCHANTPTS; } set { _CLOT_CTDT_ENCHANTPTS = value; } }//2 bytes
109
110 private byte[] _CLOT_OTHER_DATA;
111 public byte[] CLOT_OTHER_DATA { get { return _CLOT_OTHER_DATA; } set { _CLOT_OTHER_DATA = value; } } // the rest of the clothing data entry
112 #endregion
113
114
115 }
116
117 public interface IPlugingClothing : IParse, ICommit, IAsBytes, ISizeOffset
118 {
119 Dictionary<string, ClothingEntry> ClothingEntries { get; }
120 }
121 public class PlugingClothing : IPlugingClothing, ICommitParseAsBytes
122 {
123 private ConsoleLog Log;
124 private const string CLOTHING_MAGIC = "\0CLOT";
125 private const string CLOTHING_NAME_MAGIC = "NAME";
126 MemoryStream reader = new MemoryStream();
127 private List<int> SectionOffsets = new List<int>();
128 public PlugingClothing()
129 {
130 this.reader = new MemoryStream();
131 this.Offset = 0;
132 this.Size = 0;
133 this.SectionOffsets = new List<int>();
134 this.ClothingEntries = new Dictionary<string, ClothingEntry>();
135 }
136 public PlugingClothing(BinaryReader br, List<int> SectionOffsets, bool ReadOnly, ConsoleLog Log)
137 : this()
138 {
139 this.Log = Log;
140 br.BaseStream.Seek(0, SeekOrigin.Begin);
141 //this.Offset = offset;
142 //this.Size = size;
143 this.SectionOffsets = SectionOffsets;
144 this.reader = new MemoryStream(br.ReadBytes((int)br.BaseStream.Length), 0, (int)br.BaseStream.Length);
145 this.Parse(this.reader);
146 }
147 #region IPlugingClothing Members
148 private Dictionary<string, ClothingEntry> _ClothingEntries;
149 public Dictionary<string, ClothingEntry> ClothingEntries
150 {
151 get { return _ClothingEntries; }
152 private set { _ClothingEntries = value; }
153 }
154
155 #endregion
156 #region IParse Members
157
158 public bool Parse(MemoryStream stream)
159 {
160 BinaryReader br = new BinaryReader(stream);
161 this.Log.WriteLine();
162 // read header section magic
163
164 for (int i = 0; i < this.SectionOffsets.Count; i++)
165 {
166 ClothingEntry entry = new ClothingEntry();
167
168 entry.Offset = this.SectionOffsets[i]; // set the offset for this entry
169
170 br.BaseStream.Seek(this.SectionOffsets[i], SeekOrigin.Begin);
171 this.Log.WriteLine(string.Format("Clothing Section: Index=0x{0:x8} Offset=0x{1:x8}", i,(int)br.BaseStream.Position));
172
173 byte[] magic = br.ReadBytes(4);
174 string str_magic = ASCIIEncoding.ASCII.GetString(magic);
175 Debug.Assert(str_magic == "CLOT", string.Format("Excepted: {0} found: {1}", "CLOT", str_magic));
176
177 // Clothing Name
178 byte[] section_size_bytes = br.ReadBytes(12);
179 int section_size = BitConverter.ToInt32(section_size_bytes, 0);
180
181 entry.CLOT_SIZE = section_size_bytes; // set the clot size
182
183 int name_offset = (int)br.BaseStream.Position;
184 magic = br.ReadBytes(4);
185 str_magic = ASCIIEncoding.ASCII.GetString(magic);
186 Debug.Assert(str_magic == "NAME", string.Format("Excepted: {0} found: {1}", "NAME", str_magic));
187
188 int name_size = br.ReadInt32();
189
190 this.Log.WriteLine("\t\tClothing Name Size: " + name_size.ToString());
191 byte[] name_bytes = br.ReadBytes(name_size);
192 string ClothingName = ASCIIEncoding.ASCII.GetString(name_bytes);
193
194 entry.CLOT_NAME = ClothingName; // set the NAME
195
196 this.Log.WriteLine("\t\tClothing Name : " + ClothingName);
197
198
199 // Clothing Model
200 magic = br.ReadBytes(4);
201 str_magic = ASCIIEncoding.ASCII.GetString(magic);
202 Debug.Assert(str_magic == "MODL", string.Format("Excepted: {0} found: {1}", "MODL", str_magic));
203
204 int modl_name_size = br.ReadInt32();
205 this.Log.WriteLine("\t\tClothing Model Name Size: " + modl_name_size.ToString());
206 byte[] modl_name_bytes = br.ReadBytes(modl_name_size);
207 string ClothingModelName = ASCIIEncoding.ASCII.GetString(modl_name_bytes);
208
209 entry.CLOT_MODL = ClothingModelName; // set the MODL
210
211 this.Log.WriteLine("\t\tClothing Model Name: " + ClothingModelName);
212
213 // Clothing Full Name
214 magic = br.ReadBytes(4);
215 str_magic = ASCIIEncoding.ASCII.GetString(magic);
216 Debug.Assert(str_magic == "FNAM", string.Format("Excepted: {0} found: {1}", "FNAM", str_magic));
217
218 int fname_size = br.ReadInt32();
219 this.Log.WriteLine("\t\tClothing FullName Size: " + fname_size.ToString());
220 byte[] fname_bytes = br.ReadBytes(fname_size);
221 string ClothingFullName = ASCIIEncoding.ASCII.GetString(fname_bytes);
222 entry.CLOT_FULLNAME = ClothingFullName; // set the full name
223 this.Log.WriteLine("\t\tClothing FullName: " + ClothingFullName);
224
225 // Clothing Data
226 magic = br.ReadBytes(4);
227 str_magic = ASCIIEncoding.ASCII.GetString(magic);
228 Debug.Assert(str_magic == "CTDT", string.Format("Excepted: {0} found: {1}", "CTDT", str_magic));
229
230 int ctdt_size = br.ReadInt32();
231
232 int ctdt_type = br.ReadInt32();
233 string ctdt_type_string = "";
234
235 try
236 {
237 ctdt_type_string = Enum.GetName(typeof(ClothingTypes), ctdt_type);
238 }
239 catch { ctdt_type_string = "unknown"; }
240
241
242 float ctdt_weight = br.ReadSingle();
243 short ctdt_value = br.ReadInt16();
244 short ctdt_echant_pts = br.ReadInt16();
245
246
247 entry.CLOT_CTDT_SIZE = ctdt_size; // set the size
248 entry.CLOT_CTDT_TYPE = ctdt_type; // set the type
249 entry.CLOT_CTDT_WEIGHT = ctdt_weight; // set the weight
250 entry.CLOT_CTDT_VALUE = ctdt_value; // set the value
251 entry.CLOT_CTDT_ENCHANTPTS = ctdt_echant_pts; // set the enchant pts
252
253 this.Log.WriteLine("\t\tClothing Data: ");
254 this.Log.WriteLine("\t\t\tType: " + ctdt_type + " (" + ctdt_type_string +")");
255 this.Log.WriteLine("\t\t\tWeight: " + ctdt_weight);
256 this.Log.WriteLine("\t\t\tValue: " + ctdt_value);
257 this.Log.WriteLine("\t\t\tEnchant Points: " + ctdt_echant_pts);
258
259
260
261 //magic = br.ReadBytes(4);
262 //str_magic = ASCIIEncoding.ASCII.GetString(magic);
263 //Debug.Assert(str_magic == "SCRI", string.Format("Excepted: {0} found: {1}", "SCRI", str_magic));
264 //br.BaseStream.Position = br.BaseStream.Position - 4; // back up 4 bytes
265 //int length_till_end_of_section = (name_offset + section_size) + 0x10;
266 int length_till_end_of_section = (name_offset + section_size) - (int)br.BaseStream.Position;
267
268
269 //try
270 //{
271 byte[] extra_clothing_data = br.ReadBytes(length_till_end_of_section);
272 entry.CLOT_OTHER_DATA = extra_clothing_data; // set the extra data
273 //}
274 //catch { break; }
275
276 //break;
277 this.ClothingEntries.Add(entry.CLOT_NAME, entry);
278 //this.ClothingEntries.Sort(); // sorting should not cause any major issues, since each entry holds its own offset
279 }
280
281
282 return true;
283 }
284
285 #endregion
286
287 #region ICommit Members
288
289 public bool Commit(BinaryWriter writer)
290 {
291 throw new NotImplementedException();
292 }
293
294 #endregion
295
296 #region IAsBytes Members
297
298 public byte[] AsBytes
299 {
300 get
301 {
302 this.reader.Seek(0, SeekOrigin.Begin);
303 BinaryReader br = new BinaryReader(this.reader);
304 return br.ReadBytes(this.Size);
305 }
306 }
307
308 #endregion
309
310 #region ISizeOffset Members
311
312 private int _Size;
313 public int Size { get { return _Size; } private set { _Size = value; } } // headersize
314
315 private int _Offset;
316 public int Offset { get { return _Offset; } private set { _Offset = value; } }
317 public int OffsetToNext { get { return this.Size + this.Offset; } } // force this to 16 bytes
318 #endregion
319
320 #region Sub-Classes
321 public class SectionLocater : IParse, IOffset, ISize
322 {
323 private ConsoleLog Log;
324 MemoryStream reader = new MemoryStream();
325 public SectionLocater()
326 {
327 this.reader = new MemoryStream();
328 this.Log = new ConsoleLog();
329 this.ClothingSectionOffsets = new List<int>();
330
331 }
332 public SectionLocater(BinaryReader br, int CurrentOffset, ConsoleLog Log) : this()
333 {
334 this.Log = Log;
335 br.BaseStream.Seek(0, SeekOrigin.Begin);
336 this.Offset = CurrentOffset;
337 this.reader = new MemoryStream(br.ReadBytes((int)br.BaseStream.Length), CurrentOffset, (int)br.BaseStream.Length - CurrentOffset);
338 this.Parse(this.reader);
339 }
340
341 #region IParse Members
342
343 public bool Parse(MemoryStream stream)
344 {
345 BinaryReader br = new BinaryReader(stream);
346 this.Log.WriteLine();
347
348 byte[] data = br.ReadBytes((int)br.BaseStream.Length);
349
350
351 this.ClothingSectionOffsets = new List<int>();
352
353 foreach (var position in data.Locate(ASCIIEncoding.ASCII.GetBytes(PlugingClothing.CLOTHING_MAGIC)))
354 {
355 this.ClothingSectionOffsets.Add(position + 0x1); // add 1 byte to remove the \0,
356 }
357
358 if (this.ClothingSectionOffsets.Count == 0)
359 {
360 this.Log.WriteLine("\t\tNo Clothing Section Could be Found!");
361 }
362 else
363 {
364 this.Log.WriteLine("\t\tFound 0x" + this.ClothingSectionOffsets.Count.ToString("x2") + "clothing sections");
365 }
366
367 return true;
368 }
369
370 #endregion
371
372
373
374 #region IOffset Members
375 private int _Offset;
376 public int Offset
377 {
378 get { return _Offset; }
379 private set { _Offset = value; }
380 }
381 private int _Size;
382 public int Size
383 {
384 get { return _Size; }
385 private set { _Size = value; }
386 }
387 private List<int> _ClothingSectionOffsets;
388 public List<int> ClothingSectionOffsets
389 {
390 get { return _ClothingSectionOffsets; }
391 private set { _ClothingSectionOffsets = value; }
392 }
393 #endregion
394 }
395 #endregion
396
397
398 }
399 }

  ViewVC Help
Powered by ViewVC 1.1.22