Example #1
0
        public static List <DotHackPatch> GetObjectsFromPatchSheet(string patchSheet = "Patches")
        {
            List <DotHackPatch> objects = new();
            var values = ExcelReader.GetValuesFromSheet(patchSheet);

            if (values != null && values.Count > 0)
            {
                foreach (var row in values)
                {
                    DotHackPatch o = new DotHackPatch()
                    {
                        Name                     = (string)row[0],
                        DataSheetName            = (string)row[1],
                        TextSheetName            = (string)row[2],
                        OfflineFile              = DotHackFiles.GetFileByName((string)row[3]),
                        OnlineFile               = DotHackFiles.GetFileByName((string)row[4]),
                        OfflineBaseAddress       = int.Parse((string)row[5], NumberStyles.HexNumber),
                        OnlineBaseAddress        = int.Parse((string)row[6], NumberStyles.HexNumber),
                        OfflineStringBaseAddress = int.Parse((string)row[7], NumberStyles.HexNumber),
                        OnlineStringBaseAddress  = int.Parse((string)row[8], NumberStyles.HexNumber),
                        ObjectReadLength         = int.Parse((string)row[9], NumberStyles.HexNumber),
                        ObjectCount              = int.Parse((string)row[10]),
                        StringByteLimit          = int.Parse((string)row[11], NumberStyles.HexNumber),
                        PointerOffsets           = new int[row.Count - 12]
                    };
                    for (int i = 0; i < o.PointerOffsets.Length; i++)
                    {
                        o.PointerOffsets[i] = int.Parse((string)row[12 + i], NumberStyles.HexNumber);
                    }
                    objects.Add(o);
                }
            }

            return(objects);
        }
Example #2
0
        private static void UpdateISO(string directory, DotHackPatch patch)
        {
            bool writeOffline = patch.OfflineFile.FileName != DotHackFiles.NONE.FileName,
                 writeOnline  = patch.OnlineFile.FileName != DotHackFiles.NONE.FileName;

            using (FileStream isoStream = File.Open(directory, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                using (BinaryWriter bw = new BinaryWriter(isoStream))
                {
                    Dictionary <int, int> offsetPairs = new Dictionary <int, int>();

                    //If we already made the text pointer dictionary we don't need to redo any of this
                    if (patch.TextSheetName != "None" && !textPointerDictionaries.TryGetValue(patch.TextSheetName, out offsetPairs))
                    {
                        Log.Logger.Information($"Patching {patch.Name} Text..");
                        Dictionary <int, string> pointerTextPairs = PatchHandler.GetNewStringsFromSheet($"{patch.TextSheetName}");
                        offsetPairs = new Dictionary <int, int>();
                        int newoff = 0;
                        foreach (KeyValuePair <int, string> kvp in pointerTextPairs)
                        {
                            if (patch.PointerOffsets.Length == 0)
                            {
                                newoff = kvp.Key;
                            }
                            if (!offsetPairs.ContainsKey(kvp.Key))
                            {
                                offsetPairs.Add(kvp.Key, newoff);
                            }
                            if (writeOffline)
                            {
                                bw.BaseStream.Position = patch.OfflineFile.ISOLocation + patch.OfflineStringBaseAddress + newoff;
                                bw.Write(enc.GetBytes(kvp.Value.Replace("\n", "\0").Replace("`", "\n")));
                            }
                            if (writeOnline)
                            {
                                bw.BaseStream.Position = patch.OnlineFile.ISOLocation + patch.OnlineStringBaseAddress + newoff;
                                bw.Write(enc.GetBytes(kvp.Value.Replace("\n", "\0").Replace("`", "\n")));
                            }
                            newoff += enc.GetBytes(kvp.Value).Length;
                            if (newoff > patch.StringByteLimit)
                            {
                                Log.Logger.Warning("Writing outside data bounds!");
                            }
                        }
                        textPointerDictionaries.Add(patch.TextSheetName, offsetPairs);
                    }

                    if (patch.DataSheetName != "None")
                    {
                        Log.Logger.Information($"Patching {patch.Name} Data..");
                        var dataPatches = PatchHandler.GetPointersFromSheet($"{patch.DataSheetName}");
                        foreach (KeyValuePair <int, List <int> > kvp in dataPatches)
                        {
                            for (int i = 0; i < kvp.Value.Count; i++)
                            {
                                int p = kvp.Value[i];
                                if (p != -1)
                                {
                                    //If an object has no text associated, we write the value data directly to the address
                                    if (offsetPairs.Count == 0)
                                    {
                                        if (writeOffline)
                                        {
                                            bw.BaseStream.Position = patch.OfflineFile.ISOLocation + patch.OfflineBaseAddress + kvp.Key + i * 4;
                                            bw.Write(LittleEndian((p).ToString("X8")));
                                        }
                                        if (writeOnline)
                                        {
                                            bw.BaseStream.Position = patch.OnlineFile.ISOLocation + patch.OnlineBaseAddress + kvp.Key + i * 4;
                                            bw.Write(LittleEndian((p).ToString("X8")));
                                        }
                                    }
                                    else
                                    {
                                        offsetPairs.TryGetValue(p, out int s);
                                        if (writeOffline)
                                        {
                                            bw.BaseStream.Position = patch.OfflineFile.ISOLocation + patch.OfflineBaseAddress + kvp.Key + patch.PointerOffsets[i];
                                            bw.Write(LittleEndian((patch.OfflineStringBaseAddress + patch.OfflineFile.LiveMemoryOffset + s).ToString("X8")));
                                        }
                                        if (writeOnline)
                                        {
                                            bw.BaseStream.Position = patch.OnlineFile.ISOLocation + patch.OnlineBaseAddress + kvp.Key + patch.PointerOffsets[i];
                                            bw.Write(LittleEndian((patch.OnlineStringBaseAddress + patch.OnlineFile.LiveMemoryOffset + s).ToString("X8")));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }