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

Annotation of /trunk/libTES3FileFormat/PlugingClothing.cs

Parent Directory Parent Directory | Revision Log Revision Log


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

1 william 17 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 william 18 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 william 17
26 william 20 public interface IClothingEntry : IOffset
27 william 17 {
28 william 20 byte[] CLOT_MAGIC { get; } // 4bytes, CLOT
29     byte[] CLOT_SIZE { get; set; } // 12 bytes
30 william 17
31 william 20 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 william 17 }
51 william 20 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 william 17 public class PlugingClothing : IPlugingClothing, ICommitParseAsBytes
115     {
116     private ConsoleLog Log;
117 william 19 private const string CLOTHING_MAGIC = "\0CLOT";
118 william 17 private const string CLOTHING_NAME_MAGIC = "NAME";
119     MemoryStream reader = new MemoryStream();
120 william 19 private List<int> SectionOffsets = new List<int>();
121 william 17 public PlugingClothing()
122     {
123     this.reader = new MemoryStream();
124     this.Offset = 0;
125     this.Size = 0;
126 william 19 this.SectionOffsets = new List<int>();
127 william 20 this.ClothingEntries = new List<ClothingEntry>();
128 william 17 }
129 william 19 public PlugingClothing(BinaryReader br, List<int> SectionOffsets, bool ReadOnly, ConsoleLog Log)
130 william 17 : this()
131     {
132     this.Log = Log;
133 william 19 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 william 17 this.Parse(this.reader);
139     }
140 william 20 #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 william 17
148 william 20 #endregion
149 william 17 #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 william 19 for (int i = 0; i < this.SectionOffsets.Count; i++)
158 william 18 {
159 william 20 ClothingEntry entry = new ClothingEntry();
160    
161     entry.Offset = this.SectionOffsets[i]; // set the offset for this entry
162    
163 william 19 br.BaseStream.Seek(this.SectionOffsets[i], SeekOrigin.Begin);
164 william 18 this.Log.WriteLine(string.Format("Clothing Section: Index=0x{0:x8} Offset=0x{1:x8}", i,(int)br.BaseStream.Position));
165 william 17
166 william 18 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 william 17
170 william 18 // Clothing Name
171 william 20 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 william 19 int name_offset = (int)br.BaseStream.Position;
177 william 18 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 william 20
183 william 18 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 william 20
187     entry.CLOT_NAME = ClothingName; // set the NAME
188    
189 william 18 this.Log.WriteLine("\t\tClothing Name : " + ClothingName);
190 william 17
191    
192 william 18 // 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 william 20
202     entry.CLOT_MODL = ClothingModelName; // set the MODL
203    
204 william 18 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 william 20 entry.CLOT_FULLNAME = ClothingFullName; // set the full name
216 william 18 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 william 20
225 william 18 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 william 20
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 william 18 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 william 19
253 william 18
254 william 19 //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 william 18
261 william 19
262 william 20 //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 william 19
269     //break;
270 william 20 this.ClothingEntries.Add(entry);
271 william 18 }
272    
273    
274 william 17 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 william 19 this.ClothingSectionOffsets = new List<int>();
322 william 20
323 william 17 }
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 william 19
342 william 17
343 william 19 this.ClothingSectionOffsets = new List<int>();
344 william 17
345     foreach (var position in data.Locate(ASCIIEncoding.ASCII.GetBytes(PlugingClothing.CLOTHING_MAGIC)))
346     {
347 william 19 this.ClothingSectionOffsets.Add(position + 0x1); // add 1 byte to remove the \0,
348 william 17 }
349    
350 william 19 if (this.ClothingSectionOffsets.Count == 0)
351 william 17 {
352 william 19 this.Log.WriteLine("\t\tNo Clothing Section Could be Found!");
353 william 17 }
354     else
355     {
356 william 19 this.Log.WriteLine("\t\tFound 0x" + this.ClothingSectionOffsets.Count.ToString("x2") + "clothing sections");
357     }
358 william 17
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 william 19 private List<int> _ClothingSectionOffsets;
380     public List<int> ClothingSectionOffsets
381 william 18 {
382 william 19 get { return _ClothingSectionOffsets; }
383     private set { _ClothingSectionOffsets = value; }
384 william 18 }
385 william 17 #endregion
386     }
387     #endregion
388 william 20
389    
390 william 17 }
391     }

  ViewVC Help
Powered by ViewVC 1.1.22