Exemplo n.º 1
0
        public static IList <Function> ParseMultiple(string input, IStringWriter stringWriter)
        {
            // Split input to function parts
            var functionValues = input.Split(Environment.NewLine + Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);

            // Check if all functions match the pattern
            if (functionValues.Any(x => !ParseCheck.IsMatch(x)))
            {
                return(Array.Empty <Function>());
            }

            // Write all function names
            foreach (var functionValue in functionValues.OrderBy(x => stringWriter.GetHash(GetFunctionName(x))))
            {
                stringWriter.Write(GetFunctionName(functionValue));
            }

            // Write all jump labels
            foreach (var functionValue in functionValues)
            {
                var functionBody = GetFunctionBody(functionValue);
                var jumps        = GetJumpLabels(functionBody).OrderBy(x => stringWriter.GetHash(x.label));
                foreach (var jump in jumps)
                {
                    stringWriter.Write(jump.label);
                }
            }

            // Parse all functions
            return(functionValues.Select(x => Parse(x, stringWriter)).ToArray());
        }
Exemplo n.º 2
0
        private Stream WriteFunctions(IList <Function> functions, IList <Jump> jumps, IList <Instruction> instructions, IStringWriter stringWriter)
        {
            var functionStream = new MemoryStream();

            var lastInstructionOffset = 0;
            var lastJumpOffset        = 0;

            var convertedFunctions = new List <Xq32Function>();

            foreach (var function in functions)
            {
                var currentInstructionOffset = instructions.IndexOf(function.Instructions.FirstOrDefault());
                if (currentInstructionOffset >= 0)
                {
                    lastInstructionOffset = currentInstructionOffset;
                }

                var currentJumpOffset = jumps.IndexOf(function.Jumps.OrderBy(x => stringWriter.GetHash(x.Label)).FirstOrDefault());
                if (currentJumpOffset >= 0)
                {
                    lastJumpOffset = currentJumpOffset;
                }

                convertedFunctions.Add(new Xq32Function
                {
                    instructionOffset    = (short)lastInstructionOffset,
                    instructionEndOffset = (short)(lastInstructionOffset + function.Instructions.Count),

                    nameOffset = (int)stringWriter.Write(function.Name),
                    crc32      = stringWriter.GetHash(function.Name),

                    jumpOffset = (short)lastJumpOffset,
                    jumpCount  = (short)function.Jumps.Count,

                    parameterCount = (short)function.ParameterCount,

                    unk1 = (short)function.Unknowns[0],
                    unk2 = (short)function.Unknowns[1]
                });

                lastInstructionOffset += function.Instructions.Count;
                lastJumpOffset        += function.Jumps.Count;
            }

            using var bw = new BinaryWriterX(functionStream, true);
            bw.WriteMultiple(convertedFunctions.OrderBy(x => x.crc32));

            functionStream.Position = 0;
            return(functionStream);
        }
Exemplo n.º 3
0
        // TODO: Try to detect type from value itself
        public static Argument Parse(int subType, string input, IStringWriter stringWriter)
        {
            if (!ParseCheck.IsMatch(input))
            {
                return(null);
            }

            var type  = GetArgumentType(input);
            var value = GetArgumentValue(input);

            switch (type)
            {
            case 1:
                return(new Argument(type, long.Parse(value)));

            case 2:
                if (subType != 0x14 && subType != 0x1E && subType != 0x1F && subType != 0x21)
                {
                    return(new Argument(type, long.Parse(value)));
                }

                if (!StringValue.IsMatch(value))
                {
                    return(new Argument(type, long.Parse(value)));
                }

                var stringValue = StringValue.Match(value).Groups.Values.Skip(1).First().Value;
                stringWriter.Write(stringValue);
                var stringHash = stringWriter.GetHash(stringValue);

                return(new Argument(type, stringHash));

            case 3:
                return(new Argument(type, BitConverter.SingleToInt32Bits(float.Parse(value, CultureInfo.GetCultureInfo("en-gb")))));

            case 4:
                if (!IsParameter.IsMatch(value))
                {
                    return(new Argument(type, long.Parse(value)));
                }

                var argumentValue = IsParameter.Match(value).Groups.Values.Skip(1).First().Value;
                var argType       = value[0];
                var offset        = argType == 'v' ? 1000 :
                                    argType == 'x' ? 2000 :
                                    argType == 'p' ? 3000 : 4000;
                return(new Argument(type, long.Parse(argumentValue) + offset));

            case 24:
                var stringValue1 = StringValue.Match(value).Groups.Values.Skip(1).First().Value;
                return(new Argument(type, stringWriter.Write(stringValue1)));

            case 25:
                var stringValue2 = StringValue.Match(value).Groups.Values.Skip(1).First().Value;
                return(new Argument(type, stringWriter.Write(stringValue2)));

            default:
                return(null);
            }
        }
Exemplo n.º 4
0
        private Stream WriteJumps(IList <Jump> jumps, IList <Function> functions, IList <Instruction> instructions, IStringWriter stringWriter)
        {
            var jumpStream = new MemoryStream();

            using var bw = new BinaryWriterX(jumpStream, true);
            foreach (var jump in jumps)
            {
                var relatedFunction = functions.First(x => x.Jumps.Contains(jump));
                var lastInstruction = relatedFunction.Instructions.Last();

                var instructionIndex = instructions.IndexOf(jump.Instruction);
                bw.WriteType(new Xq32Jump
                {
                    instructionIndex = instructionIndex == -1 ? instructions.IndexOf(lastInstruction) + 1 : instructionIndex,
                    nameOffset       = (int)stringWriter.Write(jump.Label),
                    crc32            = stringWriter.GetHash(jump.Label)
                });
            }

            jumpStream.Position = 0;
            return(jumpStream);
        }