sin365
2 months ago
5 changed files with 604 additions and 1 deletions
@ -0,0 +1,60 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace MHFOldQuestConditionStringFix |
||||
{ |
||||
public class FileHelper |
||||
{ |
||||
public static bool LoadFile(string FilePath, out byte[] data) |
||||
{ |
||||
using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read)) |
||||
{ |
||||
try |
||||
{ |
||||
byte[] buffur = new byte[fs.Length]; |
||||
fs.Read(buffur, 0, (int)fs.Length); |
||||
fs.Close(); |
||||
data = buffur; |
||||
return true; |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
data = null; |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static string[] GetDirFile(string Path) |
||||
{ |
||||
return Directory.GetFiles(Path); |
||||
} |
||||
|
||||
public static byte[] String2Byte(string value) |
||||
{ |
||||
return Encoding.Default.GetBytes(value); |
||||
} |
||||
public static bool SaveFile(string FilePath, byte[] buffer) |
||||
{ |
||||
try |
||||
{ |
||||
//创建一个文件流 |
||||
using (FileStream wfs = new FileStream(FilePath, FileMode.Create)) |
||||
{ |
||||
//将byte数组写入文件中 |
||||
wfs.Write(buffer, 0, buffer.Length); |
||||
//所有流类型都要关闭流,否则会出现内存泄露问题 |
||||
wfs.Close(); |
||||
return true; |
||||
} |
||||
} |
||||
catch |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,226 @@
|
||||
using System.Text; |
||||
|
||||
namespace MHFOldQuestConditionStringFix |
||||
{ |
||||
public class HexHelper |
||||
{ |
||||
|
||||
public static byte[] CopyByteArr(byte[] src) |
||||
{ |
||||
byte[] target = new byte[src.Length]; |
||||
//加载数据 |
||||
target = new byte[src.Length]; |
||||
for (int i = 0; i < src.Length; i++) |
||||
target[i] = src[i]; |
||||
return target; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 读取byte[]数据 |
||||
/// </summary> |
||||
/// <param name="src"></param> |
||||
/// <param name="lenght"></param> |
||||
/// <param name="offset"></param> |
||||
/// <returns></returns> |
||||
public static byte[] ReadBytes(byte[] src, int lenght, int offset = 0) |
||||
{ |
||||
byte[] data = new byte[lenght]; |
||||
for (int i = 0; i < lenght; i++) |
||||
{ |
||||
data[i] = src[offset + i]; |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
/** |
||||
* byte[]转换int byte高位在前 |
||||
*/ |
||||
public static int bytesToInt(byte[] src,int lenght, int offset = 0) |
||||
{ |
||||
if (lenght == 1) |
||||
return src[offset + 0]; |
||||
|
||||
byte[] data = new byte[lenght]; |
||||
for (int i = 0; i < lenght; i++) |
||||
{ |
||||
data[i] = src[offset + i]; |
||||
} |
||||
|
||||
if(lenght == 2) |
||||
return BitConverter.ToInt16(data, 0); |
||||
else //if (lenght == 4) |
||||
return BitConverter.ToInt32(data, 0); |
||||
} |
||||
|
||||
/** |
||||
* byte[]转换int byte高位在前 |
||||
*/ |
||||
public static uint bytesToUInt(byte[] src, int lenght, int offset = 0) |
||||
{ |
||||
if (lenght == 1) |
||||
return src[offset + 0]; |
||||
|
||||
byte[] data = new byte[lenght]; |
||||
for (int i = 0; i < lenght; i++) |
||||
{ |
||||
data[i] = src[offset + i]; |
||||
} |
||||
|
||||
if (lenght == 2) |
||||
return BitConverter.ToUInt16(data, 0); |
||||
else //if (lenght == 4) |
||||
return BitConverter.ToUInt32(data, 0); |
||||
} |
||||
|
||||
/** |
||||
* int 转 byte[] byte高位在前 |
||||
*/ |
||||
public static byte[] intToBytes(int value) |
||||
{ |
||||
return BitConverter.GetBytes(value); |
||||
} |
||||
|
||||
/** |
||||
* 从字节读取字符串 |
||||
*/ |
||||
public static string ReadBytesToString(byte[] src, int Start, Encoding encoding = null) |
||||
{ |
||||
List<byte> bytes = new List<byte>(); |
||||
|
||||
int index = 0; |
||||
while (true) |
||||
{ |
||||
bytes.Add(src[Start + index]); |
||||
|
||||
if (src[Start + index + 1] == 0x00) |
||||
break; |
||||
|
||||
index++; |
||||
} |
||||
if (encoding == null) |
||||
encoding = Encoding.GetEncoding("Shift-JIS"); |
||||
string str = encoding.GetString(bytes.ToArray()); |
||||
return str; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 从字节读取字符串 |
||||
*/ |
||||
public static string ReadBytesToString(byte[] src, Encoding encoding = null) |
||||
{ |
||||
if (encoding == null) |
||||
encoding = Encoding.GetEncoding("Shift-JIS"); |
||||
string str = encoding.GetString(src.ToArray()); |
||||
return str; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 写入int到byte[] byte高位在前 |
||||
*/ |
||||
public static void ModifyIntHexToBytes(byte[] srcdata, int targetvalue,int startoffset, int srclenght) |
||||
{ |
||||
byte[] targetVal = intToBytes(targetvalue); |
||||
|
||||
//抹去数据 |
||||
for (int i = 0; i < srclenght; i++) |
||||
srcdata[startoffset + i] = 0x00; |
||||
|
||||
for (int i = 0; i < targetVal.Length && i < srclenght; i++) |
||||
srcdata[startoffset + i] = targetVal[i]; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 写入byte[]到byte[] byte高位在前 |
||||
*/ |
||||
public static void ModifyDataToBytes(byte[] srcdata, byte[] targetVal, int startoffset) |
||||
{ |
||||
//抹去数据 |
||||
for (int i = 0; i < targetVal.Length; i++) |
||||
srcdata[startoffset + i] = 0x00; |
||||
|
||||
for (int i = 0; i < targetVal.Length && i < targetVal.Length; i++) |
||||
srcdata[startoffset + i] = targetVal[i]; |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* 对比数据 |
||||
*/ |
||||
public static bool CheckDataEquals(byte[] srcdata, byte[] targetVal, int startoffset) |
||||
{ |
||||
byte[] temp = new byte[targetVal.Length]; |
||||
for (int i = 0; i < targetVal.Length && i < targetVal.Length; i++) |
||||
temp[i] = srcdata[startoffset + i]; |
||||
|
||||
return Array.Equals(targetVal, temp); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 另一种16进制转10进制的处理方式,Multiplier参与*16的循环很巧妙,对Multiplier的处理很推荐,逻辑统一 |
||||
/// </summary> |
||||
/// <param name="HexaDecimalString"></param> |
||||
/// <returns></returns> |
||||
public static int HexaToDecimal(string HexaDecimalString) |
||||
{ |
||||
int Decimal = 0; |
||||
int Multiplier = 1; |
||||
|
||||
for (int i = HexaDecimalString.Length - 1; i >= 0; i--) |
||||
{ |
||||
Decimal += HexaToDecimal(HexaDecimalString[i]) * Multiplier; |
||||
Multiplier *= 16; |
||||
} |
||||
return Decimal; |
||||
} |
||||
|
||||
static int HexaToDecimal(char c) |
||||
{ |
||||
switch (c) |
||||
{ |
||||
case '0': |
||||
return 0; |
||||
case '1': |
||||
return 1; |
||||
case '2': |
||||
return 2; |
||||
case '3': |
||||
return 3; |
||||
case '4': |
||||
return 4; |
||||
case '5': |
||||
return 5; |
||||
case '6': |
||||
return 6; |
||||
case '7': |
||||
return 7; |
||||
case '8': |
||||
return 8; |
||||
case '9': |
||||
return 9; |
||||
case 'A': |
||||
case 'a': |
||||
return 10; |
||||
case 'B': |
||||
case 'b': |
||||
return 11; |
||||
case 'C': |
||||
case 'c': |
||||
return 12; |
||||
case 'D': |
||||
case 'd': |
||||
return 13; |
||||
case 'E': |
||||
case 'e': |
||||
return 14; |
||||
case 'F': |
||||
case 'f': |
||||
return 15; |
||||
} |
||||
return -1; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<OutputType>Exe</OutputType> |
||||
<TargetFramework>net6.0</TargetFramework> |
||||
<ImplicitUsings>enable</ImplicitUsings> |
||||
<Nullable>enable</Nullable> |
||||
</PropertyGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,301 @@
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
namespace MHFOldQuestConditionStringFix |
||||
{ |
||||
internal class Program |
||||
{ |
||||
static string loc = Path.GetDirectoryName(AppContext.BaseDirectory) + "\\"; |
||||
const string InDir = "Input"; |
||||
const string OutDir = "Out"; |
||||
const string Ver = "0.1"; |
||||
static byte[] SrcStringByte = { 0x83, |
||||
0x81, |
||||
0x83, |
||||
0x43, |
||||
0x83, |
||||
0x93, |
||||
0x83, |
||||
0x5e, |
||||
0x81, |
||||
0x5b, |
||||
0x83, |
||||
0x51, |
||||
0x83, |
||||
0x62, |
||||
0x83, |
||||
0x67, |
||||
0x81, |
||||
0x41, |
||||
0x82, |
||||
0xe0, |
||||
0x82, |
||||
0xb5, |
||||
0x82, |
||||
0xad, |
||||
0x82, |
||||
0xcd, |
||||
0x0a, |
||||
0x83, |
||||
0x54, |
||||
0x83, |
||||
0x75, |
||||
0x83, |
||||
0x5e, |
||||
0x81, |
||||
0x5b, |
||||
0x83, |
||||
0x51, |
||||
0x83, |
||||
0x62, |
||||
0x83, |
||||
0x67, |
||||
0x82, |
||||
0x60, |
||||
0x82, |
||||
0xA9, |
||||
0x82, |
||||
0x61, |
||||
0x82, |
||||
0xCC, |
||||
0x92, |
||||
0x42, |
||||
0x90, |
||||
0xAC, |
||||
0x00,}; |
||||
static byte[] SrcStringByte_2 = { 0x83, |
||||
0x81, |
||||
0x83, |
||||
0x43, |
||||
0x83, |
||||
0x93, |
||||
0x83, |
||||
0x5e, |
||||
0x81, |
||||
0x5b, |
||||
0x83, |
||||
0x51, |
||||
0x83, |
||||
0x62, |
||||
0x83, |
||||
0x67, |
||||
0x81, |
||||
0x41, |
||||
0x82, |
||||
0xe0, |
||||
0x82, |
||||
0xb5, |
||||
0x82, |
||||
0xad, |
||||
0x82, |
||||
0xcd, |
||||
0x0a, |
||||
0x83, |
||||
0x54, |
||||
0x83, |
||||
0x75, |
||||
0x83, |
||||
0x5e, |
||||
0x81, |
||||
0x5b, |
||||
0x83, |
||||
0x51, |
||||
0x83, |
||||
0x62, |
||||
0x83, |
||||
0x67, |
||||
0x82, |
||||
0x60, |
||||
0x81, |
||||
0x41, |
||||
0x82, |
||||
0x61, |
||||
0x82, |
||||
0xCC, |
||||
0x92, |
||||
0x42, |
||||
0x90, |
||||
0xAC, |
||||
0x00,}; |
||||
static byte[] targetStringByte = { 0x82, |
||||
0x60, |
||||
0x82, |
||||
0xA9, |
||||
0x82, |
||||
0x61, |
||||
0x82, |
||||
0xCC, |
||||
0x92, |
||||
0x42, |
||||
0x90, |
||||
0xAC, |
||||
0x00}; |
||||
static void Main(string[] args) |
||||
{ |
||||
string title = $"MHFOldQuestConditionStringFix Ver.{Ver} By 皓月云 axibug.com"; |
||||
Console.Title = title; |
||||
Console.WriteLine(title); |
||||
|
||||
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
||||
|
||||
//Encoding shiftencode = Encoding.GetEncoding("Shift-JIS"); |
||||
//SrcStringByte = shiftencode.GetBytes("メインターゲット、もしくは\\r\\nサブターゲットAかBの達成"); |
||||
//targetStringByte = shiftencode.GetBytes("AかBの達成"); |
||||
|
||||
if (!Directory.Exists(loc + InDir)) |
||||
{ |
||||
Console.WriteLine("Input文件不存在"); |
||||
Console.ReadLine(); |
||||
return; |
||||
} |
||||
|
||||
if (!Directory.Exists(loc + OutDir)) |
||||
{ |
||||
Console.WriteLine("Out文件不存在"); |
||||
Console.ReadLine(); |
||||
return; |
||||
} |
||||
|
||||
Console.WriteLine($"-----------原数据读取完毕-----------"); |
||||
|
||||
string[] files = FileHelper.GetDirFile(loc + InDir); |
||||
Console.WriteLine($"共{files.Length}个文件,是否处理? (y/n)"); |
||||
|
||||
string yn = Console.ReadLine(); |
||||
if (yn.ToLower() != "y") |
||||
return; |
||||
|
||||
int index = 0; |
||||
int errcount = 0; |
||||
for (int i = 0; i < files.Length; i++) |
||||
{ |
||||
string FileName = files[i].Substring(files[i].LastIndexOf("\\")); |
||||
|
||||
if (!FileName.ToLower().Contains(".mib") && !FileName.ToLower().Contains(".bin")) |
||||
{ |
||||
continue; |
||||
} |
||||
index++; |
||||
|
||||
Console.WriteLine($">>>>>>>>>>>>>>开始处理 第{index}个文件 {FileName}<<<<<<<<<<<<<<<<<<<"); |
||||
FileHelper.LoadFile(files[i], out byte[] data); |
||||
if (Do(data, out byte[] targetdata)) |
||||
{ |
||||
string newfileName = FileName; |
||||
string outstring = loc + OutDir + "\\" + newfileName; |
||||
FileHelper.SaveFile(outstring, targetdata); |
||||
Console.WriteLine($">>>>>>>>>>>>>>成功处理 第{index}个:{outstring}"); |
||||
} |
||||
else |
||||
{ |
||||
errcount++; |
||||
Console.WriteLine($">>>>>>>>>>>>>>处理失败 第{index}个"); |
||||
} |
||||
} |
||||
Console.WriteLine($"已处理{files.Length}个文件,其中{errcount}个失败"); |
||||
Console.WriteLine($"完毕"); |
||||
Console.ReadLine(); |
||||
} |
||||
|
||||
static bool Do(byte[] src, out byte[] target) |
||||
{ |
||||
try |
||||
{ |
||||
int Idx = 0; |
||||
|
||||
if (SearchByte(src, SrcStringByte, 0, ref Idx) > 0) |
||||
{ |
||||
target = HexHelper.CopyByteArr(src);//加载数据 |
||||
for (int i = 0; i < SrcStringByte.Length; i++) |
||||
{ |
||||
if (i + 1 <= targetStringByte.Length) |
||||
target[Idx + i] = targetStringByte[i]; |
||||
else |
||||
target[Idx + i] = 0x00; |
||||
} |
||||
} |
||||
else if (SearchByte(src, SrcStringByte_2, 0, ref Idx) > 0) |
||||
{ |
||||
target = HexHelper.CopyByteArr(src);//加载数据 |
||||
for (int i = 0; i < SrcStringByte_2.Length; i++) |
||||
{ |
||||
if (i + 1 <= targetStringByte.Length) |
||||
target[Idx + i] = targetStringByte[i]; |
||||
else |
||||
target[Idx + i] = 0x00; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
target = src; |
||||
} |
||||
return true; |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
target = null; |
||||
return false; |
||||
} |
||||
} |
||||
static int SearchByte(byte[] buffer, byte[] key, int startPos, ref int pos) |
||||
{ |
||||
int i = startPos; |
||||
int tem_pos = 0; |
||||
bool found1 = false; |
||||
int found2 = 0; |
||||
|
||||
do |
||||
{ |
||||
for (int j = 0; j < key.Length; j++) |
||||
{ |
||||
if (buffer[i] == key[j]) |
||||
{ |
||||
if (j == 0) |
||||
{ |
||||
found1 = true; |
||||
tem_pos = i; |
||||
} |
||||
else |
||||
found2 = 1; |
||||
i = i + 1; |
||||
} |
||||
else |
||||
{ |
||||
if (j == 0) |
||||
found1 = false; |
||||
else |
||||
found2 = 2; |
||||
|
||||
} |
||||
|
||||
if (found1 == false) |
||||
{ |
||||
i = i + 1; |
||||
break; |
||||
} |
||||
|
||||
if ((found2 == 2)) |
||||
{ |
||||
i = i - j + 1; |
||||
found1 = false; |
||||
found2 = 0; |
||||
break; |
||||
} |
||||
|
||||
if ((found1 == true) && (found2 == 1) && (j == (key.Length - 1))) //匹配上了 |
||||
{ |
||||
pos = i - (key.Length); |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
||||
while (i < buffer.Length); |
||||
|
||||
return 0; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue