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

Contents of /trunk/libTES3FileFormat/PlugingClothing.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (show annotations) (download)
Fri Jul 29 18:22:20 2011 UTC (9 years ago) by william
File size: 16117 byte(s)
*** add list support to hold clothing entry data and implement in parser class

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

  ViewVC Help
Powered by ViewVC 1.1.22