예제 #1
0
        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());
                }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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();
        }