Beispiel #1
0
        public static bool ChangeVarValue(byte[] data, File.Code code, string name, int from_value, int to_value)
        {
            ErrorContext context = new ErrorContext(code.Name);

            Ast.ILBlock block = code.Block;
            bool        found = false;

            foreach (Ast.ILExpression expr in block.GetSelfAndChildrenRecursive <Ast.ILExpression>(x => x.Code == GMCode.Assign))
            {
                Ast.ILVariable v = expr.Arguments[0].Operand as Ast.ILVariable;
                Ast.ILValue    value;

                if (v.Name == name &&
                    Ast.PatternMatching.Match(expr.Arguments[1], GMCode.Constant, out value) && value.IntValue == from_value)
                {
                    found = true;
                    Context.dataWinChanged |= true;
                    Debug.Assert(value.DataOffset != null);
                    int offset = (int)value.DataOffset;
                    if (value.Type == GM_Type.Short)
                    {
                        ChangeOffset(data, (uint)offset, (short)to_value);
                    }
                    else
                    {
                        ChangeOffset(data, (uint)offset, to_value);
                    }
                    context.Message("Changed {0}={1} to {0}={2} at offset 0x{3:X8}", name, from_value, to_value, (int)value.DataOffset);
                }
            }
            if (!found)
            {
                context.Message("Could Not find var '{0}'", name);
            }
            return(found);
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            // Context.doThreads = false;
            //  Context.doXML = true;
            //  Context.doAssigmentOffsets = true;
            // ugh have to do it here?
            string dataWinFileName = args.ElementAtOrDefault(0);

            if (string.IsNullOrWhiteSpace(dataWinFileName))
            {
                InstructionError("Missing data.win file");
            }
            try
            {
                File.LoadDataWin(dataWinFileName);
            }
            catch (Exception e)
            {
                Context.Error(e);
                InstructionError("Could not open data.win file {0}\n Exception:", dataWinFileName, e.Message);
            }
            List <string> chunks = new List <string>();

            byte[] changedData = null;
            for (int i = 1; i < args.Length; i++)
            {
                string a = args[i];
                if (string.IsNullOrWhiteSpace(a))
                {
                    continue;                               // does this ever happen?
                }
                switch (a)
                {
                case "-printOffset":
                {
                    Context.saveChangedDataWin = true;

                    string offset_name = args.ElementAtOrDefault(i + 1);
                    i += 1;
                    uint offset_int;
                    if (!TryParseOffset(offset_name, out offset_int))
                    {
                        Context.FatalError("Cannot parse {0} value in -printOffset", offset_name);
                    }
                    Context.Message(Context.FormatDebugOffset(changedData ?? File.DataWinRaw, (int)offset_int));
                }
                break;

                case "-changeInt":
                case "-changeShort":
                {
                    Context.saveChangedDataWin = true;

                    string offset_name = args.ElementAtOrDefault(i + 1);
                    string to_value    = args.ElementAtOrDefault(i + 2);
                    i += 2;
                    uint offset_int;
                    int  to_int;
                    if (!TryParseOffset(offset_name, out offset_int))
                    {
                        Context.FatalError("Cannot parse {0} value in -changeShort", offset_name);
                    }
                    if (!TryParseHex(to_value, out to_int))
                    {
                        Context.FatalError("Cannot parse {0} value in -changeShort", to_value);
                    }
                    if (changedData == null)
                    {
                        changedData = File.CopyData();
                        File.LoadEveything();
                    }
                    if (a == "-changeShort")
                    {
                        File.ChangeOffset(changedData, offset_int, (short)to_int);
                    }
                    else
                    {
                        File.ChangeOffset(changedData, offset_int, to_int);
                    }
                }
                break;

                case "-changeVar":
                {
                    Context.saveChangedDataWin = true;
                    string code_name  = args.ElementAtOrDefault(i + 1);
                    string var_name   = args.ElementAtOrDefault(i + 2) ?? "";
                    string from_value = args.ElementAtOrDefault(i + 3) ?? "";
                    string to_value   = args.ElementAtOrDefault(i + 4) ?? "";
                    int    from_int;
                    int    to_int;
                    if (!TryParseHex(from_value, out from_int))
                    {
                        Context.FatalError("Cannot parse {0} value in -change", from_value);
                    }
                    if (!TryParseHex(to_value, out to_int))
                    {
                        Context.FatalError("Cannot parse {0} value in -change", to_value);
                    }
                    i += 4;

                    if (changedData == null)
                    {
                        changedData = File.CopyData();
                        File.LoadEveything();
                    }

                    File.Code   code   = null;
                    File.Script script = null;
                    if (File.TryLookup(code_name, out code) || File.TryLookup(code_name, out script))
                    {
                        if (script != null)
                        {
                            code = script.Code;
                        }

                        File.ChangeVarValue(changedData, code, var_name, from_int, to_int);
                    }
                    else
                    {
                        Context.Error("'{0}' code/script not found", code_name);
                    }
                }
                break;

                case "-output":
                {
                    i++;
                    string dir = args.ElementAtOrDefault(i);
                    if (string.IsNullOrWhiteSpace(dir))
                    {
                        InstructionError("Missing otuput directory");
                    }
                    Context.CheckAndSetOutputDirectory(dir);
                }
                break;

                case "-delete":
                    Context.deleteDirectorys = true;
                    break;

                case "-lua":
                    Context.doLua = true;
                    Context.doXML = false;
                    break;

                case "-oneFile":
                    Context.oneFile = true;
                    break;

                case "-constOffsets":
                    Context.doAssigmentOffsets = true;
                    break;

                case "-mask":
                    Context.saveAllMasks = true;
                    break;

                case "-png":
                    Context.saveAllPngs = true;
                    break;

                case "-xml":
                    Context.doXML = true;
                    break;

                case "-search":
                    Context.doSearch = true;
                    break;

                case "-json":
                    Context.doXML = false;
                    break;

                case "-old":
                    Context.Version = UndertaleVersion.V10000;
                    break;

                case "-debug":
                    Context.Debug = true;
                    break;

                case "-nothread":
                    Context.doThreads = false;
                    break;

                case "-watch":
                    Context.debugSearch = true;
                    break;

                default:
                    if (a[0] == '-')
                    {
                        InstructionError("bad flag '{0}'", a);
                    }
                    if (char.IsLetter(a[0]))
                    {
                        chunks.Add(a);
                    }
                    break;
                }
            }
            Context.CheckAndSetOutputDirectory();

            ErrorContext.StartErrorSystem();
            if (Context.saveChangedDataWin)
            {
                if (changedData != null)
                {
                    using (var file = Context.CreateFileStream("changed_data.win", FileMode.Create, true))
                    {
                        file.Write(changedData, 0, changedData.Length);
                        file.Flush();
                    }
                }
            }
            else
            {
                File.LoadEveything();
                var w = new Writers.AllWriter();
                if (Context.doSearch)
                {
                    var results = File.Search(chunks);
                    if (results.Count == 0)
                    {
                        Context.Error("No data found in search");
                    }
                    string path = ".";
                    if (Context.doThreads)
                    {
                        Parallel.ForEach(results, result => AllWriter.DoSingleItem(path, result));
                    }
                    else
                    {
                        foreach (var result in results)
                        {
                            AllWriter.DoSingleItem(path, result);
                        }
                    }
                }
                else if (Context.debugSearch)
                {
                    Context.doThreads = false;
                    Context.Debug     = true;
                    var results = File.Search(chunks);
                    if (results.Count == 0)
                    {
                        Context.FatalError("No data found in search");
                    }
                    foreach (var f in new DirectoryInfo(".").GetFiles("*.txt"))
                    {
                        if (System.IO.Path.GetFileName(f.Name) != "errors.txt")
                        {
                            f.Delete();                                                     // clear out eveything
                        }
                    }
                    foreach (var a in results)
                    {
                        File.Code c = a as File.Code;
                        if (c != null)
                        {
                            var error = new ErrorContext(c.Name);
                            error.Message("Decompiling");
                            Context.Debug = true;
                            var block = c.Block;
                            if (block != null)
                            {
                                using (Writers.BlockToCode to = new Writers.BlockToCode(c.Name + "_watch.js"))
                                    to.Write(block);
                                error.Message("Finished Decompiling");
                            }
                            else
                            {
                                error.Message("Block is null");
                            }
                        }
                        else
                        {
                            Context.Error("Code '{0} not found", a);
                        }
                    }
                    //Context.HackyDebugWatch = new HashSet<string>(chunks);
                    // w.AddAction("code");
                }
                else
                {
                    if (chunks.Count == 0)
                    {
                        chunks.Add("everything");
                    }
                    foreach (var a in chunks)
                    {
                        w.AddAction(a);
                    }
                }
                w.FinishProcessing();
            }
            GoodExit();
        }