public IdentificationSection(byte[] rawBytes) : base(rawBytes)
        {
            CenterId = SectionReader.ReadGribShort();

            SubCenterId = SectionReader.ReadGribShort();

            MasterTablesVersionNumber = SectionReader.ReadByte();

            LocalTablesVersionNumber = SectionReader.ReadByte();

            SignificanceOfReferenceTime = SectionReader.ReadByte();

            var year   = SectionReader.ReadGribShort();
            var month  = SectionReader.ReadByte();
            var day    = SectionReader.ReadByte();
            var hour   = SectionReader.ReadByte();
            var minute = SectionReader.ReadByte();
            var second = SectionReader.ReadByte();

            ReferenceTime = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc);

            ProductionStatusOfMessage = SectionReader.ReadByte();

            ProcessedDataTypeOfMessage = SectionReader.ReadByte();

            Reserved = SectionReader.ReadBytes(Length - Constants.Section1.DefaultLength);
        }
        public void BeforeEachTest()
        {
            const string relativePathToInputFile = @"TestInputFiles\OneNoteApi Demo.one";

            stream            = File.OpenRead(relativePathToInputFile);
            binaryReader      = new BinaryReader(stream);
            oneNoteFileReader = new OneNoteFileReader(binaryReader);
            sectionReader     = new SectionReader(oneNoteFileReader);
        }
Exemple #3
0
 public static Section Open(string path)
 {
     using (var stream = File.OpenRead(path))
         using (var reader = new BinaryReader(stream))
         {
             var fileReader    = new OneNoteFileReader(reader);
             var sectionReader = new SectionReader(fileReader);
             return(sectionReader.ReadSection());
         }
 }
        public GridDefinition(byte[] rawBytes) : base(rawBytes)
        {
            SourceOfGridDefinition = SectionReader.ReadByte();

            NumberOfDataPoints = SectionReader.ReadGribInt();

            NumberOfOctetsForOptionalListOfNumbersDefiningNumberOfPoints = SectionReader.ReadByte();
            InterpretationOfOptionalList = SectionReader.ReadByte();

            GridDefintionTemplateNumber = SectionReader.ReadGribShort();
            if (GridDefintionTemplateNumber == Constants.Section3.GridDefinitionTemplateNumber.LatitudeLongitude)
            {
                var def = new LatLonGridDefinitionTemplate();
            }

            GridDefinitionTemplateAndStuff = SectionReader.ReadBytes(Length - 14);
        }
Exemple #5
0
        internal GMFile(GMFileContent f)
        {
            Content = f;

            General = SectionReader.GetGeneralInfo(f);
            Options = SectionReader.GetOptionInfo(f);

            Sound        = Utils.UintRange(0, f.Sounds->Count).Select(i => SectionReader.GetSoundInfo(f, i)).ToArray();
            Sprites      = Utils.UintRange(0, f.Sprites->Count).Select(i => SectionReader.GetSpriteInfo(f, i)).ToArray();
            Backgrounds  = Utils.UintRange(0, f.Backgrounds->Count).Select(i => SectionReader.GetBgInfo(f, i)).ToArray();
            Paths        = Utils.UintRange(0, f.Paths->Count).Select(i => SectionReader.GetPathInfo(f, i)).ToArray();
            Scripts      = Utils.UintRange(0, f.Scripts->Count).Select(i => SectionReader.GetScriptInfo(f, i)).ToArray();
            Fonts        = Utils.UintRange(0, f.Fonts->Count).Select(i => SectionReader.GetFontInfo(f, i)).ToArray();
            Objects      = Utils.UintRange(0, f.Objects->Count).Select(i => SectionReader.GetObjectInfo(f, i)).ToArray();
            Rooms        = Utils.UintRange(0, f.Rooms->Count).Select(i => SectionReader.GetRoomInfo(f, i)).ToArray();
            TexturePages = Utils.UintRange(0, f.TexturePages->Count).Select(i => SectionReader.GetTexPageInfo(f, i)).ToArray();
            Code         = Utils.UintRange(0, f.Code->Count).Select(i => Disassembler.DisassembleCode(f, i)).ToArray();
            Strings      = Utils.UintRange(0, f.Strings->Count).Select(i => SectionReader.GetStringInfo(f, i)).ToArray();
            Textures     = Utils.UintRange(0, f.Textures->Count).Select(i => SectionReader.GetTextureInfo(f, i)).ToArray();
            Audio        = Utils.UintRange(0, f.Audio->Count).Select(i => SectionReader.GetAudioInfo(f, i)).ToArray();

            AudioSoundMap = new Dictionary <uint, uint>();
            for (uint i = 0; i < Sound.Length; i++)
            {
                var s = Sound[i];

                if ((s.IsEmbedded || s.IsCompressed) && s.AudioId != -1)
                {
                    AudioSoundMap[(uint)s.AudioId] = i;
                }
            }

            var vars = General.IsOldBCVersion ? SectionReader.GetRefDefs(f, f.Variables) : SectionReader.GetRefDefsWithOthers(f, f.Variables);
            var fns  = General.IsOldBCVersion ? SectionReader.GetRefDefs(f, f.Functions) : SectionReader.GetRefDefsWithLength(f, f.Functions);

            RefData = new RefData
            {
                Variables = vars,
                Functions = fns,

                VarAccessors  = Disassembler.GetReferenceTable(f, vars),
                FuncAccessors = Disassembler.GetReferenceTable(f, fns)
            };
        }
        public void TestReadOptionsFile()
        {
            SectionReader sr = new SectionReader();
            Dictionary<string,List<Option>> sections = sr.Read(optionsxml);
            Assert.AreEqual(17, sections.Count, "Incorrect number of sections returned");
            List<Option> options = sections["User Preferences"];
            Assert.IsNotNull(options, "Failed to get the User Preference Section");
            Assert.AreEqual(16, options.Count, "Failed to get the correct number of options");

            Option option = options[0];
            Assert.AreEqual("Use Page Layout View for Source Documents", option.Name);
            Assert.AreEqual("{14aae503-889c-41b6-a694-2b2b29618b5a}", option.Guid);
            Assert.AreEqual("11", option.Type);
            Assert.AreEqual("0", option.Default);
            Assert.AreEqual("2", option.BoundControl);
            Assert.AreEqual("0", option.ReadOnly);
            Assert.AreEqual("Use Page Layout View for Source Documents", option.DisplayName);
            Assert.AreEqual("2", option.Applications);
            Assert.AreEqual("0", option.Private);
            Assert.AreEqual("0", option.Value); 
        }
Exemple #7
0
        public static CodeInfo DisassembleCode(GMFileContent content, uint id)
        {
            if (id >= content.Code->Count)
            {
                throw new ArgumentOutOfRangeException(nameof(id));
            }

            var cee = (CodeEntryE *)GMFile.PtrFromOffset(content, (&content.Code->Offsets)[id]);

            var len = cee->Length;
            var bc  = &cee->Bytecode;

            if (content.General->BytecodeVersion > 0xE)
            {
                var cef = (CodeEntryF *)cee;

                bc = (uint *)((byte *)&cef->BytecodeOffset + cef->BytecodeOffset); // ikr?
            }

            var ret = new List <IntPtr>(); // doesn't like T* as type arg

            len = Utils.PadTo(len, 4);
            AnyInstruction *instr;

            for (uint i = 0; i * 4 < len; /* see loop end */)
            {
                instr = (AnyInstruction *)(bc + i);

                ret.Add((IntPtr)instr);

                i += DisasmExt.Size(instr, content.General->BytecodeVersion);
            }

            return(new CodeInfo
            {
                Name = SectionReader.StringFromOffset(content, cee->Name),
                Instructions = Utils.MPtrListToPtrArr(ret),
                Size = cee->Length
            });
        }
Exemple #8
0
        //将解析好的内容再序列化成osb文件格式的文本内容
        private static void SerializeDecodeStoryboardContent(string beatmap_folder, bool parse_osb, string output_path)
        {
            try
            {
                var info       = BeatmapFolderInfoEx.Parse(beatmap_folder, null);
                var input_file = parse_osb ? info.osb_file_path : info.osu_file_path;
                output_path = string.IsNullOrWhiteSpace(output_path) ? input_file + ".parse_output" : output_path;

                Log.User($"Start serialize {input_file} ....");
                using (var writer = new StreamWriter(File.OpenWrite(output_path)))
                {
                    writer.WriteLine($"[{Section.Events.ToString()}]");

                    OsuFileReader reader = new OsuFileReader(input_file);

                    VariableCollection collection = new VariableCollection(new VariableReader(reader).EnumValues());

                    SectionReader section = new SectionReader(Section.Events, reader);

                    EventReader event_section = new EventReader(reader, collection);

                    foreach (var line in section.EnumValues())
                    {
                        var decode_line = event_section.LineProcessVariable(line);
                        writer.WriteLine(decode_line);
                    }
                }

                Log.User("Serialize successfully! it output to " + output_path);
                Exit("Serialize successfully! it output to " + output_path);
            }
            catch (Exception e)
            {
                Log.Error("Serialize failed!" + e.Message);
                Exit("Serialize failed!" + e.Message);
            }
        }
Exemple #9
0
        public static string DisplayInstructions(GMFileContent content, RefData rdata, CodeInfo code, AnyInstruction *[] instructions = null, bool absolute = false)
        {
            var bcv = content.General->BytecodeVersion;

            var instrs = instructions ?? code.Instructions;

            if (instrs.Length == 0)
            {
                return(String.Empty);
            }

            var sb = new StringBuilder();

            var firstI = code.Instructions[0];

            for (int i = 0; i < instrs.Length; i++)
            {
                var iptr     = instrs[i];
                var relInstr = (long)iptr - (absolute ? (long)content.RawData.BPtr : (long)firstI);

                sb.Append(HEX_PRE).Append(relInstr.ToString(HEX_FM6))
                .Append(COLON_S).Append(iptr->OpCode.ToPrettyString(bcv)).Append(' ');

                switch (iptr->Kind(content.General->BytecodeVersion))
                {
                case InstructionKind.SingleType:
                    var st = iptr->SingleType;

                    sb.Append(st.Type.ToPrettyString());

                    if (bcv > 0xE && st.OpCode.VersionF == FOpCode.Dup)
                    {
                        sb.Append(' ').Append(st.DupExtra);
                    }

                    break;

                case InstructionKind.DoubleType:
                    var dt = iptr->DoubleType;

                    if (bcv > 0xE && iptr->OpCode.VersionF == FOpCode.Cmp)
                    {
                        sb.Append(dt.ComparisonType.ToPrettyString()).Append(' ');
                    }

                    sb.Append(dt.Types);
                    break;

                case InstructionKind.Goto:
                    var g = iptr->Goto;

                    var a = g.Offset.UValue * 4;
                    if ((a & 0xFF000000) != 0)
                    {
                        a &= 0x00FFFFFF;
                        a -= 0x01000000;
                    }

                    sb.Append(HEX_PRE).Append(Utils.ToHexSignString(relInstr + unchecked ((int)a), HEX_FM6));
                    break;

                    #region set
                case InstructionKind.Set:
                    var s = iptr->Set;

                    sb.Append(s.Types).Append(' ');

                    if (s.IsMagic)
                    {
                        sb.Append(MAGIC);
                        break;
                    }

                    if (s.Instance <= InstanceType.StackTopOrGlobal)
                    {
                        sb.Append(s.Instance.ToPrettyString());
                    }
                    else
                    {
                        var o = SectionReader.GetObjectInfo(content, (uint)s.Instance);

                        sb.Append('[').Append(o.Name).Append(']');
                    }

                    sb.Append(':');

                    sb.Append(rdata.Variables[rdata.VarAccessors[(IntPtr)iptr]].Name);
                    sb.Append(s.DestVar.Type.ToPrettyString());
                    break;

                    #endregion
                    #region push
                case InstructionKind.Push:
                    var pp = (PushInstruction *)iptr;
                    var p  = iptr->Push;

                    sb.Append(p.Type.ToPrettyString()).Append(' ');

                    var r = p.ValueRest;

                    switch (p.Type)
                    {
                    case DataType.Int16:
                        sb.Append(p.Value.ToString(CultureInfo.InvariantCulture));
                        break;

                    case DataType.Variable:
                        var rv = *(Reference *)&r;

                        var inst = (InstanceType)p.Value;

                        if (inst <= InstanceType.StackTopOrGlobal)
                        {
                            sb.Append(inst.ToPrettyString());
                        }
                        else
                        {
                            var o = SectionReader.GetObjectInfo(content, (uint)inst);

                            sb.Append('[').Append(o.Name).Append(']');
                        }
                        sb.Append(':');

                        sb.Append(rdata.Variables[rdata.VarAccessors[(IntPtr)iptr]].Name);
                        sb.Append(rv.Type.ToPrettyString());
                        break;

                    case DataType.Boolean:
                        sb.Append(((DwordBool *)&r)->ToPrettyString());
                        break;

                    case DataType.Double:
                        sb.Append(((double *)&r)->ToString(CultureInfo.InvariantCulture));
                        break;

                    case DataType.Single:
                        sb.Append(((float *)&r)->ToString(CultureInfo.InvariantCulture));
                        break;

                    case DataType.Int32:
                        sb.Append(unchecked ((int)r).ToString(CultureInfo.InvariantCulture));
                        break;

                    case DataType.Int64:
                        sb.Append(((long *)&pp->ValueRest)->ToString(CultureInfo.InvariantCulture));
                        break;

                    case DataType.String:
                        sb.Append(SectionReader.GetStringInfo(content, p.ValueRest).Escape());
                        break;
                    }
                    break;

                    #endregion
                    #region call
                case InstructionKind.Call:
                    var c = iptr->Call;

                    sb.Append(c.ReturnType.ToPrettyString()).Append(':')
                    .Append(c.Arguments).Append(' ');

                    sb.Append(rdata.Functions[rdata.FuncAccessors[(IntPtr)iptr]].Name);
                    sb.Append(c.Function.Type.ToPrettyString());
                    break;
                    #endregion

                case InstructionKind.Break:
                    var b = iptr->Break;

                    sb.Append(b.Type.ToPrettyString()).Append(' ').Append(b.Signal);
                    break;
                }

                sb.AppendLine();
            }

            return(sb.ToString());
        }
 public void TestReadNonExistingFile()
 {
     SectionReader sr = new SectionReader();
     sr.Read("x:\\xyzgfasdjaskauwheqkjwehqkjehqjkehqwelas.xml");
 }
 public void TestReadSettingsFile()
 {
     SectionReader sr = new SectionReader();
     Dictionary<string, List<Option>> sections = sr.Read(settingsxml);
     Assert.AreEqual(0, sections.Count, "Incorrect number of sections returned");
 }
Exemple #12
0
        internal GMFile(GMFileContent f)
        {
            Content = f;

            var orderList = new List <SectionHeaders>(f.HeaderOffsets.Length);

            foreach (long headerOffset in f.HeaderOffsets)
            {
                SectionHeaders tag = ((SectionHeader *)((byte *)f.Form + headerOffset))->Identity;
                if (tag != SectionHeaders.Form)
                {
                    orderList.Add(tag);
                }
            }
            ChunkOrder = orderList.ToArray();

            if (f.General != null)
            {
                General = SectionReader.GetGeneralInfo(f);
            }
            if (f.Options != null)
            {
                Options = SectionReader.GetOptionInfo(f);
            }
            if (f.Globals != null)
            {
                Globals = SectionReader.GetGlobalInfo(f);
            }

            Sound = MkLazyArr(f.Sounds, i => SectionReader.GetSoundInfo(f, i));

            if (f.TexturePages != null)
            {
                var toil = SectionReader.BuildTPAGOffsetIndexLUT(f);
                Sprites = MkLazyArr(f.Sprites, i => SectionReader.GetSpriteInfo(f, i, toil));
            }

            Backgrounds  = MkLazyArr(f.Backgrounds, i => SectionReader.GetBgInfo(f, i));
            Paths        = MkLazyArr(f.Paths, i => SectionReader.GetPathInfo(f, i));
            Scripts      = MkLazyArr(f.Scripts, i => SectionReader.GetScriptInfo(f, i));
            Fonts        = MkLazyArr(f.Fonts, i => SectionReader.GetFontInfo(f, i));
            Objects      = MkLazyArr(f.Objects, i => SectionReader.GetObjectInfo(f, i));
            Rooms        = MkLazyArr(f.Rooms, i => SectionReader.GetRoomInfo(f, i));
            TexturePages = MkLazyArr(f.TexturePages, i => SectionReader.GetTexPageInfo(f, i));
            Code         = MkLazyArr(f.Code, i => Disassembler.DisassembleCode(f, i));
            Strings      = MkLazyArr(f.Strings, i => SectionReader.GetStringInfo(f, i));
            Textures     = MkLazyArr(f.Textures, i => SectionReader.GetTextureInfo(f, i));
            Audio        = MkLazyArr(f.Audio, i => SectionReader.GetAudioInfo(f, i));
            AudioGroups  = MkLazyArr(f.AudioGroup, i => SectionReader.GetAudioGroupInfo(f, i));
            Extensions   = MkLazyArr(f.Extensions, i => SectionReader.GetExtensionInfo(f, i));
            Shaders      = MkLazyArr(f.Shaders, i => SectionReader.GetShaderInfo(f, i));
            Timelines    = MkLazyArr(f.Timelines, i => SectionReader.GetTimelineInfo(f, i));

            AudioSoundMap = new Dictionary <uint, uint>();
            if (f.Sounds != null)
            {
                for (uint i = 0; i < Sound.Length; i++)
                {
                    var s = Sound[i];

                    if ((s.IsEmbedded || s.IsCompressed) && s.AudioID != -1 && s.GroupID == 0)
                    {
                        AudioSoundMap[(uint)s.AudioID] = i;
                    }
                }
            }

            if (f.General == null)
            {
                return;
            }

            try
            {
                // TODO: do this in a better way
                var vars = General.IsOldBCVersion
                    ? SectionReader.GetRefDefs(f, f.Variables)
                    : SectionReader.GetRefDefsWithOthers(f, f.Variables);
                var fns = General.IsOldBCVersion
                    ? SectionReader.GetRefDefs(f, f.Functions)
                    : SectionReader.GetRefDefsWithLength(f, f.Functions);

                var varacc = Disassembler.GetReferenceTable(f, vars);
                var fnacc  = Disassembler.GetReferenceTable(f, fns);

                RefData = new RefData
                {
                    Variables     = vars,
                    Functions     = fns,
                    VarAccessors  = varacc,
                    FuncAccessors = fnacc
                };

                if (f.Functions->Entries.NameOffset * 12 < f.Functions->Header.Size)
                {
                    FunctionLocals = SectionReader.GetFunctionLocals(f, f.Functions);
                }
                if (f.Variables != null && !General.IsOldBCVersion)
                {
                    VariableExtra = new uint[]
                    {
                        ((uint *)&f.Variables->Entries)[0],
                        ((uint *)&f.Variables->Entries)[1],
                        ((uint *)&f.Variables->Entries)[2]
                    }
                }
                ;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Warning: Can't figure out RefDef pairs. Exception:");
                Console.Error.WriteLine(e);
            }
        }
Exemple #13
0
        public static Statement[] ParseStatements(GMFileContent content, RefData rdata, CodeInfo code, AnyInstruction *[] instr = null, Stack <Expression> stack = null, List <Expression> dupTars = null, bool absolute = false)
        {
            var bcv = content.General->BytecodeVersion;

            //! here be dragons

            stack   = stack ?? new Stack <Expression>();
            dupTars = dupTars ?? new List <Expression>();
            instr   = instr ?? code.Instructions;

            if (instr.Length == 0)
            {
                return(EmptyStmtArray);
            }

            var stmts = new List <Statement>();

            var firstI  = code.Instructions[0];
            var baseOff = absolute ? (long)content.RawData.BPtr : (long)firstI;

            //TODO: use locals

            Func <Expression> Pop = () => stack.Count == 0 ? PopExpr : stack.Pop();
            //Func<Expression> Peek = () => stack.Count == 0 ? PopExpr : stack.Peek();
            Func <int, IEnumerable <Expression> > PopMany = i =>
            {
                var ret = new List <Expression>();

                for (int j = 0; j < i; j++)
                {
                    ret.Add(Pop());
                }

                return(ret);
            };
            Action FlushStack = () =>
            {
                var readd = new Stack <Expression>();

                //? not sure if this is a good idea (random 'push'es in the wild) (see TODO)
                stmts.AddRange(stack.PopAll().Where(e =>
                {
                    if (dupTars.Contains(e))
                    {
                        readd.Push(e);
                        return(false);
                    }

                    return(!(e is PopExpression)); // 'push pop' is obviously stupid to emit
                }).Reverse().Select(e =>
                                    e is UnaryOperatorExpression &&
                                    ((UnaryOperatorExpression)e).Operator == UnaryOperator.Duplicate
                        ? (Statement) new DupStatement() : new PushStatement {
                    Expr = e
                }));

                stack.PushRange(readd);
            };
            Action <Statement> AddStmt = s =>
            {
                FlushStack();

                stmts.Add(s);
            };
            Func <VariableType, Expression[]> TryGetIndices = vt =>
            {
                Expression index = null;

                var dimentions = 0;
                if (vt == VariableType.Array)
                {
                    index = Pop();

                    var arrInd = Pop();

                    if ((arrInd is LiteralExpression) && ((LiteralExpression)arrInd).Value is short)
                    {
                        var s = (short)((LiteralExpression)arrInd).Value;

                        switch (s)
                        {
                        case -1:
                            dimentions = 2;
                            break;

                        case -5:
                            dimentions = 1;
                            break;
                        }
                    }

                    if (dimentions == 0)
                    {
                        stack.Push(arrInd);
                        stack.Push(index);

                        index = null;
                    }
                }

                if (index == null)
                {
                    return(null);
                }

                // analyse index for specified dimention
                switch (dimentions)
                {
                case 2:
                    if (index is BinaryOperatorExpression && ((BinaryOperatorExpression)index).Operator == BinaryOperator.Addition)
                    {
                        var boe = (BinaryOperatorExpression)index;

                        var a = boe.Arg1;
                        var b = boe.Arg2;

                        if (a is BinaryOperatorExpression && ((BinaryOperatorExpression)a).Operator == BinaryOperator.Multiplication)
                        {
                            var a_ = (BinaryOperatorExpression)a;
                            var c  = a_.Arg2;

                            if (c is LiteralExpression && ((LiteralExpression)c).ReturnType == DataType.Int32 &&
                                (int /* should be */)((LiteralExpression)c).Value == 32000)
                            {
                                return new[] { a_.Arg1, b }
                            }
                            ;
                        }
                    }
                    break;
                }

                return(new[] { index });
            };

            for (int i = 0; i < instr.Length; i++)
            {
                var ins = instr[i];

                #region stuff
                var pst = (SingleTypeInstruction *)ins;
                var pdt = (DoubleTypeInstruction *)ins;
                var pcl = (CallInstruction *)ins;
                var pps = (PushInstruction *)ins;
                var pse = (SetInstruction *)ins;
                var pbr = (BranchInstruction *)ins;
                var pbk = (BreakInstruction *)ins;

                var st = ins->SingleType;
                var dt = ins->DoubleType;
                var cl = ins->Call;
                var ps = ins->Push;
                var se = ins->Set;

                var t1 = ins->Kind(bcv) == InstructionKind.SingleType ? st.Type
                      : (ins->Kind(bcv) == InstructionKind.DoubleType ? dt.Types.Type1 : 0);
                var t2 = ins->Kind(bcv) == InstructionKind.DoubleType ? dt.Types.Type2
                      : (ins->Kind(bcv) == InstructionKind.SingleType ? st.Type        : 0);
                #endregion

                GeneralOpCode opc;
                switch (opc = ins->OpCode.General(bcv))
                {
                    #region dup, pop
                case GeneralOpCode.Dup:
                    var normal = true;
                    if (i < instr.Length - 1 && instr[i + 1]->OpCode.General(bcv) == GeneralOpCode.Push)
                    {
                        var n = &instr[i + 1]->Push;
                        var t = ((Reference *)&n->ValueRest)->Type;

                        if (t == VariableType.Array && stack.Count > 1)
                        {
                            normal = false;

                            stack.Push(stack.Skip(1).First());     // second item
                            stack.Push(stack.Skip(1).First());     // first  item (original stack top)
                        }
                    }

                    if (!normal)
                    {
                        break;
                    }

                    if (!dupTars.Contains(stack.Peek()))
                    {
                        dupTars.Add(stack.Peek());
                    }

                    //var stackArr = stack.ToArray();
                    //for (i = 0; i <= ins->SingleType.DupExtra; i++)
                    //{
                    //    if (i >= stackArr.Length)
                    //    {
                    //        // .__.
                    //        break;
                    //    }

                    var elem = stack.Peek();        //stackArr[stackArr.Length - i - 1];

                    if (elem.WalkExprTree(e => e is CallExpression).Any(Utils.Identity))
                    {
                        stack.Push(new UnaryOperatorExpression
                        {
                            Input        = elem,
                            Operator     = UnaryOperator.Duplicate,
                            OriginalType = elem.ReturnType,
                            ReturnType   = st.Type
                        });
                    }
                    else
                    {
                        stack.Push(elem);
                    }
                    //}
                    break;

                case GeneralOpCode.Pop:
                    if (stack.Count > 0 && stack.Peek() is CallExpression)
                    {
                        AddStmt(new CallStatement {
                            Call = (CallExpression)stack.Pop()
                        });
                    }
                    else
                    {
                        AddStmt(new PopStatement());
                    }
                    break;

                    #endregion
                    #region br etc
                //TODO: use actual '(with obj ...)' syntax
                //! it might mess with the CFG structure
                case GeneralOpCode.PushEnv:
                case GeneralOpCode.PopEnv:
                case GeneralOpCode.Brt:
                case GeneralOpCode.Brf:
                case GeneralOpCode.Br:
                {
                    var a = pbr->Offset.UValue * 4;
                    if ((a & 0xFF000000) != 0)
                    {
                        a &= 0x00FFFFFF;
                        a -= 0x01000000;
                    }

                    var tar = (AnyInstruction *)((long)ins + unchecked ((int)a));
                    var off = (long)ins - baseOff + unchecked ((int)a);

                    switch (opc)
                    {
                    case GeneralOpCode.PushEnv:
                        AddStmt(new PushEnvStatement
                            {
                                Target       = tar,
                                TargetOffset = off,
                                Parent       = stack.Pop()
                            });
                        break;

                    case GeneralOpCode.PopEnv:
                        AddStmt(new PopEnvStatement
                            {
                                Target       = tar,
                                TargetOffset = off
                            });
                        break;

                    case GeneralOpCode.Brt:
                    case GeneralOpCode.Brf:
                    case GeneralOpCode.Br:
                        AddStmt(new BranchStatement
                            {
                                Type         = pbr->Type(bcv),
                                Conditional  = pbr->Type(bcv) == BranchType.Unconditional ? null : Pop(),
                                Target       = tar,
                                TargetOffset = off
                            });
                        break;
                    }
                }
                break;

                    #endregion
                    #region break, ret, exit
                case GeneralOpCode.Break:
                    stack.Push(new AssertExpression
                    {
                        ControlValue = pbk->Signal,
                        ReturnType   = pbk->Type,
                        Expr         = Pop()
                    });
                    break;

                case GeneralOpCode.Ret:
                    AddStmt(new ReturnStatement
                    {
                        ReturnType = pst->Type,
                        RetValue   = Pop()
                    });
                    break;

                case GeneralOpCode.Exit:
                    AddStmt(new ExitStatement());
                    break;

                    #endregion
                    #region set
                case GeneralOpCode.Set:
                    if (se.IsMagic)
                    {
                        AddStmt(new MagicSetStatement
                        {
                            OriginalType = se.Types.Type1,
                            ReturnType   = se.Types.Type2
                        });

                        break;
                    }

                    var ind = TryGetIndices(se.DestVar.Type);     // call before Value's pop
                    AddStmt(new SetStatement
                    {
                        OriginalType = se.Types.Type1,
                        ReturnType   = se.Types.Type2,
                        Type         = se.DestVar.Type,
                        OwnerType    = se.Instance,
                        OwnerName    = se.Instance > InstanceType.StackTopOrGlobal ? SectionReader.GetObjectInfo(content, (uint)se.Instance, true).Name : null,
                        Target       = rdata.Variables[rdata.VarAccessors[(IntPtr)ins]],
                        Value        = Pop(),
                        ArrayIndices = ind ?? TryGetIndices(se.DestVar.Type)
                    });
                    break;

                    #endregion
                default:
                    switch (ins->ExprType(bcv))
                    {
                        #region variable
                    case ExpressionType.Variable:
                        var vt = ((Reference *)&pps->ValueRest)->Type;

                        stack.Push(/*vt == VariableType.StackTop &&*/ (InstanceType)ps.Value == InstanceType.StackTopOrGlobal
                                    ? new MemberExpression
                        {
                            Owner        = Pop(),
                            ReturnType   = ps.Type,
                            Type         = vt,
                            OwnerType    = (InstanceType)ps.Value,
                            OwnerName    = se.Instance > InstanceType.StackTopOrGlobal ? SectionReader.GetObjectInfo(content, (uint)se.Instance, true).Name : null,
                            Variable     = rdata.Variables[rdata.VarAccessors[(IntPtr)ins]],
                            ArrayIndices = TryGetIndices(vt)
                        }
                                    : new VariableExpression
                        {
                            ReturnType   = ps.Type,
                            Type         = vt,
                            OwnerType    = (InstanceType)ps.Value,
                            Variable     = rdata.Variables[rdata.VarAccessors[(IntPtr)ins]],
                            ArrayIndices = TryGetIndices(vt)
                        });
                        break;

                        #endregion
                        #region literal
                    case ExpressionType.Literal:
                        object v    = null;
                        var    rest = &pps->ValueRest;

                        #region get value
                        switch (ps.Type)
                        {
                        case DataType.Int16:
                            v = ps.Value;
                            break;

                        case DataType.Boolean:
                            v = ((DwordBool *)rest)->IsTrue();
                            break;

                        case DataType.Double:
                            v = *(double *)rest;
                            break;

                        case DataType.Single:
                            v = *(float *)rest;
                            break;

                        case DataType.Int32:
                            v = *(int *)rest;
                            break;

                        case DataType.Int64:
                            v = *(long *)rest;
                            break;

                        case DataType.String:
                            v = SectionReader.GetStringInfo(content, (uint)ps.ValueRest);
                            break;
                        }
                        #endregion

                        stack.Push(new LiteralExpression
                        {
                            ReturnType = ps.Type,
                            Value      = v
                        });
                        break;

                        #endregion
                        #region call
                    case ExpressionType.Call:
                        stack.Push(new CallExpression
                        {
                            ReturnType = cl.ReturnType,
                            Type       = cl.Function.Type,
                            Function   = rdata.Functions[rdata.FuncAccessors[(IntPtr)ins]],
                            Arguments  = PopMany(cl.Arguments).Reverse().ToArray()
                        });
                        break;

                        #endregion
                        #region binaryop
                    case ExpressionType.BinaryOp:
                        var a1 = Pop();
                        var a2 = Pop();

                        stack.Push(new BinaryOperatorExpression
                        {
                            OriginalType = t1,
                            ReturnType   = t2,
                            Arg1         = a2,
                            Arg2         = a1,
                            Operator     = ins->BinaryOp(bcv)
                        });
                        break;

                        #endregion
                        #region unaryop
                    case ExpressionType.UnaryOp:
                        stack.Push(new UnaryOperatorExpression
                        {
                            OriginalType = t1,
                            ReturnType   = t2,
                            Input        = Pop(),
                            Operator     = ins->UnaryOp(bcv)
                        });
                        break;
                        #endregion
                    }
                    break;
                }
            }

            FlushStack();

            return(stmts.ToArray());
        }
        public static BeatmapFolderInfoEx Parse(string folder_path, Parameters args)
        {
            string explicitly_osu_diff_name = "";

            if (args != null && args.TryGetArg("diff", out var diff_name))
            {
                explicitly_osu_diff_name = diff_name;
            }

            var info = BeatmapFolderInfo.Parse <BeatmapFolderInfoEx>(folder_path);

            if (!string.IsNullOrWhiteSpace(explicitly_osu_diff_name))
            {
                int index = -1;
                index = int.TryParse(explicitly_osu_diff_name, out index) ? index : -1;

                if (index > 0)
                {
                    info.osu_file_path = info.DifficultFiles.OrderBy(x => x.Key).FirstOrDefault().Value;
                }
                else
                {
                    info.osu_file_path = info.DifficultFiles.Where(x => x.Key.Contains(explicitly_osu_diff_name)).OrderBy(x => x.Key.Length).FirstOrDefault().Value;
                }
            }
            else
            {
                //优先选std铺面的.一些图其他模式谱面会有阻挡 53925 fripSide - Hesitation Snow
                info.osu_file_path = info.DifficultFiles.FirstOrDefault(x =>
                {
                    var lines = File.ReadAllLines(x.Value);

                    foreach (var line in lines)
                    {
                        if (line.StartsWith("Mode"))
                        {
                            try
                            {
                                var mode = line.Split(':').Last().ToInt();

                                if (mode == 0)
                                {
                                    return(true);
                                }
                            }
                            catch { }
                        }
                    }

                    return(false);
                }).Value;

                if (!File.Exists(info.osu_file_path))
                {
                    info.osu_file_path = info.DifficultFiles.FirstOrDefault().Value;
                }
            }

            if ((!string.IsNullOrWhiteSpace(info.osu_file_path)) && File.Exists(info.osu_file_path))
            {
                info.reader = new OsuFileReader(info.osu_file_path);
                var section = new SectionReader(Section.General, info.reader);

                info.audio_file_path = Path.Combine(folder_path, section.ReadProperty("AudioFilename"));
                Log.User($"audio file path={info.audio_file_path}");

                var wideMatch = section.ReadProperty("WidescreenStoryboard");

                if (!string.IsNullOrWhiteSpace(wideMatch))
                {
                    info.IsWidescreenStoryboard = wideMatch.ToInt() == 1;
                }
            }

            /*
             * if (string.IsNullOrWhiteSpace(info.osu_file_path) || (!File.Exists(info.osu_file_path)))
             * {
             *  info.audio_file_path = Directory
             *      .GetFiles(info.folder_path, "*.mp3")
             *      .Select(x => new FileInfo(x))
             *      .OrderByDescending(x => x.Length)
             *      .FirstOrDefault()
             *      ?.FullName;
             * }
             */

            if (string.IsNullOrWhiteSpace(info.osu_file_path) || !File.Exists(info.osu_file_path))
            {
                Log.Warn("No .osu load");
            }

            if (string.IsNullOrWhiteSpace(info.audio_file_path) || !File.Exists(info.audio_file_path))
            {
                throw new Exception("Audio file not found.");
            }

            return(info);
        }
Exemple #15
0
        public static BeatmapFolderInfo Parse(string folder_path, ProgramCommandParser.Parameters args)
        {
            if (!Directory.Exists(folder_path))
            {
                throw new Exception($"\"{folder_path}\" not a folder!");
            }

            BeatmapFolderInfo info = new BeatmapFolderInfo();

            var osu_files = TryGetAnyFiles(".osu");

            string explicitly_osu_diff_name = string.Empty;

            if (args != null && args.TryGetArg("diff", out var diff_name))
            {
                explicitly_osu_diff_name = diff_name;
            }

            if (!string.IsNullOrWhiteSpace(explicitly_osu_diff_name))
            {
                int index = -1;
                index = int.TryParse(explicitly_osu_diff_name, out index) ? index : -1;

                if (index > 0)
                {
                    info.osu_file_path = osu_files.OrderBy(x => x).FirstOrDefault();
                }
                else
                {
                    var   fix_pattern = Regex.Escape(explicitly_osu_diff_name);
                    Regex regex       = new Regex(@"\[.*" + fix_pattern + @".*\]\.osu", RegexOptions.IgnoreCase);

                    info.osu_file_path = osu_files.Where(x => regex.IsMatch(x)).OrderBy(x => x.Length).FirstOrDefault();
                }
            }
            else
            {
                //优先先选std铺面的.一些图其他模式谱面会有阻挡 53925 fripSide - Hesitation Snow
                info.osu_file_path = osu_files.FirstOrDefault(x =>
                {
                    var lines = File.ReadAllLines(x);

                    foreach (var line in lines)
                    {
                        if (line.StartsWith("Mode"))
                        {
                            try
                            {
                                var mode = line.Split(':').Last().ToInt();

                                if (mode == 0)
                                {
                                    return(true);
                                }
                            }
                            catch { }
                        }
                    }

                    return(false);
                });

                if (!File.Exists(info.osu_file_path))
                {
                    info.osu_file_path = osu_files.FirstOrDefault();
                }
            }

            if (string.IsNullOrWhiteSpace(info.osu_file_path) || !File.Exists(info.osu_file_path))
            {
                Log.Warn("No .osu load");
            }

            info.osb_file_path = TryGetAnyFiles(".osb").FirstOrDefault();

            info.folder_path = folder_path;

            if ((!string.IsNullOrWhiteSpace(info.osu_file_path)) && File.Exists(info.osu_file_path))
            {
                info.reader = new OsuFileReader(info.osu_file_path);
                var section = new SectionReader(Section.General, info.reader);

                info.audio_file_path = Path.Combine(folder_path, section.ReadProperty("AudioFilename"));
                Log.User($"audio file path={info.audio_file_path}");

                var wideMatch = section.ReadProperty("WidescreenStoryboard");

                if (!string.IsNullOrWhiteSpace(wideMatch))
                {
                    info.IsWidescreenStoryboard = wideMatch.ToInt() == 1;
                }
            }

            if (string.IsNullOrWhiteSpace(info.osu_file_path) || (!File.Exists(info.osu_file_path)))
            {
                info.audio_file_path = Directory
                                       .GetFiles(info.folder_path, "*.mp3")
                                       .Select(x => new FileInfo(x))
                                       .OrderByDescending(x => x.Length)
                                       .FirstOrDefault()
                                       ?.FullName;
            }

            if (!(_check(info.osu_file_path) || _check(info.osb_file_path)) && _check(info.audio_file_path))
            {
                MainProgram.Exit($"missing files such as .osu/.osb and audio file which is registered in .osu");
            }

            return(info);

            bool _check(string file_path)
            {
                return((!string.IsNullOrWhiteSpace(file_path)) && File.Exists(file_path));
            }

            IEnumerable <string> TryGetAnyFiles(string extend_name)
            {
                return(Directory.EnumerateFiles(folder_path, "*" + extend_name, SearchOption.AllDirectories));
            }
        }