-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSearchAndReplace.cs
107 lines (92 loc) · 3.62 KB
/
SearchAndReplace.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace SciLor_s_Mashed_Runner {
class SearchAndReplace {
public static bool SearchNReplace(String file, ByteMask[] searchPattern, ByteMask[] replacePattern) {
bool patched = false;
if (File.Exists(file + ".bak") || File.Exists(file + ".tmp")) return false;
if (searchPattern.Length != replacePattern.Length) return false;
int length = 0;
foreach (ByteMask byteMask in searchPattern) {
length = Math.Max(length, byteMask.Length());
}
File.Copy(file, file + ".bak");
File.Delete(file);
FileStream fread = File.OpenRead(file + ".bak");
if (fread.Length < length) {
fread.Close();
File.Copy(file + ".bak", file);
File.Delete(file + ".bak");
return false;
}
FileStream fwrite = File.OpenWrite(file + ".tmp");
byte[] buffer = new byte[length];
int filled = 0;
while (filled < buffer.Length) {
buffer[filled] = (byte)fread.ReadByte();
filled++;
}
while (fread.Position < fread.Length) {
patched = replacePatterns(ref buffer, searchPattern, replacePattern) || patched;
fwrite.WriteByte(buffer[0]);
buffer = moveOne(buffer);
buffer[buffer.Length - 1] = (byte)fread.ReadByte();
}
fread.Close();
patched = replacePatterns(ref buffer, searchPattern, replacePattern) || patched;
for (int i = 0; i<buffer.Length; i++) {
fwrite.WriteByte(buffer[i]);
}
fwrite.Close();
File.Copy(file + ".tmp", file);
File.Delete(file + ".tmp");
return patched;
}
private static bool isSame(byte[] buffer, ByteMask search) {
for (int i=0; i<search.Length(); i++) {
if (!search.Mask[i]) continue;
if (buffer[i] != search.Pattern[i]) return false;
}
return true;
}
private static byte[] replaceBuffer(byte[] buffer, ByteMask replace) {
byte[] replacedBuffer = new byte[buffer.Length];
for (int i=0; i<replace.Length(); i++) {
if (replace.Mask[i]) {
replacedBuffer[i] = replace.Pattern[i];
} else {
replacedBuffer[i] = buffer[i];
}
}
return replacedBuffer;
}
private static bool replacePatterns(ref byte[] buffer, ByteMask[] search, ByteMask[] replace) {
for (int i = 0; i < search.Length; i++) {
if (isSame(buffer, search[i])) {
buffer = replaceBuffer(buffer, replace[i]);
return true;
}
}
return false;
}
private static byte[] moveOne(byte[] buffer) {
byte[] tmp = new byte[buffer.Length];
for (int i = 1; i < buffer.Length; i++) {
tmp[i - 1] = buffer[i];
}
return tmp;
}
public static bool PatchLauncher(String path, ByteMask[] search, ByteMask[] replace) {
return SearchNReplace(path,
search,
replace);
}
public static void RevertLauncher(String path) {
File.Copy(path + ".bak", path);
File.Delete(path + ".bak");
}
}
}