public byte[] Write() { using (MemoryStream stream = new MemoryStream()) using (EndianBinaryWriter writer = new EndianBinaryWriter(stream, XData.Endianness)) { XData.Write(writer); int padding = Version[0] >= 7 ? 0 : -1; uint fileStart = (uint)writer.BaseStream.Position; writer.Write(padding); if (Version[0] >= 7) { writer.Write(Hash); } uint hSdataOffset = (uint)writer.BaseStream.Position; writer.Write(Version[0] >= 7 ? 0x28 : 0x20); writer.Write(padding); writer.Write(padding); if (Version[0] >= 7) { writer.Write(padding); } writer.Write(SData.Count); writer.Write(SData.ToArray()); writer.Write((uint)0); while ((writer.BaseStream.Length & 0xF) != 0x0 && (writer.BaseStream.Length & 0xF) != 0x4 && (writer.BaseStream.Length & 0xF) != 0x8 && (writer.BaseStream.Length & 0xF) != 0xC) { writer.Write((byte)0); } writer.BaseStream.Seek(hSdataOffset + 0x4, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); writer.Write(XRef.Count); for (int i = 0; i < XRef.Count; i++) { writer.Write(XRef[i]); } writer.BaseStream.Seek(hSdataOffset + 0x8, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); uint classListOffs = (uint)writer.BaseStream.Position; writer.Write(Classes.Count); for (int i = 0; i < Classes.Count; i++) { writer.Write(padding); } List <uint> classNameOffs = new List <uint>(); List <uint[]> varNameOffs = new List <uint[]>(); List <uint[]> funcNameOffs = new List <uint[]>(); List <uint[]> constNameOffs = new List <uint[]>(); for (int i = 0; i < Classes.Count; i++) { writer.BaseStream.Seek(classListOffs + 4 + (i * 4), SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); uint cl = (uint)writer.BaseStream.Position; classNameOffs.Add(cl); writer.Write(padding); writer.Write(Classes[i].Hash); writer.Write(padding); writer.Write(padding); writer.Write(padding); if (Version[0] >= 2 || Version[1] >= 1) { writer.Write(padding); } if (Version[0] >= 7) { writer.Write(padding); } writer.Write(Classes[i].Flags); bool writeVariables = true; //if (Version[0] >= 7) // writeVariables = Classes[i].Variables.Count > 0; List <uint> vOffs = new List <uint>(); if (writeVariables) { writer.BaseStream.Seek(cl + 0x8, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); uint varListOffs = (uint)writer.BaseStream.Position; writer.Write(Classes[i].Variables.Count); for (int v = 0; v < Classes[i].Variables.Count; v++) { writer.Write((uint)(varListOffs + 4 + (Classes[i].Variables.Count * 4) + (v * 0x10))); } for (int v = 0; v < Classes[i].Variables.Count; v++) { vOffs.Add((uint)writer.BaseStream.Position); writer.Write(padding); writer.Write(Classes[i].Variables[v].Hash); writer.Write(padding); writer.Write(Classes[i].Variables[v].Flags); } } bool writeFunctions = true; //if (Version[0] >= 7) // writeFunctions = Classes[i].Functions.Count > 0; List <uint> funcOffsList = new List <uint>(); if (writeFunctions) { writer.BaseStream.Seek(cl + 0xC, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); uint funcListOffs = (uint)writer.BaseStream.Position; writer.Write(Classes[i].Functions.Count); for (int v = 0; v < Classes[i].Functions.Count; v++) { writer.Write(padding); } for (int v = 0; v < Classes[i].Functions.Count; v++) { writer.BaseStream.Seek(funcListOffs + 4 + (v * 4), SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); funcOffsList.Add((uint)writer.BaseStream.Length); writer.Write(padding); writer.Write(Classes[i].Functions[v].Hash); if (Version[0] >= 7) { writer.Write(Classes[i].Functions[v].Arguments); writer.Write(Classes[i].Functions[v].Registers); } if (Version[0] >= 2 || Version[1] >= 1) //Only 2.x and 1.1.x use function flags { writer.Write((uint)writer.BaseStream.Position + 8); writer.Write(Classes[i].Functions[v].Flags); } else { writer.Write((uint)writer.BaseStream.Position + 4); } for (int f = 0; f < Classes[i].Functions[v].Instructions.Count; f++) { Classes[i].Functions[v].Instructions[f].Write(writer); } } } bool writeConstants = true; if (Version[0] >= 7) { writeConstants = Classes[i].Constants.Count > 0; } List <uint> cOffs = new List <uint>(); if (writeConstants) { writer.BaseStream.Seek(cl + 0x10, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); writer.Write(Classes[i].Constants.Count); uint constListOffs = (uint)writer.BaseStream.Position; for (int v = 0; v < Classes[i].Constants.Count; v++) { writer.Write((uint)(constListOffs + (Classes[i].Constants.Count * 4) + (v * 8))); } for (int v = 0; v < Classes[i].Constants.Count; v++) { cOffs.Add((uint)writer.BaseStream.Position); writer.Write(padding); writer.Write(Classes[i].Constants[v].Value); } } bool writeUnkSection = false; if (Version[0] >= 2 || Version[1] >= 1) { writeUnkSection = true; } else if (Version[0] >= 7) { writeUnkSection = Classes[i].UnknownList.Count > 0; } if (writeUnkSection) { writer.BaseStream.Seek(cl + 0x14, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); writer.Write(Classes[i].UnknownList.Count); for (int v = 0; v < Classes[i].UnknownList.Count; v++) { writer.Write(Classes[i].UnknownList[v]); } } bool writeUnk2Section = false; if (Version[0] >= 7) { writeUnk2Section = Classes[i].Unknown2List.Count > 0; } if (writeUnk2Section) { writer.BaseStream.Seek(cl + 0x18, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); writer.Write(Classes[i].Unknown2List.Count); for (int v = 0; v < Classes[i].Unknown2List.Count; v++) { writer.Write(Classes[i].Unknown2List[v]); } } varNameOffs.Add(vOffs.ToArray()); funcNameOffs.Add(funcOffsList.ToArray()); constNameOffs.Add(cOffs.ToArray()); } //String writing writer.BaseStream.Seek(0x10, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Name); for (int i = 0; i < Classes.Count; i++) { writer.BaseStream.Seek(classNameOffs[i], SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Classes[i].Name); if (Version[0] < 7 || Classes[i].Variables.Count > 0) { for (int v = 0; v < Classes[i].Variables.Count; v++) { uint vo = varNameOffs[i][v]; writer.BaseStream.Seek(vo, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Classes[i].Variables[v].Name); writer.BaseStream.Seek(vo + 0x8, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Classes[i].Variables[v].Type); } } if (Version[0] < 7 || Classes[i].Functions.Count > 0) { for (int v = 0; v < Classes[i].Functions.Count; v++) { writer.BaseStream.Seek(funcNameOffs[i][v], SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Classes[i].Functions[v].Name); } } if (Version[0] < 7 || Classes[i].Constants.Count > 0) { for (int v = 0; v < Classes[i].Constants.Count; v++) { writer.BaseStream.Seek(constNameOffs[i][v], SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Classes[i].Constants[v].Name); } } } XData.UpdateFilesize(writer); return(stream.GetBuffer().Take((int)XData.Filesize).ToArray()); } }
public void Write(EndianBinaryWriter writer) { XData.Write(writer); writer.Write(Version); writer.Write(Namespaces.Count + 1); writer.Write(0x24); writer.Write(Scripts.Count); uint scrListOffs = (uint)(0x34 + (Namespaces.Count * 0x14) + (IndexTable.Count * 4)); writer.Write(scrListOffs); //Script data end bound offset, -1 for now until we get there writer.Write(-1); writer.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); //Namespace information writer.Write(RootNamespaces); for (int i = 0; i < Namespaces.Count; i++) { //Console.WriteLine($"{Namespaces[i].Name} - Index {Namespaces[i].Index}, In table: {IndexTable.Contains(Namespaces[i].Index)}, Index: {IndexTable.IndexOf(Namespaces[i].Index)}"); if (!IndexTable.Contains(Namespaces[i].Index)) { writer.Write(scrListOffs); } else { writer.Write((uint)(0x34 + (Namespaces.Count * 0x14) + (IndexTable.IndexOf(Namespaces[i].Index) * 4))); } writer.Write(-1); //Come back to this later for string writing writer.Write(Namespaces[i].Scripts); writer.Write(Namespaces[i].TotalScripts); writer.Write(Namespaces[i].ChildNamespaces); } //writer.Write(scrListOffs); for (int i = 0; i < IndexTable.Count; i++) { writer.Write(IndexTable[i]); } writer.BaseStream.Seek(scrListOffs, SeekOrigin.Begin); for (int i = 0; i < Scripts.Count; i++) { writer.Write(-1); //Come back to this later for string writing writer.Write(-1); } for (int i = 0; i < Scripts.Count; i++) { writer.BaseStream.Seek(scrListOffs + (i * 8) + 4, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); writer.Write(Scripts.Values.ToArray()[i].Write()); while ((writer.BaseStream.Length & 0xF) != 0x0 && (writer.BaseStream.Length & 0xF) != 0x4 && (writer.BaseStream.Length & 0xF) != 0x8 && (writer.BaseStream.Length & 0xF) != 0xC) { writer.Write((byte)0); } } writer.BaseStream.Seek(0x24, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); writer.Write((long)0); while ((writer.BaseStream.Length & 0xF) != 0x0 && (writer.BaseStream.Length & 0xF) != 0x4 && (writer.BaseStream.Length & 0xF) != 0x8 && (writer.BaseStream.Length & 0xF) != 0xC) { writer.Write((byte)0); } for (int i = 0; i < Namespaces.Count; i++) { writer.BaseStream.Seek(0x34 + (i * 20) + 4, SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Namespaces[i].Name); } for (int i = 0; i < Scripts.Count; i++) { writer.BaseStream.Seek(scrListOffs + (i * 8), SeekOrigin.Begin); writer.Write((uint)writer.BaseStream.Length); writer.BaseStream.Seek(0, SeekOrigin.End); WriteUtil.WriteString(writer, Scripts.Keys.ToArray()[i]); } XData.UpdateFilesize(writer); }
public void AddClass(Type type) { if (!Attribute.IsDefined(type, typeof(Table))) // проверка на существование атрибута { throw new NotCompatibleClass(); } HidTypeInfo hti = new HidTypeInfo(); List <MemberInfo> pks = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Where(n => Attribute.IsDefined(n, typeof(Id))).ToList(); if (pks.Count != 1) { throw new PrimaryKeyException(); } List <MemberInfo> columns = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Where(n => Attribute.IsDefined(n, typeof(Id)) || Attribute.IsDefined(n, typeof(Column))).ToList(); var tt = (Attribute.GetCustomAttribute(type, typeof(Table)) as Table); string tableName = conf.TabelPrfix + "t" + (tt.Name ?? type.Name); if (tt.force) { tableName = tt.Name; } if (string.IsNullOrEmpty(tableName)) { throw new NotCompatibleClass(); } hti.TableName = tableName; if (tableName == HibTableName) { throw new TypeNameError(); } WriteUtil.WriteLine(tableName); string idColName = ""; bool cr = false; // create table bool dt = false; // delete table string ct = "CREATE TABLE [" + tableName + "]("; foreach (var c in columns) { Column col = null; var otrs = c.GetCustomAttributes(typeof(Column), true); if (otrs.Length != 0) { col = (Column)otrs[0]; } Id id = null; otrs = c.GetCustomAttributes(typeof(Id), true); if (otrs.Length != 0) { id = (Id)otrs[0]; } string ctype = GetSqlTypeByMem(c); string name = (col?.Name) ?? c.Name; ct += ("[" + name + "] " + ctype + " ") + (id != null ? " NOT NULL " : "") + ", \n"; HidTypeInfo.HidFieldInfo h = new HidTypeInfo.HidFieldInfo() { Mem = c, type = HidTypeInfo.HidFieldInfo.MemType(c), colName = name, SQlType = GetTypeClassByMem(c) }; if (id != null) { idColName = name; hti.idInfo = h; } hti.fields.Add(h); } ct += " CONSTRAINT [PK_" + tableName + "] PRIMARY KEY CLUSTERED ( ["+ idColName + "] ) ) "; using (var com = m_connection.CreateCommand()) { com.Transaction = m_tranaction; com.CommandText = "select parval from " + HibTableName + " where parcode = " + conf.parPre + "p"; var p = com.CreateParameter(); p.DbType = System.Data.DbType.String; p.ParameterName = "p"; p.Value = "Table_HashCode_" + tableName; com.Parameters.Add(p); using (var rd = com.ExecuteReader()) { if (!rd.Read() || rd[0].ToString() != ct.GetHashCode().ToString()) { cr = true; dt = true; } rd.Close(); } } if (cr) { if (dt) { using (var com = m_connection.CreateCommand()) { com.Transaction = m_tranaction; try { com.CommandText = "DROP TABLE " + tableName; com.ExecuteNonQuery(); } catch (Exception) { } } } using (var com = m_connection.CreateCommand()) { com.Transaction = m_tranaction; com.CommandText = ct; com.ExecuteNonQuery(); } using (var com = m_connection.CreateCommand()) { com.Transaction = m_tranaction; com.CommandText = "INSERT INTO " + HibTableName + " (parcode , parval ) VALUES (" + conf.parPre + "p1 , " + conf.parPre + "p2)"; var p = com.CreateParameter(); p.DbType = System.Data.DbType.String; p.ParameterName = "p1"; p.Value = "Table_HashCode_" + tableName; com.Parameters.Add(p); p = com.CreateParameter(); p.DbType = System.Data.DbType.String; p.ParameterName = "p2"; p.Value = ct.GetHashCode().ToString(); com.Parameters.Add(p); com.ExecuteNonQuery(); this.Commit(); } } loadedTypes.Add(type, hti); // m_tranaction.Commit(); }