Advertisement
Guest User

Untitled

a guest
Feb 16th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.31 KB | None | 0 0
  1. public class D2OUnpacker : IFileUnpacker<D2OClass>
  2.     {
  3.         private int _contentPosition;
  4.         private const string FileHeader = "D2O";
  5.         private const string FileSignature = "AKSF";
  6.  
  7.         public D2OClassDefinition ClassDefinition { get; private set; }
  8.         public IReadOnlyCollection<D2OClass> Unpacked { get; private set; }
  9.  
  10.         public void Unpack(IReader reader)
  11.         {
  12.             if(!_tryParseHeader(reader)) throw new InvalidOperationException("d2o file is corrupted");
  13.  
  14.             var classPointers = _parseClassPointers(reader);
  15.             var classCount = reader.ReadValue<int>();
  16.  
  17.             ClassDefinition = _parseClassDefinition(reader);
  18.  
  19.             var unpacked = new List<D2OClass>(classCount);
  20.             foreach (var pointer in classPointers)
  21.             {
  22.                 reader.Seek(pointer.Value);
  23.                 unpacked.Add(_parseClassValues(reader, pointer.Key));
  24.             }
  25.  
  26.             Unpacked = unpacked;
  27.         }
  28.  
  29.         #region Private Methods
  30.         private bool _tryParseHeader(IReader reader)
  31.         {
  32.             var fileHeader = Encoding.ASCII.GetString(reader.ReadValues<byte>(3));
  33.             if (fileHeader == FileHeader) return true;
  34.  
  35.             reader.Seek(0);
  36.  
  37.             var signature = reader.ReadValue<string>();
  38.             if (signature != FileSignature) return false;
  39.  
  40.             reader.Seek(6); // skip formatVersion + len
  41.  
  42.             var realHeader = Encoding.ASCII.GetString(reader.ReadValues<byte>(3));
  43.             return realHeader != FileHeader;
  44.         }
  45.         private Dictionary<int, int> _parseClassPointers(IReader reader)
  46.         {
  47.             var tablePointerPosition = reader.ReadValue<int>();
  48.             reader.Seek(tablePointerPosition + _contentPosition);
  49.  
  50.             var objectPointersLen = reader.ReadValue<int>();
  51.             var classPointers = new Dictionary<int, int>(objectPointersLen);
  52.             for (var i = 0; i < objectPointersLen; i += 8)
  53.             {
  54.                 var key = reader.ReadValue<int>();
  55.                 var pointer = reader.ReadValue<int>();
  56.                 classPointers[key] = pointer + _contentPosition;
  57.             }
  58.  
  59.             return classPointers;
  60.         }
  61.         private D2OClassDefinition _parseClassDefinition(IReader reader)
  62.         {
  63.             reader.Skip(4);
  64.             var className = reader.ReadValue<string>();
  65.             var packageName = reader.ReadValue<string>();
  66.  
  67.             var fieldsCount = reader.ReadValue<int>();
  68.             var fields = new List<D2OFieldDefinition>(fieldsCount);
  69.             for (var i = 0; i < fieldsCount; i++)
  70.             {
  71.                 var fieldName = reader.ReadValue<string>();
  72.                 var fieldType = (D2OFieldValueType)reader.ReadValue<int>();
  73.                 if (fieldType == D2OFieldValueType.Vector)
  74.                 {
  75.                     reader.SkipString(); // skip inner field name
  76.                     fieldType = (D2OFieldValueType)reader.ReadValue<int>();
  77.                     fields.Add(new D2OFieldDefinition(fieldName, D2OFieldValueType.Vector, fieldType));
  78.                     continue;
  79.                 }
  80.                 fields.Add(new D2OFieldDefinition(fieldName, fieldType, D2OFieldValueType.None));
  81.             }
  82.  
  83.             return new D2OClassDefinition(className, packageName, fields);
  84.         }
  85.         private D2OClass _parseClassValues(IReader reader, int classId)
  86.         {
  87.             reader.Skip(4); // skip class identifier
  88.  
  89.             var fields = new List<D2OField>(ClassDefinition.Fields.Count);
  90.             foreach(var field in ClassDefinition.Fields)
  91.             {
  92.                 if (field.Type != D2OFieldValueType.Vector)
  93.                 {
  94.                     var value = reader.ReadFrom(field.Type);
  95.                     fields.Add(new D2OField(field.Name, field.Type, value));
  96.                     continue;
  97.                 }
  98.  
  99.                 var len = reader.ReadValue<int>();
  100.                 var innerFieldValue = new object[len];
  101.                 for (var i = 0; i < len; i++)
  102.                     innerFieldValue[i] = reader.ReadFrom(field.InnerType);
  103.  
  104.                 fields.Add(new D2OField(field.Name, D2OFieldValueType.Vector, field.Type, innerFieldValue));
  105.             }
  106.  
  107.             return new D2OClass(classId, fields);
  108.         }
  109.         #endregion
  110.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement