Exemplo n.º 1
0
    //////////////////////////////////////////
    /// GetExample()
    /// Returns an example of this class, used
    /// for validating json serialization.
    //////////////////////////////////////////
    public static ModificationData GetExample() {
        ModificationData example = new ModificationData();
        example.Target = "Strength";
        example.ModType = ModificationTypes.Flat;
        example.PerkKeys = new List<string>() { "PerkA", "PerkB" };
        example.Amount = 3;

        return example;
    }
Exemplo n.º 2
0
        protected static void BuildModificationData(ModificationData A, ModificationData B)
        {
            int N               = A.HashedPieces.Length;
            int M               = B.HashedPieces.Length;
            int MAX             = M + N + 1;
            var forwardDiagonal = new int[MAX + 1];
            var reverseDiagonal = new int[MAX + 1];

            BuildModificationData(A, 0, N, B, 0, M, forwardDiagonal, reverseDiagonal);
        }
Exemplo n.º 3
0
    //////////////////////////////////////////
    /// GetExample()
    /// Returns an example of this class, used
    /// for validating json serialization.
    //////////////////////////////////////////
    public static ModificationData GetExample()
    {
        ModificationData example = new ModificationData();

        example.Target   = "Strength";
        example.ModType  = ModificationTypes.Flat;
        example.PerkKeys = new List <string>()
        {
            "PerkA", "PerkB"
        };
        example.Amount = 3;

        return(example);
    }
Exemplo n.º 4
0
    //////////////////////////////////////////
    /// GetModification()
    /// Returns the modification for the
    /// incoming key of this effect (as an
    /// integer).
    //////////////////////////////////////////
    public int GetModification(string i_strKey)
    {
        // find the modification
        ModificationData data = GetModificationData(i_strKey);

        // if the data is not null, return it's modification
        if (data != null)
        {
            return((int)data.Amount);
        }
        else
        {
            return(0);
        }
    }
Exemplo n.º 5
0
            public void Will_return_empty_modifications_for_empty_strings()
            {
                var differ = new TestableDiffer();
                var a      = new ModificationData("");
                var b      = new ModificationData("");

                a.HashedPieces  = new int[0];
                b.HashedPieces  = new int[0];
                a.Modifications = new bool[a.HashedPieces.Length];
                b.Modifications = new bool[b.HashedPieces.Length];

                differ.TestBuildModificationData(a, b);

                Assert.Empty(a.Modifications);
                Assert.Empty(b.Modifications);
            }
Exemplo n.º 6
0
            public void Will_return_correct_modifications_count_for_random_data(int[] aLines, int[] bLines, int editLength)
            {
                var differ = new TestableDiffer();
                var a      = new ModificationData("");
                var b      = new ModificationData("");

                a.HashedPieces  = aLines;
                b.HashedPieces  = bLines;
                a.Modifications = new bool[aLines.Length];
                b.Modifications = new bool[bLines.Length];

                differ.TestBuildModificationData(a, b);

                int modCount = a.Modifications.Count(x => x == true) + b.Modifications.Count(x => x == true);

                Assert.Equal(editLength, modCount);
            }
Exemplo n.º 7
0
            public void Will_return_all_modifications_for_non_empty_vs_empty_string()
            {
                var differ = new TestableDiffer();
                var a      = new ModificationData("cat\nhat\npat\nmatt");
                var b      = new ModificationData("");

                a.HashedPieces  = new[] { 1, 2, 3, 4 };
                b.HashedPieces  = new int[] { };
                a.Modifications = new bool[a.HashedPieces.Length];
                b.Modifications = new bool[b.HashedPieces.Length];

                differ.TestBuildModificationData(a, b);

                foreach (var mod in a.Modifications)
                {
                    Assert.True(mod);
                }
            }
Exemplo n.º 8
0
        private static void BuildPieceHashes(IDictionary <string, int> pieceHash, ModificationData data, bool ignoreWhitespace, bool ignoreCase, Func <string, string[]> chunker)
        {
            string[] pieces;

            if (string.IsNullOrEmpty(data.RawData))
            {
                pieces = new string[0];
            }
            else
            {
                pieces = chunker(data.RawData);
            }

            data.Pieces        = pieces;
            data.HashedPieces  = new int[pieces.Length];
            data.Modifications = new bool[pieces.Length];

            for (int i = 0; i < pieces.Length; i++)
            {
                string piece = pieces[i];
                // if (ignoreWhitespace) piece = piece.TrimEnd(new char [] {(char)1}).Trim();  // 2015/7/18
                if (ignoreWhitespace)
                {
                    piece = piece.Trim();
                }
                if (ignoreCase)
                {
                    piece = piece.ToUpperInvariant();
                }

                if (pieceHash.ContainsKey(piece))
                {
                    data.HashedPieces[i] = pieceHash[piece];
                }
                else
                {
                    data.HashedPieces[i] = pieceHash.Count;
                    pieceHash[piece]     = pieceHash.Count;
                }
            }
        }
Exemplo n.º 9
0
            public void Will_return_correct_modifications_for_strings_with_two_differences()
            {
                var differ = new TestableDiffer();
                var a      = new ModificationData("cat\nfat\ntac");
                var b      = new ModificationData("cat\nmatt\ntac");

                a.HashedPieces  = new[] { 1, 2, 3 };
                b.HashedPieces  = new[] { 1, 4, 3 };
                a.Modifications = new bool[a.HashedPieces.Length];
                b.Modifications = new bool[b.HashedPieces.Length];

                differ.TestBuildModificationData(a, b);

                Assert.False(a.Modifications[0]);
                Assert.True(a.Modifications[1]);
                Assert.False(a.Modifications[2]);

                Assert.False(b.Modifications[0]);
                Assert.True(b.Modifications[1]);
                Assert.False(b.Modifications[2]);
            }
Exemplo n.º 10
0
            public void Will_return_no_modifications_for_same_strings()
            {
                var differ = new TestableDiffer();
                var a      = new ModificationData("cat\nhat\npat\nmatt");
                var b      = new ModificationData("cat\nhat\npat\nmatt");

                a.HashedPieces  = new[] { 1, 2, 3, 4 };
                b.HashedPieces  = new[] { 1, 2, 3, 4 };
                a.Modifications = new bool[a.HashedPieces.Length];
                b.Modifications = new bool[b.HashedPieces.Length];

                differ.TestBuildModificationData(a, b);

                foreach (var mod in a.Modifications)
                {
                    Assert.False(mod);
                }
                foreach (var mod in b.Modifications)
                {
                    Assert.False(mod);
                }
            }
Exemplo n.º 11
0
            public void Will_return_all_modifications_for_unique_strings()
            {
                var differ = new TestableDiffer();
                var a      = new ModificationData("cat\nhat\npat\nmatt");
                var b      = new ModificationData("door\nfloor\nbore\nmore");

                a.HashedPieces  = new[] { 1, 2, 3, 4 };
                b.HashedPieces  = new[] { 5, 6, 7, 8 };
                a.Modifications = new bool[a.HashedPieces.Length];
                b.Modifications = new bool[b.HashedPieces.Length];

                differ.TestBuildModificationData(a, b);

                foreach (var mod in a.Modifications)
                {
                    Assert.True(mod);
                }
                foreach (var mod in b.Modifications)
                {
                    Assert.True(mod);
                }
            }
Exemplo n.º 12
0
            public void Will_return_correct_modifications_two_partially_similar_strings()
            {
                var differ = new TestableDiffer();
                var a      = new ModificationData("cat\nhat\npat\nmatt");
                var b      = new ModificationData("cat\nmatt\ntac");

                a.HashedPieces  = new[] { 1, 2, 3, 4 };
                b.HashedPieces  = new[] { 1, 4, 5 };
                a.Modifications = new bool[a.HashedPieces.Length];
                b.Modifications = new bool[b.HashedPieces.Length];

                differ.TestBuildModificationData(a, b);

                Assert.False(a.Modifications[0]);
                Assert.True(a.Modifications[1]);
                Assert.True(a.Modifications[2]);
                Assert.False(a.Modifications[3]);

                Assert.False(b.Modifications[0]);
                Assert.False(b.Modifications[1]);
                Assert.True(b.Modifications[2]);
            }
    private void UpdateStats(ModificationData modData)
    {
        if (!modData.changed)
        {
            return;
        }

        statsLock.EnterWriteLock();
        try
        {
            currentStats.NumRomBytesModified++;

            currentStats.NumMarksModified  += modData.mMarks ? 1 : 0;
            currentStats.NumDbModified     += modData.mDb ? 1 : 0;
            currentStats.NumDpModified     += modData.mDp ? 1 : 0;
            currentStats.NumXFlagsModified += modData.mX ? 1 : 0;
            currentStats.NumMFlagsModified += modData.mM ? 1 : 0;
        }
        finally
        {
            statsLock.ExitWriteLock();
        }
    }
        public bool ParseTextLine(string line, ModificationData modData)
        {
            // caution: very performance-sensitive function, please take care when making modifications
            // string.IndexOf() is super-slow too.
            // Input lines must follow this strict format and be this exact formatting and column indices.
            // 028cde rep #$30               A:0004 X:0000 Y:0004 S:1fdd D:0000 DB:02 nvmxdiZC V:133 H: 654 F:36
            if (line.Length < 80)
            {
                return(false);
            }

            // performance: we could just parse the whitespace, but,
            // tracelogs have a huge amount of lines. so we parse the first line,
            // then save the offsets for all other lines in the same file.
            if (TextImportFormatCached.LastLineLength != line.Length)
            {
                TextImportFormatCached.RecomputeCachedIndicesBasedOn(line);
            }

            // TODO: add error treatment / validation here.

            modData.SnesAddress = (int)ByteUtil.ByteParseHex(line, 0, 6);
            modData.DirectPage  = (int)ByteUtil.ByteParseHex(line, TextImportFormatCached.D, 4);
            modData.DataBank    = (int)ByteUtil.ByteParseHex(line, TextImportFormatCached.Db, 2);

            // 'X' (if emulation mode) or 'B' (if native mode) = unchecked in bsnesplus debugger UI = (8bit)
            // 'x' or '.' = checked (16bit)
            modData.XFlagSet = line[TextImportFormatCached.Fx] == 'X' || line[TextImportFormatCached.Fx] == 'B';

            // 'M' (if emulation mode) or '1' (if native mode) = unchecked in bsnesplus debugger UI = (8bit)
            // 'm' or '.' = checked (16bit)
            modData.MFlagSet = line[TextImportFormatCached.Fm] == 'M' || line[TextImportFormatCached.Fm] == '1';

            // TODO: we could capture native vs emulation mode here and mark that.

            return(true);
        }
Exemplo n.º 15
0
        public DiffResult CreateCustomDiffs(string oldText, string newText, bool ignoreWhiteSpace, bool ignoreCase, Func <string, string[]> chunker)
        {
            if (oldText == null)
            {
                throw new ArgumentNullException("oldText");
            }
            if (newText == null)
            {
                throw new ArgumentNullException("newText");
            }
            if (chunker == null)
            {
                throw new ArgumentNullException("chunker");
            }

            var pieceHash = new Dictionary <string, int>();
            var lineDiffs = new List <DiffBlock>();

            var modOld = new ModificationData(oldText);
            var modNew = new ModificationData(newText);

            BuildPieceHashes(pieceHash, modOld, ignoreWhiteSpace, ignoreCase, chunker);
            BuildPieceHashes(pieceHash, modNew, ignoreWhiteSpace, ignoreCase, chunker);

            BuildModificationData(modOld, modNew);

            int piecesALength = modOld.HashedPieces.Length;
            int piecesBLength = modNew.HashedPieces.Length;
            int posA          = 0;
            int posB          = 0;

            do
            {
                while (posA < piecesALength &&
                       posB < piecesBLength &&
                       !modOld.Modifications[posA] &&
                       !modNew.Modifications[posB])
                {
                    posA++;
                    posB++;
                }

                int beginA = posA;
                int beginB = posB;
                for (; posA < piecesALength && modOld.Modifications[posA]; posA++)
                {
                    ;
                }

                for (; posB < piecesBLength && modNew.Modifications[posB]; posB++)
                {
                    ;
                }

                int deleteCount = posA - beginA;
                int insertCount = posB - beginB;
                if (deleteCount > 0 || insertCount > 0)
                {
                    lineDiffs.Add(new DiffBlock(beginA, deleteCount, beginB, insertCount));
                }
            } while (posA < piecesALength && posB < piecesBLength);

            return(new DiffResult(modOld.Pieces, modNew.Pieces, lineDiffs));
        }
Exemplo n.º 16
0
        private static void BuildModificationData
            (ModificationData A,
            int startA,
            int endA,
            ModificationData B,
            int startB,
            int endB,
            int[] forwardDiagonal,
            int[] reverseDiagonal)
        {
            while (startA < endA && startB < endB && A.HashedPieces[startA].Equals(B.HashedPieces[startB]))
            {
                startA++;
                startB++;
            }
            while (startA < endA && startB < endB && A.HashedPieces[endA - 1].Equals(B.HashedPieces[endB - 1]))
            {
                endA--;
                endB--;
            }

            int aLength = endA - startA;
            int bLength = endB - startB;

            if (aLength > 0 && bLength > 0)
            {
                EditLengthResult res = CalculateEditLength(A.HashedPieces, startA, endA, B.HashedPieces, startB, endB, forwardDiagonal, reverseDiagonal);
                if (res.EditLength <= 0)
                {
                    return;
                }

                if (res.LastEdit == Edit.DeleteRight && res.StartX - 1 > startA)
                {
                    A.Modifications[--res.StartX] = true;
                }
                else if (res.LastEdit == Edit.InsertDown && res.StartY - 1 > startB)
                {
                    B.Modifications[--res.StartY] = true;
                }
                else if (res.LastEdit == Edit.DeleteLeft && res.EndX < endA)
                {
                    A.Modifications[res.EndX++] = true;
                }
                else if (res.LastEdit == Edit.InsertUp && res.EndY < endB)
                {
                    B.Modifications[res.EndY++] = true;
                }

                BuildModificationData(A, startA, res.StartX, B, startB, res.StartY, forwardDiagonal, reverseDiagonal);

                BuildModificationData(A, res.EndX, endA, B, res.EndY, endB, forwardDiagonal, reverseDiagonal);
            }
            else if (aLength > 0)
            {
                for (int i = startA; i < endA; i++)
                {
                    A.Modifications[i] = true;
                }
            }
            else if (bLength > 0)
            {
                for (int i = startB; i < endB; i++)
                {
                    B.Modifications[i] = true;
                }
            }
        }
    private void ApplyModificationIfNeeded(ModificationData modData)
    {
        var romByte = snesData.Data.RomBytes[modData.Pc];

        modData.ApplyModificationIfNeeded(romByte);
    }
    private void ApplyModification(ModificationData modData)
    {
        ApplyModificationIfNeeded(modData);

        UpdateStats(modData);
    }
 private void UpdatePCAddress(ModificationData modData)
 {
     modData.Pc = ConvertSnesToPc(modData.SnesAddress);
 }
Exemplo n.º 20
0
 public void TestBuildModificationData(ModificationData A, ModificationData B)
 {
     BuildModificationData(A, B);
 }
        private void ApplyModificationIfNeeded(ModificationData modData)
        {
            var romByte = data.RomByteSource?.Bytes[modData.Pc];

            modData.ApplyModificationIfNeeded(romByte);
        }
        private static void ParseBinary(byte[] bytes, bool abridgedFormat, out byte opcodeLen, ModificationData modData)
        {
            // file format info from the BSNES side:
            // https://github.com/binary1230/bsnes-plus/blob/e30dfc784f3c40c0db0a09124db4ec83189c575c/bsnes/snes/cpu/core/disassembler/disassembler.cpp#L224

            // extremely performance-intensive function. be really careful when adding stuff
            if (abridgedFormat)
            {
                if (bytes.Length != 8)
                {
                    throw new InvalidDataException("Non-abridged trace data length must be 8 bytes");
                }
            }
            else
            {
                if (bytes.Length != 21)
                {
                    throw new InvalidDataException("Non-abridged trace data length must be 21 bytes");
                }
            }

            var currentIndex = 0;

            // -----------------------------
            modData.SnesAddress = ByteUtil.ByteArrayToInt24(bytes, currentIndex);
            currentIndex       += 3;

            opcodeLen = bytes[currentIndex++];

            modData.DirectPage = ByteUtil.ByteArrayToInt16(bytes, currentIndex);
            currentIndex      += 2;

            modData.DataBank = bytes[currentIndex++];

            // the flags register
            var flags = bytes[currentIndex++];

            // n = flags & 0x80;
            // v = flags & 0x40;
            // m = flags & 0x20;
            // d = flags & 0x08;
            // i = flags & 0x04;
            // z = flags & 0x02;
            // c = flags & 0x01;

            // we only care about X and M flags
            modData.XFlagSet = (flags & 0x10) != 0;
            modData.MFlagSet = (flags & 0x20) != 0;

            if (!abridgedFormat)
            {
                // skip opcodes. NOTE: must read all 5 bytes but only use up to 'opcode_len' bytes
                //var op  = bytes[currentIndex++];
                //var op0 = bytes[currentIndex++];
                //var op1 = bytes[currentIndex++];
                //var op2 = bytes[currentIndex++];
                currentIndex += 4;

                // skip A register
                currentIndex += 2;

                // skip X register
                currentIndex += 2;

                // skip Y register
                currentIndex += 2;

                // skip S register
                currentIndex += 2;

                // skip, flag 'e' for emulation mode or not
                // skip E(emu) flag <-- NOTE: we might... want this someday.
                currentIndex += 1;
            }

            Debug.Assert(currentIndex == bytes.Length);
        }