├── .gitattributes ├── .gitignore ├── HATE.sln ├── HATE ├── App.config ├── Extensions.cs ├── Functionality.cs ├── HATE.csproj ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── PHATE.csproj ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── SafeMethods.cs ├── Shuffle.cs ├── hateicon.ico └── packages.config ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /HATE.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29409.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HATE", "HATE\HATE.csproj", "{2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Debug|x64.ActiveCfg = Debug|x64 21 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Debug|x64.Build.0 = Debug|x64 22 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Debug|x86.ActiveCfg = Debug|x86 23 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Debug|x86.Build.0 = Debug|x86 24 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Release|x64.ActiveCfg = Release|x64 27 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Release|x64.Build.0 = Release|x64 28 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Release|x86.ActiveCfg = Release|x86 29 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1}.Release|x86.Build.0 = Release|x86 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {6404AB49-52F3-46D3-8809-1A3BBDB9D1F1} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /HATE/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /HATE/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace HATE 6 | { 7 | public static class Extensions 8 | { 9 | public static void Shuffle(this IList list, Random random) 10 | { 11 | if (random == null) 12 | throw new ArgumentNullException(nameof(random)); 13 | 14 | int n = list.Count; 15 | while (n > 1) 16 | { 17 | n--; 18 | int k = random.Next(n + 1); 19 | T value = list[k]; 20 | list[k] = list[n]; 21 | list[n] = value; 22 | } 23 | } 24 | 25 | public static void Shuffle(this IList list, Action swapAction, Random random) 26 | { 27 | if (random == null) 28 | throw new ArgumentNullException(nameof(random)); 29 | 30 | int n = list.Count; 31 | while (n-- > 1) 32 | { 33 | int k = random.Next(n + 1); 34 | swapAction(list[n], list[k]); 35 | } 36 | } 37 | 38 | public static byte[] Garble(this byte[] array, float chnc, Random random) 39 | { 40 | if (random == null) 41 | throw new ArgumentNullException(nameof(random)); 42 | 43 | return array.Select(x => (char.IsLetterOrDigit((char)x) && random.NextDouble() < chnc) ? (byte)(random.Next(75) + 47) : x).ToArray(); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /HATE/Functionality.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | using System.Windows.Forms; 6 | 7 | namespace HATE 8 | { 9 | public class StringPointer 10 | { 11 | public ResourcePointer Base; 12 | public string Ending; 13 | public string Str; 14 | 15 | public StringPointer(ResourcePointer ptr, string str) 16 | { 17 | Base = ptr; 18 | Str = str; 19 | char[] FormatChars = { '%', '/', 'C' }; 20 | List Ending = new List(); 21 | 22 | for (int i = 1; i < str.Length; i++) 23 | { 24 | char C = str[str.Length - i]; 25 | 26 | if (FormatChars.Contains(C)) 27 | Ending.Add(C); 28 | else 29 | break; 30 | } 31 | 32 | Ending.Reverse(); 33 | this.Ending = new string(Ending.ToArray()); 34 | } 35 | } 36 | 37 | public class ResourcePointer 38 | { 39 | public int Address; 40 | public int Location; 41 | 42 | public ResourcePointer(int ptr, int loc) { Address = ptr; Location = loc; } 43 | public ResourcePointer(byte[] ptr, int loc) { Address = BitConverter.ToInt32(ptr, 0); Location = loc; } 44 | } 45 | 46 | 47 | 48 | partial class MainForm 49 | { 50 | public bool ShuffleAudio_Func(Random random, float chance, StreamWriter logstream) 51 | { 52 | return Shuffle.LoadDataAndFind("SOND", random, chance, logstream, _dataWin, Shuffle.SimpleShuffle) && 53 | Shuffle.LoadDataAndFind("AUDO", random, chance, logstream, _dataWin, Shuffle.SimpleShuffle); 54 | } 55 | 56 | public bool ShuffleBG_Func(Random random, float chance, StreamWriter logstream) 57 | { 58 | return Shuffle.LoadDataAndFind("BGND", random, chance, logstream, _dataWin, Shuffle.SimpleShuffle); 59 | } 60 | 61 | public bool ShuffleFont_Func(Random random, float chance, StreamWriter logstream) 62 | { 63 | return Shuffle.LoadDataAndFind("FONT", random, chance, logstream, _dataWin, Shuffle.SimpleShuffle); 64 | } 65 | 66 | public bool HitboxFix_Func(Random random_, float chance, StreamWriter logstream_) 67 | { 68 | return Shuffle.LoadDataAndFind("SPRT", random_, chance, logstream_, _dataWin, Shuffle.ComplexShuffle(Shuffle.SimpleAccumulator, HitboxFix_Shuffler, Shuffle.SimpleWriter)); 69 | } 70 | 71 | public bool ShuffleGFX_Func(Random random_, float chance, StreamWriter logstream_) 72 | { 73 | return Shuffle.LoadDataAndFind("SPRT", random_, chance, logstream_, _dataWin, Shuffle.ComplexShuffle(ShuffleGFX_Accumulator, Shuffle.SimpleShuffler, Shuffle.SimpleWriter)); 74 | } 75 | 76 | public bool ShuffleText_Func(Random random_, float chance, StreamWriter logstream_) 77 | { 78 | if (Directory.Exists("./lang") && Safe.GetFiles("./lang").Count > 0) 79 | { 80 | bool success = true; 81 | 82 | foreach (string path in Safe.GetFiles("./lang")) 83 | { 84 | success = success && Shuffle.JSONStringShuffle(path, path, random_, chance, logstream_); 85 | } 86 | return success; 87 | 88 | } 89 | else 90 | { 91 | //MessageBox.Show(lblGameName.Text); 92 | return Shuffle.LoadDataAndFind("STRG", random_, chance, logstream_, _dataWin, Shuffle.ComplexShuffle(Shuffle.SimpleAccumulator, ShuffleText_Shuffler, Shuffle.SimpleWriter)); 93 | } 94 | } 95 | 96 | // TODO: clean this 97 | public List ShuffleGFX_Accumulator(FileStream stream, Random random, float shufflechance, StreamWriter logstream) 98 | { 99 | byte[] readBuffer = new byte[Shuffle.WordSize]; 100 | int pointerNum = 0; 101 | long pointerArrayBegin = 0; 102 | List pointerList = new List(); 103 | 104 | stream.Read(readBuffer, 0, 4); 105 | pointerNum = BitConverter.ToInt32(readBuffer, 0); 106 | pointerArrayBegin = stream.Position; 107 | 108 | for (int i = 0; i < pointerNum; i++) 109 | { 110 | if (random.NextDouble() < shufflechance) 111 | { 112 | byte[] _tmp = new byte[4], _tmp2 = new byte[4]; 113 | stream.Read(_tmp, 0, 4); 114 | ResourcePointer ptr = new ResourcePointer(_tmp, (int)stream.Position - 4); 115 | long pos = stream.Position; 116 | stream.Position = ptr.Address; 117 | stream.Read(_tmp2, 0, 4); 118 | stream.Position = BitConverter.ToInt32(_tmp2, 0); 119 | 120 | List byteString = new List(); 121 | bool stringBegun = false; 122 | 123 | for (int j = 0; j < 128; j++) 124 | { 125 | byteString.Add((byte)stream.ReadByte()); 126 | 127 | if (byteString[byteString.Count - 1] == 0 && stringBegun) 128 | break; 129 | 130 | if (byteString[byteString.Count - 1] != 0) 131 | stringBegun = true; 132 | } 133 | 134 | string convertedString = new string(byteString.Where(x => x == '_' || (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || (x >= '0' && x <= '9')).Select(x => (char)x).ToArray()); 135 | 136 | if (!_friskSpriteHandles.Contains(convertedString.Trim()) || _friskMode) 137 | pointerList.Add(ptr); 138 | 139 | stream.Position = pos; 140 | } 141 | } 142 | 143 | logstream.WriteLine($"Added {pointerList.Count} out of {pointerNum} sprite pointers to SPRT List."); 144 | 145 | return pointerList; 146 | } 147 | 148 | // TODO: implement this 149 | public List HitboxFix_Shuffler(FileStream stream, Random random, float shufflechance, StreamWriter logstream, List pointerlist) 150 | { 151 | foreach (ResourcePointer spriteptr in pointerlist) 152 | { 153 | // Previous implementation of HitboxFix didn't work at all and was unsafe to boot, better implementation will be added later. 154 | } 155 | logstream.WriteLine($"Wrote {pointerlist.Count} hitboxes to {_dataWin}."); 156 | 157 | return pointerlist; 158 | } 159 | 160 | // TODO: delete this 161 | // TODO: clean this 162 | public List ShuffleText_Shuffler(FileStream stream, Random random, float shufflechance, StreamWriter logstream, List pointerlist) 163 | { 164 | string[] bannedStrings = { "_" }; 165 | List shuffledPointerList = new List(); 166 | List strPointerList = new List(); 167 | 168 | 169 | for (int i = 0; i < pointerlist.Count; i++) 170 | { 171 | stream.Position = pointerlist[i].Address; 172 | byte Strlen = (byte)stream.ReadByte(); 173 | stream.Position += 3; 174 | List ByteString = new List(); 175 | 176 | for (int j = 0; j < Strlen; j++) 177 | { 178 | ByteString.Add((byte)stream.ReadByte()); 179 | } 180 | 181 | string convertedString = new string(ByteString.Select(x => (char)x).ToArray()); 182 | 183 | if (Strlen >= 3 && !bannedStrings.Any(convertedString.Contains) && !(convertedString.Any(x => x > 127))) 184 | strPointerList.Add(new StringPointer(pointerlist[i], convertedString)); 185 | } 186 | 187 | logstream.WriteLine($"Added {strPointerList.Count} good string pointers to SprPointerList."); 188 | 189 | Dictionary> stringDict = new Dictionary>(); 190 | int totalStrings = 0; 191 | 192 | foreach (StringPointer s in strPointerList) 193 | { 194 | if (!string.IsNullOrWhiteSpace(s.Ending)) 195 | { 196 | if (!stringDict.ContainsKey(s.Ending)) 197 | stringDict[s.Ending] = new List(); 198 | 199 | stringDict[s.Ending].Add(s.Base); 200 | totalStrings++; 201 | } 202 | } 203 | 204 | foreach (string ending in stringDict.Keys) 205 | { 206 | logstream.WriteLine($"Added {stringDict[ending].Count} string pointers of ending {ending} to dialogue string List."); 207 | 208 | stringDict[ending].Shuffle(Shuffle.PointerSwapLoc, random); 209 | 210 | shuffledPointerList = shuffledPointerList.Concat(stringDict[ending]).ToList(); 211 | } 212 | 213 | return shuffledPointerList; 214 | } 215 | 216 | public void DebugListChunks(string resource_file, StreamWriter logstream) 217 | { 218 | byte[] readBuffer = new byte[4]; 219 | 220 | using (FileStream stream = new FileStream(resource_file, FileMode.OpenOrCreate)) 221 | { 222 | logstream.WriteLine($"Opened {resource_file}."); 223 | stream.Position = 8; 224 | 225 | int dataSegmentCounter = 0; 226 | 227 | while (stream.Position != stream.Length) 228 | { 229 | stream.Read(readBuffer, 0, 4); 230 | string headerName = new string(readBuffer.Select(x => (char)x).ToArray()); 231 | stream.Read(readBuffer, 0, 4); 232 | int chunk_size = BitConverter.ToInt32(readBuffer, 0); 233 | logstream.WriteLine($"Chunk #{dataSegmentCounter}: {headerName} found, size {chunk_size}."); 234 | stream.Position += chunk_size; 235 | dataSegmentCounter++; 236 | } 237 | 238 | logstream.WriteLine($"Closed {resource_file}."); 239 | } 240 | } 241 | 242 | 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /HATE/HATE.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1} 8 | WinExe 9 | Properties 10 | HATE 11 | HATE 12 | v4.5.1 13 | 512 14 | true 15 | false 16 | publish\ 17 | true 18 | Disk 19 | false 20 | Foreground 21 | 7 22 | Days 23 | false 24 | false 25 | true 26 | 7 27 | 2.1.3.7 28 | false 29 | true 30 | 31 | 32 | AnyCPU 33 | true 34 | full 35 | false 36 | bin\Debug\ 37 | DEBUG;TRACE 38 | prompt 39 | 4 40 | 7.1 41 | 42 | 43 | AnyCPU 44 | pdbonly 45 | true 46 | bin\Release\ 47 | TRACE 48 | prompt 49 | 4 50 | true 51 | 7.1 52 | 53 | 54 | hateicon.ico 55 | 56 | 57 | true 58 | bin\x86\Debug\ 59 | DEBUG;TRACE 60 | full 61 | x86 62 | prompt 63 | MinimumRecommendedRules.ruleset 64 | true 65 | 4 66 | false 67 | 68 | 69 | bin\x86\Release\ 70 | CODE_ANALYSIS;TRACE 71 | true 72 | pdbonly 73 | x86 74 | true 75 | prompt 76 | MinimumRecommendedRules.ruleset 77 | true 78 | 4 79 | 80 | 81 | true 82 | bin\x64\Debug\ 83 | DEBUG;TRACE 84 | full 85 | x64 86 | 7.1 87 | prompt 88 | MinimumRecommendedRules.ruleset 89 | true 90 | 91 | 92 | bin\x64\Release\ 93 | CODE_ANALYSIS;TRACE 94 | true 95 | pdbonly 96 | x64 97 | true 98 | 7.1 99 | prompt 100 | MinimumRecommendedRules.ruleset 101 | true 102 | 103 | 104 | 105 | ..\packages\Optional.3.2.0\lib\net451\Optional.dll 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | Form 123 | 124 | 125 | MainForm.cs 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | MainForm.cs 134 | 135 | 136 | ResXFileCodeGenerator 137 | Resources.Designer.cs 138 | Designer 139 | 140 | 141 | True 142 | Resources.resx 143 | True 144 | 145 | 146 | 147 | SettingsSingleFileGenerator 148 | Settings.Designer.cs 149 | 150 | 151 | True 152 | Settings.settings 153 | True 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | False 165 | Microsoft .NET Framework 4.6 %28x86 and x64%29 166 | true 167 | 168 | 169 | False 170 | .NET Framework 3.5 SP1 171 | false 172 | 173 | 174 | 175 | 182 | -------------------------------------------------------------------------------- /HATE/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace HATE 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | _logWriter.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Windows Form Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 33 | this.btnCorrupt = new System.Windows.Forms.Button(); 34 | this.chbShuffleText = new System.Windows.Forms.CheckBox(); 35 | this.chbShuffleGFX = new System.Windows.Forms.CheckBox(); 36 | this.chbHitboxFix = new System.Windows.Forms.CheckBox(); 37 | this.chbShuffleFont = new System.Windows.Forms.CheckBox(); 38 | this.chbShuffleBG = new System.Windows.Forms.CheckBox(); 39 | this.chbShuffleAudio = new System.Windows.Forms.CheckBox(); 40 | this.chbShowSeed = new System.Windows.Forms.CheckBox(); 41 | this.txtSeed = new System.Windows.Forms.TextBox(); 42 | this.txtPower = new System.Windows.Forms.TextBox(); 43 | this.label1 = new System.Windows.Forms.Label(); 44 | this.label2 = new System.Windows.Forms.Label(); 45 | this.btnLaunch = new System.Windows.Forms.Button(); 46 | this.label3 = new System.Windows.Forms.Label(); 47 | this.lblGameName = new System.Windows.Forms.Label(); 48 | this.SuspendLayout(); 49 | // 50 | // btnCorrupt 51 | // 52 | this.btnCorrupt.BackColor = System.Drawing.Color.Black; 53 | this.btnCorrupt.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 54 | this.btnCorrupt.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 55 | this.btnCorrupt.ForeColor = System.Drawing.Color.Coral; 56 | this.btnCorrupt.Location = new System.Drawing.Point(19, 385); 57 | this.btnCorrupt.Name = "btnCorrupt"; 58 | this.btnCorrupt.Size = new System.Drawing.Size(147, 25); 59 | this.btnCorrupt.TabIndex = 0; 60 | this.btnCorrupt.Text = "-CORRUPT-"; 61 | this.btnCorrupt.UseVisualStyleBackColor = false; 62 | this.btnCorrupt.Click += new System.EventHandler(this.button_Corrupt_Clicked); 63 | // 64 | // chbShuffleText 65 | // 66 | this.chbShuffleText.AutoSize = true; 67 | this.chbShuffleText.BackColor = System.Drawing.Color.Black; 68 | this.chbShuffleText.FlatAppearance.BorderColor = System.Drawing.Color.White; 69 | this.chbShuffleText.FlatAppearance.BorderSize = 0; 70 | this.chbShuffleText.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; 71 | this.chbShuffleText.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 72 | this.chbShuffleText.Font = new System.Drawing.Font("Comic Sans MS", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 73 | this.chbShuffleText.ForeColor = System.Drawing.Color.White; 74 | this.chbShuffleText.Location = new System.Drawing.Point(12, 249); 75 | this.chbShuffleText.Name = "chbShuffleText"; 76 | this.chbShuffleText.Size = new System.Drawing.Size(150, 31); 77 | this.chbShuffleText.TabIndex = 1; 78 | this.chbShuffleText.Text = "Shuffle Text"; 79 | this.chbShuffleText.UseVisualStyleBackColor = false; 80 | this.chbShuffleText.CheckedChanged += new System.EventHandler(this.chbShuffleText_CheckedChanged); 81 | // 82 | // chbShuffleGFX 83 | // 84 | this.chbShuffleGFX.AutoSize = true; 85 | this.chbShuffleGFX.BackColor = System.Drawing.Color.Black; 86 | this.chbShuffleGFX.FlatAppearance.BorderColor = System.Drawing.Color.White; 87 | this.chbShuffleGFX.FlatAppearance.BorderSize = 0; 88 | this.chbShuffleGFX.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; 89 | this.chbShuffleGFX.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 90 | this.chbShuffleGFX.Font = new System.Drawing.Font("Comic Sans MS", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 91 | this.chbShuffleGFX.ForeColor = System.Drawing.Color.White; 92 | this.chbShuffleGFX.Location = new System.Drawing.Point(12, 212); 93 | this.chbShuffleGFX.Name = "chbShuffleGFX"; 94 | this.chbShuffleGFX.Size = new System.Drawing.Size(172, 31); 95 | this.chbShuffleGFX.TabIndex = 2; 96 | this.chbShuffleGFX.Text = "Shuffle Sprites"; 97 | this.chbShuffleGFX.UseVisualStyleBackColor = false; 98 | this.chbShuffleGFX.CheckedChanged += new System.EventHandler(this.chbShuffleGFX_CheckedChanged); 99 | // 100 | // chbHitboxFix 101 | // 102 | this.chbHitboxFix.AutoSize = true; 103 | this.chbHitboxFix.BackColor = System.Drawing.Color.Black; 104 | this.chbHitboxFix.FlatAppearance.BorderColor = System.Drawing.Color.White; 105 | this.chbHitboxFix.FlatAppearance.BorderSize = 0; 106 | this.chbHitboxFix.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; 107 | this.chbHitboxFix.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 108 | this.chbHitboxFix.Font = new System.Drawing.Font("Comic Sans MS", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 109 | this.chbHitboxFix.ForeColor = System.Drawing.Color.White; 110 | this.chbHitboxFix.Location = new System.Drawing.Point(11, 175); 111 | this.chbHitboxFix.Name = "chbHitboxFix"; 112 | this.chbHitboxFix.Size = new System.Drawing.Size(125, 31); 113 | this.chbHitboxFix.TabIndex = 3; 114 | this.chbHitboxFix.Text = "Hitbox Fix"; 115 | this.chbHitboxFix.UseVisualStyleBackColor = false; 116 | this.chbHitboxFix.CheckedChanged += new System.EventHandler(this.chbHitboxFix_CheckedChanged); 117 | // 118 | // chbShuffleFont 119 | // 120 | this.chbShuffleFont.AutoSize = true; 121 | this.chbShuffleFont.BackColor = System.Drawing.Color.Black; 122 | this.chbShuffleFont.FlatAppearance.BorderColor = System.Drawing.Color.White; 123 | this.chbShuffleFont.FlatAppearance.BorderSize = 0; 124 | this.chbShuffleFont.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; 125 | this.chbShuffleFont.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 126 | this.chbShuffleFont.Font = new System.Drawing.Font("Comic Sans MS", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 127 | this.chbShuffleFont.ForeColor = System.Drawing.Color.White; 128 | this.chbShuffleFont.Location = new System.Drawing.Point(11, 138); 129 | this.chbShuffleFont.Name = "chbShuffleFont"; 130 | this.chbShuffleFont.Size = new System.Drawing.Size(156, 31); 131 | this.chbShuffleFont.TabIndex = 4; 132 | this.chbShuffleFont.Text = "Shuffle Fonts"; 133 | this.chbShuffleFont.UseVisualStyleBackColor = false; 134 | this.chbShuffleFont.CheckedChanged += new System.EventHandler(this.chbShuffleFont_CheckedChanged); 135 | // 136 | // chbShuffleBG 137 | // 138 | this.chbShuffleBG.AutoSize = true; 139 | this.chbShuffleBG.BackColor = System.Drawing.Color.Black; 140 | this.chbShuffleBG.FlatAppearance.BorderColor = System.Drawing.Color.White; 141 | this.chbShuffleBG.FlatAppearance.BorderSize = 0; 142 | this.chbShuffleBG.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; 143 | this.chbShuffleBG.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 144 | this.chbShuffleBG.Font = new System.Drawing.Font("Comic Sans MS", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 145 | this.chbShuffleBG.ForeColor = System.Drawing.Color.White; 146 | this.chbShuffleBG.Location = new System.Drawing.Point(11, 101); 147 | this.chbShuffleBG.Name = "chbShuffleBG"; 148 | this.chbShuffleBG.Size = new System.Drawing.Size(145, 31); 149 | this.chbShuffleBG.TabIndex = 5; 150 | this.chbShuffleBG.Text = "Shuffle GFX"; 151 | this.chbShuffleBG.UseVisualStyleBackColor = false; 152 | this.chbShuffleBG.CheckedChanged += new System.EventHandler(this.chbShuffleBG_CheckedChanged); 153 | // 154 | // chbShuffleAudio 155 | // 156 | this.chbShuffleAudio.AutoSize = true; 157 | this.chbShuffleAudio.BackColor = System.Drawing.Color.Black; 158 | this.chbShuffleAudio.FlatAppearance.BorderColor = System.Drawing.Color.White; 159 | this.chbShuffleAudio.FlatAppearance.BorderSize = 0; 160 | this.chbShuffleAudio.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; 161 | this.chbShuffleAudio.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 162 | this.chbShuffleAudio.Font = new System.Drawing.Font("Comic Sans MS", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 163 | this.chbShuffleAudio.ForeColor = System.Drawing.Color.White; 164 | this.chbShuffleAudio.Location = new System.Drawing.Point(11, 64); 165 | this.chbShuffleAudio.Name = "chbShuffleAudio"; 166 | this.chbShuffleAudio.Size = new System.Drawing.Size(156, 31); 167 | this.chbShuffleAudio.TabIndex = 6; 168 | this.chbShuffleAudio.Text = "Shuffle Audio"; 169 | this.chbShuffleAudio.UseVisualStyleBackColor = false; 170 | this.chbShuffleAudio.CheckedChanged += new System.EventHandler(this.chbShuffleAudio_CheckedChanged); 171 | // 172 | // chbShowSeed 173 | // 174 | this.chbShowSeed.AutoSize = true; 175 | this.chbShowSeed.BackColor = System.Drawing.Color.Black; 176 | this.chbShowSeed.FlatAppearance.BorderColor = System.Drawing.Color.White; 177 | this.chbShowSeed.FlatAppearance.BorderSize = 0; 178 | this.chbShowSeed.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent; 179 | this.chbShowSeed.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 180 | this.chbShowSeed.Font = new System.Drawing.Font("Comic Sans MS", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 181 | this.chbShowSeed.ForeColor = System.Drawing.Color.White; 182 | this.chbShowSeed.Location = new System.Drawing.Point(11, 286); 183 | this.chbShowSeed.Name = "chbShowSeed"; 184 | this.chbShowSeed.Size = new System.Drawing.Size(129, 31); 185 | this.chbShowSeed.TabIndex = 7; 186 | this.chbShowSeed.Text = "Show Seed"; 187 | this.chbShowSeed.UseVisualStyleBackColor = false; 188 | this.chbShowSeed.CheckedChanged += new System.EventHandler(this.chbShowSeed_CheckedChanged); 189 | // 190 | // txtSeed 191 | // 192 | this.txtSeed.BackColor = System.Drawing.Color.White; 193 | this.txtSeed.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 194 | this.txtSeed.ForeColor = System.Drawing.Color.Black; 195 | this.txtSeed.Location = new System.Drawing.Point(66, 331); 196 | this.txtSeed.Name = "txtSeed"; 197 | this.txtSeed.Size = new System.Drawing.Size(100, 20); 198 | this.txtSeed.TabIndex = 8; 199 | // 200 | // txtPower 201 | // 202 | this.txtPower.BackColor = System.Drawing.Color.White; 203 | this.txtPower.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 204 | this.txtPower.ForeColor = System.Drawing.Color.Black; 205 | this.txtPower.Location = new System.Drawing.Point(66, 357); 206 | this.txtPower.Name = "txtPower"; 207 | this.txtPower.Size = new System.Drawing.Size(100, 20); 208 | this.txtPower.TabIndex = 9; 209 | this.txtPower.Text = "0 - 255"; 210 | this.txtPower.Enter += new System.EventHandler(this.txtPower_Enter); 211 | this.txtPower.Leave += new System.EventHandler(this.txtPower_Leave); 212 | // 213 | // label1 214 | // 215 | this.label1.AutoSize = true; 216 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 217 | this.label1.ForeColor = System.Drawing.Color.White; 218 | this.label1.Location = new System.Drawing.Point(7, 331); 219 | this.label1.Name = "label1"; 220 | this.label1.Size = new System.Drawing.Size(50, 17); 221 | this.label1.TabIndex = 10; 222 | this.label1.Text = "Seed:"; 223 | // 224 | // label2 225 | // 226 | this.label2.AutoSize = true; 227 | this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 228 | this.label2.ForeColor = System.Drawing.Color.White; 229 | this.label2.Location = new System.Drawing.Point(7, 357); 230 | this.label2.Name = "label2"; 231 | this.label2.Size = new System.Drawing.Size(57, 17); 232 | this.label2.TabIndex = 11; 233 | this.label2.Text = "Power:"; 234 | // 235 | // btnLaunch 236 | // 237 | this.btnLaunch.BackColor = System.Drawing.Color.Black; 238 | this.btnLaunch.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 239 | this.btnLaunch.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 240 | this.btnLaunch.ForeColor = System.Drawing.Color.Fuchsia; 241 | this.btnLaunch.Location = new System.Drawing.Point(19, 416); 242 | this.btnLaunch.Name = "btnLaunch"; 243 | this.btnLaunch.Size = new System.Drawing.Size(147, 25); 244 | this.btnLaunch.TabIndex = 12; 245 | this.btnLaunch.Text = "-LAUNCH-"; 246 | this.btnLaunch.UseVisualStyleBackColor = false; 247 | this.btnLaunch.Click += new System.EventHandler(this.btnLaunch_Clicked); 248 | // 249 | // label3 250 | // 251 | this.label3.AutoSize = true; 252 | this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 253 | this.label3.ForeColor = System.Drawing.Color.White; 254 | this.label3.Location = new System.Drawing.Point(12, 9); 255 | this.label3.Name = "label3"; 256 | this.label3.Size = new System.Drawing.Size(114, 17); 257 | this.label3.TabIndex = 14; 258 | this.label3.Text = "Current Game:"; 259 | // 260 | // lblGameName 261 | // 262 | this.lblGameName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 263 | | System.Windows.Forms.AnchorStyles.Right))); 264 | this.lblGameName.AutoSize = true; 265 | this.lblGameName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 266 | this.lblGameName.ForeColor = System.Drawing.Color.Yellow; 267 | this.lblGameName.Location = new System.Drawing.Point(12, 36); 268 | this.lblGameName.Margin = new System.Windows.Forms.Padding(3, 10, 3, 0); 269 | this.lblGameName.Name = "lblGameName"; 270 | this.lblGameName.Size = new System.Drawing.Size(88, 20); 271 | this.lblGameName.TabIndex = 15; 272 | this.lblGameName.Text = "Undertale"; 273 | this.lblGameName.TextAlign = System.Drawing.ContentAlignment.TopCenter; 274 | // 275 | // MainForm 276 | // 277 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 278 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 279 | this.BackColor = System.Drawing.Color.Black; 280 | this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 281 | this.ClientSize = new System.Drawing.Size(184, 449); 282 | this.Controls.Add(this.lblGameName); 283 | this.Controls.Add(this.label3); 284 | this.Controls.Add(this.btnLaunch); 285 | this.Controls.Add(this.label2); 286 | this.Controls.Add(this.label1); 287 | this.Controls.Add(this.txtPower); 288 | this.Controls.Add(this.txtSeed); 289 | this.Controls.Add(this.chbShowSeed); 290 | this.Controls.Add(this.chbShuffleAudio); 291 | this.Controls.Add(this.chbShuffleBG); 292 | this.Controls.Add(this.chbShuffleFont); 293 | this.Controls.Add(this.chbHitboxFix); 294 | this.Controls.Add(this.chbShuffleGFX); 295 | this.Controls.Add(this.chbShuffleText); 296 | this.Controls.Add(this.btnCorrupt); 297 | this.ForeColor = System.Drawing.Color.Black; 298 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 299 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 300 | this.MaximizeBox = false; 301 | this.MinimizeBox = false; 302 | this.MinimumSize = new System.Drawing.Size(200, 310); 303 | this.Name = "MainForm"; 304 | this.Text = "HATE"; 305 | this.Load += new System.EventHandler(this.MainForm_Load); 306 | this.ResumeLayout(false); 307 | this.PerformLayout(); 308 | 309 | } 310 | 311 | #endregion 312 | 313 | private System.Windows.Forms.Button btnCorrupt; 314 | private System.Windows.Forms.CheckBox chbShuffleText; 315 | private System.Windows.Forms.CheckBox chbShuffleGFX; 316 | private System.Windows.Forms.CheckBox chbHitboxFix; 317 | private System.Windows.Forms.CheckBox chbShuffleFont; 318 | private System.Windows.Forms.CheckBox chbShuffleBG; 319 | private System.Windows.Forms.CheckBox chbShuffleAudio; 320 | private System.Windows.Forms.CheckBox chbShowSeed; 321 | private System.Windows.Forms.TextBox txtSeed; 322 | private System.Windows.Forms.TextBox txtPower; 323 | private System.Windows.Forms.Label label1; 324 | private System.Windows.Forms.Label label2; 325 | private System.Windows.Forms.Button btnLaunch; 326 | private System.Windows.Forms.Label label3; 327 | private System.Windows.Forms.Label lblGameName; 328 | } 329 | } 330 | 331 | -------------------------------------------------------------------------------- /HATE/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Security.Principal; 7 | 8 | namespace HATE 9 | { 10 | public partial class MainForm : Form 11 | { 12 | private static class Style 13 | { 14 | private static readonly Color _btnRestoreColor = Color.LimeGreen; 15 | private static readonly Color _btnCorruptColor = Color.Coral; 16 | private static readonly string _btnRestoreLabel = " -RESTORE- "; 17 | private static readonly string _btnCorruptLabel = " -CORRUPT- "; 18 | private static readonly Color _optionSet = Color.Yellow; 19 | private static readonly Color _optionUnset = Color.White; 20 | 21 | public static Color GetOptionColor(bool b) { return b ? _optionSet : _optionUnset; } 22 | public static Color GetCorruptColor(bool b) { return b ? _btnCorruptColor : _btnRestoreColor; } 23 | public static string GetCorruptLabel(bool b) { return b ? _btnCorruptLabel : _btnRestoreLabel; } 24 | } 25 | 26 | private StreamWriter _logWriter; 27 | 28 | private bool _shuffleGFX = false; 29 | private bool _shuffleText = false; 30 | private bool _hitboxFix = false; 31 | private bool _shuffleFont = false; 32 | private bool _shuffleBG = false; 33 | private bool _shuffleAudio = false; 34 | private bool _corrupt = false; 35 | private bool _showSeed = false; 36 | private bool _friskMode = false; 37 | private float _truePower = 0; 38 | private readonly string _defaultPowerText = "0 - 255"; 39 | private readonly string _dataWin = "data.win"; 40 | 41 | private readonly string[] _friskSpriteHandles = { "spr_maincharal", "spr_maincharau", "spr_maincharar", "spr_maincharad", "spr_maincharau_stark", "spr_maincharar_stark", "spr_maincharal_stark", "spr_maincharad_pranked", "spr_maincharal_pranked", "spr_maincharad_umbrellafall", "spr_maincharau_umbrellafall", "spr_maincharar_umbrellafall", "spr_maincharal_umbrellafall", "spr_maincharad_umbrella", "spr_maincharau_umbrella", "spr_maincharar_umbrella", "spr_maincharal_umbrella", "spr_charad", "spr_charad_fall", "spr_charar", "spr_charar_fall", "spr_charal", "spr_charal_fall", "spr_charau", "spr_charau_fall", "spr_maincharar_shadow", "spr_maincharal_shadow", "spr_maincharau_shadow", "spr_maincharad_shadow", "spr_maincharal_tomato", "spr_maincharal_burnt", "spr_maincharal_water", "spr_maincharar_water", "spr_maincharau_water", "spr_maincharad_water", "spr_mainchara_pourwater", "spr_maincharad_b", "spr_maincharau_b", "spr_maincharar_b", "spr_maincharal_b", "spr_doorA", "spr_doorB", "spr_doorC", "spr_doorD", "spr_doorX" }; 42 | 43 | private static readonly DateTime _unixTimeZero = new DateTime(1970, 1, 1); 44 | private Random _random; 45 | 46 | public MainForm() 47 | { 48 | InitializeComponent(); 49 | 50 | if (!File.Exists(_dataWin)) 51 | { 52 | if (File.Exists("game.ios")) 53 | _dataWin = "game.ios"; 54 | else if (File.Exists("game.unx")) 55 | _dataWin = "game.unx"; 56 | } 57 | 58 | if (File.Exists("DELTARUNE.exe") || File.Exists("../../SURVEY_PROGRAM.app")) { lblGameName.Text = "Deltarune"; } 59 | else if (File.Exists("UNDERTALE.exe") || File.Exists("../../UNDERTALE.app")) { lblGameName.Text = "Undertale"; } 60 | else 61 | { 62 | lblGameName.Text = GetGame().Replace(".exe", ""); 63 | if (!string.IsNullOrWhiteSpace(lblGameName.Text)) 64 | { 65 | MessageBox.Show($"We couldn't find Deltarune or Undertale in this folder, if you're using this for another game then as long there is a {_dataWin} file and the game was made with GameMaker then this program should work but there are no guarantees that it will.", "HATE", MessageBoxButtons.OK, MessageBoxIcon.Warning); 66 | } 67 | else 68 | { 69 | MessageBox.Show("We couldn't find any game in this folder, check that this is in the right folder."); 70 | } 71 | } 72 | 73 | //This is so it doesn't keep starting the program over and over in case something messes up 74 | if (Process.GetProcessesByName("HATE").Length == 1) 75 | { 76 | if (Directory.GetCurrentDirectory().Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)) || Directory.GetCurrentDirectory().Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)) && !IsElevated) 77 | { 78 | DialogResult dialogResult = MessageBox.Show($"The game is in a system protected folder and we need elevated permissions in order to mess with {_dataWin}, Do you allow us to get elevated permissions (if you press no this will just close the program as we can't do anything)", "HATE", MessageBoxButtons.YesNo, MessageBoxIcon.Information); 79 | if (dialogResult == DialogResult.Yes) 80 | { 81 | // Restart program and run as admin 82 | var exeName = Process.GetCurrentProcess().MainModule.FileName; 83 | ProcessStartInfo startInfo = new ProcessStartInfo(exeName); 84 | startInfo.Arguments = "true"; 85 | startInfo.Verb = "runas"; 86 | Process.Start(startInfo); 87 | Close(); 88 | } 89 | else 90 | { 91 | Close(); 92 | } 93 | } 94 | } 95 | 96 | _random = new Random(); 97 | 98 | UpdateCorrupt(); 99 | } 100 | 101 | public bool IsElevated 102 | { 103 | get 104 | { 105 | return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); 106 | } 107 | } 108 | 109 | public string GetGame() 110 | { 111 | if (File.Exists("DELTARUNE.exe")) { return $"{LinuxWine()} DELTARUNE.exe"; } 112 | else if (File.Exists("../../SURVEY_PROGRAM.app")) { return "../../SURVEY_PROGRAM.app"; } 113 | else if (File.Exists("UNDERTALE.exe")) { return $"{LinuxWine()} UNDERTALE.exe"; } 114 | else if (File.Exists("../../UNDERTALE.app")) { return "../../UNDERTALE.app"; } 115 | else 116 | { 117 | var files = Directory.EnumerateFiles(Directory.GetCurrentDirectory()); 118 | foreach (string s in files) 119 | if (!s.Remove(0, s.LastIndexOf("\\") + 1).Contains("HATE.exe") && s.Contains(".exe") || s.Contains(".app")) 120 | return s.Remove(0, s.LastIndexOf("\\") + 1); 121 | 122 | return ""; 123 | } 124 | } 125 | 126 | public string LinuxWine() 127 | { 128 | PlatformID pid = (Environment.OSVersion).Platform; 129 | switch (pid) 130 | { 131 | case PlatformID.Unix: 132 | return "wine"; 133 | } 134 | return ""; 135 | } 136 | 137 | private void btnLaunch_Clicked(object sender, EventArgs e) 138 | { 139 | EnableControls(false); 140 | 141 | ProcessStartInfo processStartInfo = new ProcessStartInfo(GetGame()) 142 | { 143 | UseShellExecute = false, 144 | RedirectStandardOutput = true 145 | }; 146 | 147 | Process.Start(processStartInfo); 148 | EnableControls(true); 149 | } 150 | 151 | private void button_Corrupt_Clicked(object sender, EventArgs e) 152 | { 153 | EnableControls(false); 154 | 155 | try { _logWriter = new StreamWriter("HATE.log", true); } 156 | catch (Exception) { MessageBox.Show("Could not set up the log file."); } 157 | 158 | if (!Setup()) { goto End; }; 159 | //DebugListChunks(_dataWin, _logWriter); 160 | //Shuffle.LoadDataAndFind("STRG", _random, 0, _logWriter, _dataWin, Shuffle.ComplexShuffle(Shuffle.StringDumpAccumulator, Shuffle.SimpleShuffler, Shuffle.SimpleWriter)); 161 | if (_hitboxFix && !HitboxFix_Func(_random, _truePower, _logWriter)) { goto End; } 162 | if (_shuffleGFX && !ShuffleGFX_Func(_random, _truePower, _logWriter)) { goto End; } 163 | if (_shuffleText && !ShuffleText_Func(_random, _truePower, _logWriter)) { goto End; } 164 | if (_shuffleFont && !ShuffleFont_Func(_random, _truePower, _logWriter)) { goto End; } 165 | if (_shuffleBG && !ShuffleBG_Func(_random, _truePower, _logWriter)) { goto End; } 166 | if (_shuffleAudio && !ShuffleAudio_Func(_random, _truePower, _logWriter)) { goto End; } 167 | 168 | End: 169 | _logWriter.Close(); 170 | EnableControls(true); 171 | } 172 | 173 | public void EnableControls(bool state) 174 | { 175 | btnCorrupt.Enabled = state; 176 | btnLaunch.Enabled = state; 177 | chbShuffleText.Enabled = state; 178 | chbShuffleGFX.Enabled = state; 179 | chbHitboxFix.Enabled = state; 180 | chbShuffleFont.Enabled = state; 181 | chbShuffleBG.Enabled = state; 182 | chbShuffleAudio.Enabled = state; 183 | chbShowSeed.Enabled = state; 184 | label1.Enabled = state; 185 | label2.Enabled = state; 186 | txtPower.Enabled = state; 187 | txtSeed.Enabled = state; 188 | } 189 | 190 | public bool Setup() 191 | { 192 | _logWriter.WriteLine("-------------- Session at: " + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + "\n"); 193 | 194 | /** SEED PARSING AND RNG SETUP **/ 195 | _friskMode = false; 196 | byte power = 0; 197 | _random = new Random(); 198 | int timeSeed = (int)DateTime.Now.Subtract(_unixTimeZero).TotalSeconds; 199 | 200 | if (!byte.TryParse(txtPower.Text, out power) && _corrupt) 201 | { 202 | MessageBox.Show("Please set Power to a number between 0 and 255 and try again."); 203 | return false; 204 | } 205 | _truePower = (float)power / 255; 206 | 207 | if (txtSeed.Text.ToUpper() == "FRISK" && !File.Exists("DELTARUNE.exe")) 208 | _friskMode = true; 209 | 210 | if (_showSeed) 211 | txtSeed.Text = $"#{timeSeed}"; 212 | else 213 | txtSeed.Text = ""; 214 | 215 | _logWriter.WriteLine($"Time seed - {timeSeed}"); 216 | _logWriter.WriteLine($"Power - {power}"); 217 | _logWriter.WriteLine($"TruePower - {_truePower}"); 218 | 219 | /** ENVIRONMENTAL CHECKS **/ 220 | if (File.Exists("UNDERTALE.exe") && !File.Exists("./mus_barrier.ogg")) 221 | { 222 | MessageBox.Show("ERROR:\nIt seems you've either placed HATE.exe in the wrong location or are using an old version of Undertale. Solutions to both problems are given in the README.txt file included in the download."); 223 | return false; 224 | } 225 | 226 | if (!File.Exists(_dataWin)) 227 | { 228 | MessageBox.Show($"You seem to be missing your resource file, {_dataWin}. Make sure you've placed HATE.exe in the proper location."); 229 | return false; 230 | } 231 | else if (!Directory.Exists("Data")) 232 | { 233 | if (!Safe.CreateDirectory("Data")) { return false; } 234 | if (!Safe.CopyFile(_dataWin, $"Data/{_dataWin}")) { return false; } 235 | if (Directory.Exists("./lang")) 236 | { 237 | if (!Safe.CopyFile("./lang/lang_en.json", "./Data/lang_en.json")) { return false; }; 238 | if (!Safe.CopyFile("./lang/lang_ja.json", "./Data/lang_ja.json")) { return false; }; 239 | } 240 | _logWriter.WriteLine($"Finished setting up the Data folder."); 241 | } 242 | 243 | if (!Safe.DeleteFile(_dataWin)) { return false; } 244 | _logWriter.WriteLine($"Deleted {_dataWin}."); 245 | if (Directory.Exists("./lang")) 246 | { 247 | if (!Safe.DeleteFile("./lang/lang_en.json")) { return false; } 248 | _logWriter.WriteLine($"Deleted ./lang/lang_en.json."); 249 | if (!Safe.DeleteFile("./lang/lang_ja.json")) { return false; } 250 | _logWriter.WriteLine($"Deleted ./lang/lang_ja.json."); 251 | } 252 | 253 | if (!Safe.CopyFile($"Data/{_dataWin}", _dataWin)) { return false; } 254 | _logWriter.WriteLine($"Copied {_dataWin}."); 255 | if (Directory.Exists("./lang")) 256 | { 257 | if (!Safe.CopyFile("./Data/lang_en.json", "./lang/lang_en.json")) { return false; } 258 | _logWriter.WriteLine($"Copied ./lang/lang_en.json."); 259 | if (!Safe.CopyFile("./Data/lang_ja.json", "./lang/lang_ja.json")) { return false; } 260 | _logWriter.WriteLine($"Copied ./lang/lang_ja.json."); 261 | } 262 | 263 | return true; 264 | } 265 | 266 | public void UpdateCorrupt() 267 | { 268 | _corrupt = _shuffleGFX || _shuffleText || _hitboxFix || _shuffleFont || _shuffleAudio || _shuffleBG; 269 | btnCorrupt.Text = Style.GetCorruptLabel(_corrupt); 270 | btnCorrupt.ForeColor = Style.GetCorruptColor(_corrupt); 271 | } 272 | 273 | private void chbShuffleText_CheckedChanged(object sender, EventArgs e) 274 | { 275 | _shuffleText = chbShuffleText.Checked; 276 | chbShuffleText.ForeColor = Style.GetOptionColor(_shuffleText); 277 | UpdateCorrupt(); 278 | } 279 | 280 | private void chbShuffleGFX_CheckedChanged(object sender, EventArgs e) 281 | { 282 | _shuffleGFX = chbShuffleGFX.Checked; 283 | chbShuffleGFX.ForeColor = Style.GetOptionColor(_shuffleGFX); 284 | UpdateCorrupt(); 285 | } 286 | 287 | private void chbHitboxFix_CheckedChanged(object sender, EventArgs e) 288 | { 289 | _hitboxFix = chbHitboxFix.Checked; 290 | chbHitboxFix.ForeColor = Style.GetOptionColor(_hitboxFix); 291 | UpdateCorrupt(); 292 | } 293 | 294 | private void chbShuffleFont_CheckedChanged(object sender, EventArgs e) 295 | { 296 | _shuffleFont = chbShuffleFont.Checked; 297 | chbShuffleFont.ForeColor = Style.GetOptionColor(_shuffleFont); 298 | UpdateCorrupt(); 299 | } 300 | 301 | private void chbShuffleBG_CheckedChanged(object sender, EventArgs e) 302 | { 303 | _shuffleBG = chbShuffleBG.Checked; 304 | chbShuffleBG.ForeColor = Style.GetOptionColor(_shuffleBG); 305 | UpdateCorrupt(); 306 | } 307 | 308 | private void chbShuffleAudio_CheckedChanged(object sender, EventArgs e) 309 | { 310 | _shuffleAudio = chbShuffleAudio.Checked; 311 | chbShuffleAudio.ForeColor = Style.GetOptionColor(_shuffleAudio); 312 | UpdateCorrupt(); 313 | } 314 | 315 | private void chbShowSeed_CheckedChanged(object sender, EventArgs e) 316 | { 317 | _showSeed = chbShowSeed.Checked; 318 | chbShowSeed.ForeColor = Style.GetOptionColor(_showSeed); 319 | } 320 | 321 | private void txtPower_Enter(object sender, EventArgs e) 322 | { 323 | txtPower.Text = (txtPower.Text == _defaultPowerText) ? "" : txtPower.Text; 324 | } 325 | 326 | private void txtPower_Leave(object sender, EventArgs e) 327 | { 328 | txtPower.Text = string.IsNullOrWhiteSpace(txtPower.Text) ? _defaultPowerText : txtPower.Text; 329 | } 330 | 331 | private void MainForm_Load(object sender, EventArgs e) 332 | { 333 | 334 | } 335 | } 336 | } 337 | -------------------------------------------------------------------------------- /HATE/MainForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | AAABAAIAEBAAAAAAIABoBAAAJgAAACAgAAAAACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAEAE 124 | AAAAAAAAAAAAAAAAAAAAAAAA////Af///wH///8B////Af///wH///8B////Af///wEAAP8jAAD/F/// 125 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA/yEAAP9pAAD//wAA 126 | /3f///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAD/BwAA/wsAAP95AAD//wAA 127 | /+kAAP/LAAD/swAA/zX///8B////Af///wH///8B////Af///wH///8B////AQAA/1EAAP//AAD/9wAA 128 | //sAAP+ZAAD//wAA//8AAP+FAAD/QwAA/wP///8B////Af///wH///8BAAD/LQAA/8MAAP/TAAD//wAA 129 | //8AAP/HAAD/WwAA//8AAP//AAD//wAA//8AAP9D////Af///wEAAP8PAAD/eQAA/6EAAP//AAD//wAA 130 | //8AAP//AAD/kwAA/x0AAP//AAD//wAA//8AAP//AAD/0QAA/9EAAP8PAAD/RwAA//8AAP//AAD//wAA 131 | //8AAP//AAD//wAA/1n///8BAAD/3wAA//8AAP//AAD//wAA//8AAP//AAD/RwAA/4EAAP//AAD//wAA 132 | //8AAP//AAD//wAA//8AAP8d////AQAA/5sAAP//AAD//wAA//8AAP//AAD//wAA/4sAAP+5AAD//wAA 133 | //8AAP//AAD//wAA//8AAP/n////Af///wEAAP9jAAD//wAA//8AAP//AAD//wAA//8AAP/HAAD/7wAA 134 | //8AAP//AAD//wAA//8AAP//AAD/r////wH///8BAAD/JQAA//8AAP//AAD//wAA//8AAP//AAD/+wAA 135 | //8AAP//AAD//wAA//8AAP//AAD//wAA/3H///8B////Af///wEAAP/lAAD//wAA//8AAP//AAD//wAA 136 | //8AAP//AAD//wAA//8AAP//AAD//wAA/8sAAP8z////Af///wH///8BAAD/mwAA//cAAP//AAD//wAA 137 | //8AAP//AAD/2QAA//8AAP//AAD//wAA//8AAP8v////Af///wH///8B////Af///wEAAP+hAAD//wAA 138 | //8AAP//AAD//wAA/zcAAP//AAD//wAA/9MAAP8x////Af///wH///8B////Af///wH///8BAAD/RQAA 139 | /8sAAP//AAD//wAA/8X///8BAAD/JwAA/18AAP8P////Af///wH///8B////Af///wH///8B////Af// 140 | /wEAAP8lAAD/qwAA/88AAP9f////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 141 | /wH///8B////Af///wH///8B////AQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 142 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAA 143 | AAAAAAAA////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 144 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 145 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 146 | /wH///8B////Af///wH///8BAAD/OQAA/1UAAP9Z////Af///wH///8B////Af///wH///8B////Af// 147 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 148 | /wH///8B////Af///wH///8B////AQAA/1EAAP//AAD//wAA/9cAAP8J////Af///wH///8B////Af// 149 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 150 | /wH///8B////Af///wH///8B////AQAA/4EAAP/HAAD/jwAA//8AAP//AAD//////wH///8B////Af// 151 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 152 | /wH///8B////Af///wH///8B////Af///wH///8BAAD/xQAA//8AAP//AAD/7QAA//8AAP//AAD/MwAA 153 | /0cAAP+JAAD/Of///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 154 | /wH///8B////Af///wH///8B////AQAA/xkAAP8p////AQAA/x8AAP//AAD//wAA//8AAP+7AAD//wAA 155 | //8AAP/9AAD//QAA//8AAP+Z////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 156 | /wH///8B////Af///wH///8B////Af///wH///8BAAD/fwAA//8AAP//AAD/3QAA//8AAP//AAD//wAA 157 | /2kAAP//AAD//wAA//8AAP//AAD//wAA/+v///8B////Af///wH///8B////Af///wH///8B////Af// 158 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAP/DAAD//wAA//8AAP//AAD//wAA 159 | //8AAP/z////AQAA//8AAP//AAD//wAA//8AAP//AAD//wAA/ycAAP9nAAD/pwAA/wv///8B////Af// 160 | /wH///8B////Af///wH///8B////Af///wH///8BAAD/NQAA/6kAAP9nAAD/TQAA//8AAP//AAD//wAA 161 | //8AAP//AAD//wAA/6v///8BAAD/1wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/Xf// 162 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAP99AAD//wAA//8AAP//AAD//wAA 163 | //8AAP//AAD//wAA//8AAP//AAD/cf///wEAAP+XAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 164 | //8AAP+v////Af///wH///8B////Af///wH///8B////Af///wH///8BAAD/DwAA/8UAAP//AAD//wAA 165 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP9N////AQAA/1UAAP//AAD//wAA//8AAP//AAD//wAA 166 | //8AAP//AAD//wAA//8AAP9FAAD/hwAA/8P///8B////Af///wEAAP89AAD//wAA/+cAAP+1AAD//wAA 167 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//////wH///8BAAD/HQAA//8AAP//AAD//wAA 168 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/zn///8B////AQAA/3EAAP//AAD//wAA 169 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP/H////Af///wH///8BAAD/3wAA 170 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/cf///wH///8BAAD/qwAA 171 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA/5////8B////Af// 172 | /wEAAP+fAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP+r////Af// 173 | /wEAAP/rAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/Vf// 174 | /wH///8B////AQAA/1UAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 175 | //f///8BAAD/HQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 176 | //8AAP8d////Af///wH///8BAAD/HQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 177 | //8AAP//AAD//wAA/zkAAP9VAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 178 | //8AAP//AAD/8////wH///8B////Af///wH///8BAAD/5wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 179 | //8AAP//AAD//wAA//8AAP//AAD/cQAA/5MAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 180 | //8AAP//AAD//wAA//8AAP+r////Af///wH///8B////Af///wEAAP+nAAD//wAA//8AAP//AAD//wAA 181 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP+rAAD/xwAA//8AAP//AAD//wAA//8AAP//AAD//wAA 182 | //8AAP//AAD//wAA//8AAP//AAD//wAA/3H///8B////Af///wH///8B////AQAA/2kAAP//AAD//wAA 183 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//MAAP/7AAD//wAA//8AAP//AAD//wAA 184 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/Tf///wH///8B////Af///wH///8BAAD/KQAA 185 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 186 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//////8B////Af///wH///8B////Af// 187 | /wH///8BAAD/6wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 188 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/x////wH///8B////Af// 189 | /wH///8B////Af///wEAAP+rAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 190 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP+f////Af// 191 | /wH///8B////Af///wH///8B////AQAA/3EAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 192 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP/RAAD/XQAA 193 | /y3///8B////Af///wH///8B////Af///wH///8BAAD/MQAA/8sAAP/jAAD//wAA//8AAP//AAD//wAA 194 | //8AAP//AAD//wAA//8AAP//AAD/oQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 195 | /3////8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAD/AwAA/3UAAP//AAD//wAA 196 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP/DAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA 197 | //8AAP//AAD/Of///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAD/EwAA 198 | //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//////wEAAP9nAAD//wAA//8AAP//AAD//wAA 199 | //8AAP//AAD/ZQAA/0n///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 200 | /wH///8BAAD//wAA//MAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//////AQAA/3UAAP/9AAD//wAA 201 | //8AAP//AAD/rwAA/50AAP8V////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 202 | /wH///8B////Af///wEAAP8XAAD/OQAA//8AAP//AAD//wAA//8AAP//AAD//wAA/xn///8B////AQAA 203 | /y8AAP9tAAD/owAA/9sAAP89////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 204 | /wH///8B////Af///wH///8B////Af///wH///8BAAD/lQAA/6MAAP//AAD//wAA//8AAP//AAD/Nf// 205 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 206 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAD/EQAA//cAAP+/AAD/gQAA 207 | /0X///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 208 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 209 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 210 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af// 211 | /wH///8B////Af///wH///8B////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 212 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 213 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 214 | 215 | 216 | -------------------------------------------------------------------------------- /HATE/PHATE.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2F443ECA-6BD2-4447-BF1E-E6FDFAC308C1} 8 | WinExe 9 | Properties 10 | HATE 11 | HATE 12 | v4.6 13 | 512 14 | true 15 | false 16 | publish\ 17 | true 18 | Disk 19 | false 20 | Foreground 21 | 7 22 | Days 23 | false 24 | false 25 | true 26 | 7 27 | 2.1.3.7 28 | false 29 | true 30 | 31 | 32 | AnyCPU 33 | true 34 | full 35 | false 36 | bin\Debug\ 37 | DEBUG;TRACE 38 | prompt 39 | 4 40 | 41 | 42 | AnyCPU 43 | pdbonly 44 | true 45 | bin\Release\ 46 | TRACE 47 | prompt 48 | 4 49 | true 50 | 51 | 52 | hateicon.ico 53 | 54 | 55 | true 56 | bin\x86\Debug\ 57 | DEBUG;TRACE 58 | full 59 | x86 60 | prompt 61 | MinimumRecommendedRules.ruleset 62 | true 63 | 64 | 65 | bin\x86\Release\ 66 | CODE_ANALYSIS;TRACE 67 | true 68 | pdbonly 69 | x86 70 | true 71 | prompt 72 | MinimumRecommendedRules.ruleset 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Form 91 | 92 | 93 | HATE.cs 94 | 95 | 96 | 97 | 98 | 99 | 100 | HATE.cs 101 | 102 | 103 | ResXFileCodeGenerator 104 | Resources.Designer.cs 105 | Designer 106 | 107 | 108 | True 109 | Resources.resx 110 | True 111 | 112 | 113 | SettingsSingleFileGenerator 114 | Settings.Designer.cs 115 | 116 | 117 | True 118 | Settings.settings 119 | True 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | False 132 | Microsoft .NET Framework 4.6 %28x86 and x64%29 133 | true 134 | 135 | 136 | False 137 | .NET Framework 3.5 SP1 138 | false 139 | 140 | 141 | 142 | 149 | -------------------------------------------------------------------------------- /HATE/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace HATE 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new MainForm()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /HATE/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("HATE")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("HATE")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2f443eca-6bd2-4447-bf1e-e6fdfac308c1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /HATE/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace HATE.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HATE.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /HATE/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /HATE/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace HATE.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /HATE/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HATE/SafeMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | using System.IO; 6 | using System.Security; 7 | using Optional; 8 | 9 | namespace HATE 10 | { 11 | static class Safe 12 | { 13 | private static bool IsValidPath(string path) 14 | { 15 | try { Path.GetFullPath(path); } catch (Exception) { return false; } return true; 16 | } 17 | 18 | public static Option> GetDirectories(string dirname, string searchstring) 19 | { 20 | if (!IsValidPath(dirname) || string.IsNullOrWhiteSpace(searchstring) || !Directory.Exists(dirname) ) { return Option.None>(); } 21 | List output = new List(); 22 | try 23 | { 24 | output = Directory.GetDirectories(dirname, searchstring, SearchOption.AllDirectories).ToList(); 25 | } 26 | catch (Exception ex) 27 | { 28 | if (ex is UnauthorizedAccessException) 29 | MessageBox.Show($"UnauthorizedAccessException has occured while attempting to get the list of directories in {dirname}. The directory requires permissions which this application does not have to access. Please remove permission requirement from the directory and try again."); 30 | else if (ex is IOException) 31 | MessageBox.Show($"IOException has occured while attempting to get the list of directories in {dirname}. Please ensure that the directory is not in use and try again."); 32 | else 33 | MessageBox.Show($"{ex.ToString()} has occured while attempting to get the list of directories in {dirname}."); 34 | return Option.None>(); 35 | } 36 | return Option.Some(output); 37 | } 38 | 39 | public static bool CreateDirectory(string dirname) 40 | { 41 | if (!IsValidPath(dirname)) { return false; } 42 | 43 | try 44 | { 45 | Directory.CreateDirectory(dirname); 46 | } 47 | catch (Exception ex) 48 | { 49 | if (ex is UnauthorizedAccessException) 50 | MessageBox.Show($"UnauthorizedAccessException has occured while attempting to create {dirname}. Creation of the specified directory requires permissions which this application does not have. Please remove permission requirement from the parent directory and try again."); 51 | else 52 | MessageBox.Show($"{ex} has occured while attempting to create {dirname}."); 53 | return false; 54 | } 55 | return true; 56 | } 57 | 58 | public static bool CopyFile(string from, string to) 59 | { 60 | if (!IsValidPath(from) || !IsValidPath(to) || !File.Exists(from)) { return false; } 61 | 62 | try 63 | { 64 | File.Copy(from, to, true); 65 | } 66 | catch (Exception ex) 67 | { 68 | if (ex is UnauthorizedAccessException) 69 | MessageBox.Show($"UnauthorizedAccessException has occured while attempting to copy {from} to {to}. Please ensure that the source file doesn't require permissions to access and that destination file is not read-only."); 70 | else if (ex is IOException) 71 | MessageBox.Show($"IOException has occured while attempting to copy {from} to {to}. Please ensure that the files are not in use and try again."); 72 | else 73 | MessageBox.Show($"Exception {ex} has occured while attempting to copy {from} to {to}."); 74 | return false; 75 | } 76 | return true; 77 | } 78 | 79 | public static List GetFiles(string dirname, bool alldirs = true, string format = "*.*") 80 | { 81 | if (!IsValidPath(dirname) || !Directory.Exists(dirname)) { return new List (); } 82 | 83 | List output = new List(); 84 | try 85 | { 86 | output = Directory.GetFiles(dirname, format, alldirs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToList(); 87 | } 88 | catch (Exception ex) 89 | { 90 | if (ex is UnauthorizedAccessException) 91 | MessageBox.Show($"UnauthorizedAccessException has occured while attempting to get the list of files in {dirname}. The directory requires permissions which this application does not have to access. Please remove permission requirement from the directory and try again."); 92 | else if (ex is IOException) 93 | MessageBox.Show($"IOException has occured while attempting to get the list of files in {dirname}. Please ensure that the directory is not in use and try again."); 94 | else 95 | MessageBox.Show($"{ex} has occured while attempting to get the list of files in {dirname}."); 96 | return new List(); 97 | } 98 | return output; 99 | } 100 | 101 | public static bool DeleteDirectory(string dirname) 102 | { 103 | if (!IsValidPath(dirname) || !Directory.Exists(dirname)) { return false; } 104 | 105 | try 106 | { 107 | Directory.Delete(dirname, true); 108 | } 109 | catch (Exception ex) 110 | { 111 | if (ex is UnauthorizedAccessException) 112 | MessageBox.Show($"UnauthorizedAccessException has occured while attempting to delete {dirname}. The directory requires permissions which this application does not have to access. Please remove permission requirement from the directory and try again."); 113 | else if (ex is IOException) 114 | MessageBox.Show($"IOException has occured while attempting to delete {dirname}. Please ensure that the directory is not in use and doesn't contain a read-only file and try again."); 115 | else 116 | MessageBox.Show($"{ex} has occured while attempting to delete {dirname}."); 117 | return false; 118 | } 119 | return true; 120 | } 121 | 122 | public static bool DeleteFile(string filename) 123 | { 124 | if (!IsValidPath(filename) || !File.Exists(filename)) { return false; } 125 | 126 | try 127 | { 128 | File.Delete(filename); 129 | } 130 | catch (Exception ex) 131 | { 132 | if (ex is UnauthorizedAccessException) 133 | MessageBox.Show($"UnauthorizedAccessException has occured while attempting to delete {filename}. Please ensure that the file is neither read-only, requiring permissions to access, actually a directory all along, or a executable currently in use."); 134 | else if (ex is IOException) 135 | MessageBox.Show($"IOException has occured while attempting to delete {filename}. Please ensure that the file is not in use and try again."); 136 | else 137 | MessageBox.Show($"{ex} has occured while attempting to delete {filename}."); 138 | return false; 139 | } 140 | return true; 141 | } 142 | 143 | public static bool MoveFile(string from, string to) 144 | { 145 | if (!IsValidPath(from) || !IsValidPath(to) || !File.Exists(from)) { return false; } 146 | 147 | try 148 | { 149 | File.Move(from, to); 150 | } 151 | catch (Exception ex) 152 | { 153 | if (ex is UnauthorizedAccessException) 154 | MessageBox.Show($"UnauthorizedAccessException has occured while attempting to move {from} to {to}. Please ensure that the source file doesn't require permissions to access."); 155 | else if (ex is IOException) 156 | MessageBox.Show($"IOException has occured while attempting to move {from} to {to}. Please ensure that the destination file doesn't exist and that the source file does."); 157 | else 158 | MessageBox.Show($"{ex} has occured while attempting to move {from} to {to}."); 159 | return false; 160 | } 161 | return true; 162 | } 163 | 164 | public static Option OpenStreamWriter(string filename) 165 | { 166 | if (!IsValidPath(filename) || !File.Exists(filename)) { return Option.None(); } 167 | 168 | StreamWriter TXW; 169 | try 170 | { 171 | TXW = new StreamWriter(filename); 172 | } 173 | catch (Exception ex) 174 | { 175 | if (ex is SecurityException) 176 | MessageBox.Show($"SecurityException has occured while opening {filename} with a StreamWriter. File requires permissions to access which this program does not have."); 177 | else if (ex is IOException) 178 | MessageBox.Show($"IOException has occured while opening {filename} with a StreamWriter. Please ensure that the path is correct and the file is not in use and try again."); 179 | else if (ex is UnauthorizedAccessException) 180 | MessageBox.Show($"UnauthorizedAccessException has occured while opening {filename} with a StreamWriter. The file requires permissions which this program doesn't have to open. Please ensure that file at the specified address requires no permissions to open and try again."); 181 | else 182 | MessageBox.Show($"{ex} has occured when while opening {filename} with a StreamWriter."); 183 | return Option.None(); 184 | } 185 | return Option.Some(TXW); 186 | } 187 | 188 | public static Option OpenFileStream(string filename) 189 | { 190 | if (!IsValidPath(filename) || !File.Exists(filename)) { return Option.None(); } 191 | 192 | FileStream TXW; 193 | try 194 | { 195 | TXW = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite); 196 | } 197 | catch (Exception ex) 198 | { 199 | if (ex is SecurityException) 200 | MessageBox.Show($"SecurityException has occured while opening {filename} with a FileStream. File requires permissions to access which this program does not have."); 201 | else if (ex is IOException) 202 | MessageBox.Show($"IOException has occured while opening {filename} with a FileStream. Please ensure that the path is correct and the file isn't in use and try again."); 203 | else if (ex is UnauthorizedAccessException) 204 | MessageBox.Show($"UnauthorizedAccessException has occured while opening {filename} with a FileStream. The file requires permissions which this program doesn't have to open. Please ensure that file at the specified address requires no permissions to open and try again."); 205 | else 206 | MessageBox.Show($"{ex} has occured when while opening {filename} with a FileStream."); 207 | return Option.None(); 208 | } 209 | return Option.Some(TXW); 210 | } 211 | } 212 | } -------------------------------------------------------------------------------- /HATE/Shuffle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | using System.Text.RegularExpressions; 6 | using System.Windows.Forms; 7 | 8 | namespace HATE 9 | { 10 | static class Shuffle 11 | { 12 | public const int WordSize = 4; 13 | public const int NumDataSegments = 25; 14 | 15 | 16 | public static bool LoadDataAndFind(string seeked_header, Random random, float shufflechance, StreamWriter logstream, string resource_file, Func shufflefunc) 17 | { 18 | if (random == null) 19 | throw new ArgumentNullException(nameof(random)); 20 | 21 | byte[] readBuffer = new byte[WordSize]; 22 | 23 | using (FileStream stream = new FileStream(resource_file, FileMode.OpenOrCreate)) 24 | { 25 | logstream.WriteLine($"Opened {resource_file}."); 26 | stream.Position = 8; 27 | 28 | int dataSegmentCounter = 0; 29 | 30 | while (dataSegmentCounter++ < NumDataSegments) 31 | { 32 | stream.Read(readBuffer, 0, WordSize); 33 | 34 | string headerName = new string(readBuffer.Select(x => (char)x).ToArray()); 35 | 36 | if (headerName == seeked_header) 37 | { 38 | logstream.WriteLine($"{seeked_header} Memory Region Found at {stream.Position.ToString("X")}."); 39 | 40 | stream.Position += WordSize; 41 | 42 | try 43 | { 44 | if (!shufflefunc(stream, random, shufflechance, seeked_header, logstream)) 45 | { 46 | logstream.WriteLine($"An Error Occured While Attempting To Modify {seeked_header} Memory Region."); 47 | return false; 48 | } 49 | } 50 | catch (Exception e) 51 | { 52 | logstream.Write($"Exception Caught While Attempting To Modify {seeked_header} Memory Region. -> {e}"); 53 | throw; 54 | } 55 | 56 | logstream.WriteLine($"{seeked_header} Memory Region Modified Successfully."); 57 | logstream.WriteLine($"Closed {resource_file}."); 58 | return true; 59 | } 60 | 61 | stream.Read(readBuffer, 0, WordSize); 62 | stream.Position += BitConverter.ToInt32(readBuffer, 0); 63 | } 64 | 65 | logstream.WriteLine($"Could not find {seeked_header} Memory Region."); 66 | logstream.WriteLine($"Closed {resource_file}."); 67 | } 68 | return false; 69 | } 70 | 71 | 72 | 73 | enum ComplexShuffleStep : byte { Accumulation, FirstLog, Shuffling, SecondLog, Writing, ThirdLog } 74 | 75 | public static Func ComplexShuffle( 76 | Func> accumulator, 77 | Func, List> shuffler, 78 | Func, bool> writer) 79 | { 80 | return (FileStream stream, Random random, float chance, string header, StreamWriter logstream) => 81 | { 82 | bool success = false; 83 | ComplexShuffleStep step = ComplexShuffleStep.Accumulation; 84 | try 85 | { 86 | List pointerList = accumulator(stream, random, chance, logstream); 87 | step = ComplexShuffleStep.FirstLog; 88 | logstream.WriteLine($"Added {pointerList.Count} pointers to {header} List."); 89 | step = ComplexShuffleStep.Shuffling; 90 | pointerList = shuffler(stream, random, chance, logstream, pointerList); 91 | step = ComplexShuffleStep.SecondLog; 92 | logstream.WriteLine($"Shuffled {pointerList.Count} pointers to {header} List."); 93 | step = ComplexShuffleStep.Writing; 94 | success = writer(stream, random, chance, logstream, pointerList); 95 | step = ComplexShuffleStep.ThirdLog; 96 | logstream.WriteLine($"Written {pointerList.Count} shuffled pointers to {header} List."); 97 | } 98 | catch (Exception ex) 99 | { 100 | logstream.WriteLine($"Caught exception [{ex}] while editing {header} memory block, during step {step}."); 101 | throw; 102 | } 103 | 104 | return success; 105 | }; 106 | } 107 | 108 | public static List SimpleAccumulator(FileStream stream, Random random, float shufflechance, StreamWriter logstream) 109 | { 110 | byte[] readBuffer = new byte[WordSize]; 111 | int pointerNum = 0; 112 | List pointerList = new List(); 113 | 114 | stream.Read(readBuffer, 0, WordSize); 115 | pointerNum = BitConverter.ToInt32(readBuffer, 0); 116 | 117 | for (int i = 0; i < pointerNum; i++) 118 | { 119 | stream.Read(readBuffer, 0, WordSize); 120 | 121 | if (random.NextDouble() < shufflechance) 122 | pointerList.Add(new ResourcePointer(BitConverter.ToInt32(readBuffer, 0), (int)(stream.Position - WordSize))); 123 | } 124 | 125 | return pointerList; 126 | } 127 | 128 | public static List SimpleShuffler(FileStream stream, Random random, float shufflechance, StreamWriter logstream, List pointerlist) 129 | { 130 | pointerlist.Shuffle(PointerSwapLoc, random); 131 | return pointerlist; 132 | } 133 | 134 | public static bool SimpleWriter(FileStream stream, Random random, float shufflechance, StreamWriter logstream, List pointerlist) 135 | { 136 | foreach (ResourcePointer ptr in pointerlist) 137 | { 138 | stream.Position = ptr.Location; 139 | stream.Write(BitConverter.GetBytes(ptr.Address), 0, WordSize); 140 | } 141 | return true; 142 | } 143 | 144 | public static Func SimpleShuffle = ComplexShuffle(SimpleAccumulator, SimpleShuffler, SimpleWriter); 145 | 146 | public static List StringDumpAccumulator(FileStream stream, Random random, float shufflechance, StreamWriter logstream) 147 | { 148 | byte[] readBuffer = new byte[WordSize]; 149 | int pointerNum = 0; 150 | List pointerList = new List(); 151 | 152 | stream.Read(readBuffer, 0, WordSize); 153 | pointerNum = BitConverter.ToInt32(readBuffer, 0); 154 | 155 | for (int i = 0; i < pointerNum; i++) 156 | { 157 | stream.Read(readBuffer, 0, WordSize); 158 | long cur_pos = stream.Position; 159 | int str_ptr = BitConverter.ToInt32(readBuffer, 0); 160 | 161 | stream.Position = str_ptr; 162 | stream.Read(readBuffer, 0, WordSize); 163 | int str_size = BitConverter.ToInt32(readBuffer, 0); 164 | 165 | byte[] byteBuf = new byte[str_size]; 166 | 167 | stream.Read(byteBuf, 0, str_size); 168 | string output = new string(byteBuf.Select(x => (char)x).ToArray()); 169 | 170 | logstream.WriteLine($"Str at: {cur_pos}, ptr_to: {str_ptr}, str: {output}"); 171 | stream.Position = cur_pos; 172 | } 173 | 174 | return pointerList; 175 | } 176 | 177 | public static void PointerSwapLoc(ResourcePointer lref, ResourcePointer rref) 178 | { 179 | int tmp = lref.Location; 180 | lref.Location = rref.Location; 181 | rref.Location = tmp; 182 | } 183 | 184 | public static readonly Regex json_line_regex = new Regex("\\s*\"(.+)\":\\s*\"(.+)\",", RegexOptions.ECMAScript); 185 | 186 | public class JSONStringEntry 187 | { 188 | public string Key; 189 | public string Ending; 190 | public string Str; 191 | 192 | public JSONStringEntry(string key, string str) 193 | { 194 | Key = key; 195 | Str = str; 196 | char[] FormatChars = { '%', '/', 'C' }; 197 | List Ending = new List(); 198 | 199 | for (int i = 1; i < str.Length; i++) 200 | { 201 | char C = str[str.Length - i]; 202 | 203 | if (FormatChars.Contains(C)) 204 | Ending.Add(C); 205 | else 206 | break; 207 | } 208 | 209 | Ending.Reverse(); 210 | this.Ending = new string(Ending.ToArray()); 211 | } 212 | } 213 | 214 | public static void JSONSwapLoc(JSONStringEntry lref, JSONStringEntry rref) 215 | { 216 | string tmp = lref.Key; 217 | lref.Key = rref.Key; 218 | rref.Key = tmp; 219 | } 220 | 221 | public static bool JSONStringShuffle(string resource_file, string target_file, Random random, float shufflechance, StreamWriter logstream) 222 | { 223 | // actual JSON libraries are complicated, thankfully we can bodge it together with magic and friendship 224 | if (random == null) 225 | throw new ArgumentNullException(nameof(random)); 226 | 227 | byte[] readBuffer = new byte[WordSize]; 228 | 229 | List strings = new List(); 230 | 231 | using (FileStream stream = new FileStream(resource_file, FileMode.OpenOrCreate)) 232 | { 233 | StreamReader text_reader = new StreamReader(stream); 234 | logstream.WriteLine($"Opened {resource_file}."); 235 | long date = 0; 236 | 237 | 238 | while (stream.Position != stream.Length) 239 | { 240 | string cur_line = text_reader.ReadLine(); 241 | if (cur_line == "}" || cur_line == "{") { continue; } 242 | 243 | Match m = json_line_regex.Match(cur_line); 244 | 245 | 246 | // logstream.WriteLine($"line: {cur_line} | group_size: {m.Groups.Count}"); 247 | // logstream.Flush(); 248 | 249 | string[] match = {m.Groups[1].ToString(), m.Groups[2].ToString() }; 250 | // logstream.WriteLine($"aaaaa: {match[0]} _ {match[1]}"); 251 | 252 | strings.Add(new JSONStringEntry(match[0], match[1])); 253 | } 254 | } 255 | logstream.WriteLine($"Closed {resource_file}."); 256 | 257 | logstream.WriteLine($"Gathered {strings.Count} JSON String Entries. "); 258 | 259 | string[] bannedStrings = { "_" }; 260 | string[] bannedKeys = { "date" }; 261 | 262 | List good_strings = new List(); 263 | List final_list = new List(); 264 | 265 | foreach (JSONStringEntry entry in strings) 266 | { 267 | 268 | if (entry.Str.Length >= 3 && entry.Key.Contains('_')) 269 | { 270 | good_strings.Add(entry); 271 | } 272 | else 273 | { 274 | final_list.Add(entry); 275 | } 276 | } 277 | 278 | logstream.WriteLine($"Kept {good_strings.Count} good JSON string entries."); 279 | logstream.WriteLine($"Fastforwarded {final_list.Count} JSON string entries to the final phase."); 280 | 281 | Dictionary> stringDict = new Dictionary>(); 282 | int totalStrings = 0; 283 | 284 | foreach (JSONStringEntry s in good_strings) 285 | { 286 | //if (!string.IsNullOrWhiteSpace(s.Ending)) 287 | //{ 288 | if (!stringDict.ContainsKey(s.Ending)) 289 | stringDict[s.Ending] = new List(); 290 | 291 | stringDict[s.Ending].Add(s); 292 | totalStrings++; 293 | //} 294 | } 295 | 296 | 297 | 298 | foreach (string ending in stringDict.Keys) 299 | { 300 | logstream.WriteLine($"Added {stringDict[ending].Count} JSON string entries of ending <{ending}> to dialogue string List."); 301 | 302 | stringDict[ending].Shuffle(JSONSwapLoc, random); 303 | 304 | final_list = final_list.Concat(stringDict[ending]).ToList(); 305 | } 306 | 307 | using (FileStream out_stream = new FileStream(target_file, FileMode.Create, FileAccess.ReadWrite)) 308 | { 309 | logstream.WriteLine($"Opened {target_file}."); 310 | StreamWriter writer = new StreamWriter(out_stream); 311 | writer.Write("{\n"); 312 | 313 | foreach (JSONStringEntry s in final_list) 314 | { 315 | char comma = (s.Key == final_list[final_list.Count - 1].Key) ? ' ' : ','; 316 | writer.WriteLine($"\t\"{s.Key}\": \"{s.Str}\"{comma} "); 317 | } 318 | writer.Write("}\n"); 319 | writer.Flush(); 320 | } 321 | logstream.WriteLine($"Closed {target_file}."); 322 | 323 | 324 | return false; 325 | 326 | } 327 | } 328 | } 329 | -------------------------------------------------------------------------------- /HATE/hateicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redspah/HATE/ab0c33627c0e0e61741f7cc8e53e0d326df4b517/HATE/hateicon.ico -------------------------------------------------------------------------------- /HATE/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 RedSpah 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HATE 2 | The Undertale Corruptor. 3 | 4 | Howdy! I'm RED. RED the [REDACTED]! 5 | 6 | And this is the Undertale Corruptor! 7 | What does it do, you may ask? 8 | It allows you to shuffle game's internal data around, corrupting music, gfx and text as a result. 9 | Interested? 10 | 11 | [DOWNLOAD (BOTH WINDOWS AND MAC)](https://www.dropbox.com/s/pzsdkvu82p8urya/HATE.zip?dl=0) 12 | 13 | All instructions are inside the README file in the download. 14 | 15 | 16 | 17 | --------------------------------------------------------------------------------