归档
This commit is contained in:
commit
c9e804d250
67
FileHelper.cs
Normal file
67
FileHelper.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MHFQuestReader
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void SaveFile(string FilePath, string[] strArr)
|
||||||
|
{
|
||||||
|
System.IO.File.WriteAllLines(FilePath, strArr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
234
HexHelper.cs
Normal file
234
HexHelper.cs
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MHFQuestReader
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string get_uft8(string unicodeString)
|
||||||
|
{
|
||||||
|
UTF8Encoding utf8 = new UTF8Encoding();
|
||||||
|
Byte[] encodedBytes = utf8.GetBytes(unicodeString);
|
||||||
|
String decodedString = utf8.GetString(encodedBytes);
|
||||||
|
return decodedString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
187
LoadToSaveTemplate.cs
Normal file
187
LoadToSaveTemplate.cs
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
namespace MHFQuestReader
|
||||||
|
{
|
||||||
|
|
||||||
|
public class MapAreaData
|
||||||
|
{
|
||||||
|
public MapAreaData(int Count)
|
||||||
|
{
|
||||||
|
targetDatas = new TargetData[Count];
|
||||||
|
areaPosDatas = new List<byte[]>();
|
||||||
|
}
|
||||||
|
public TargetData[] targetDatas;
|
||||||
|
public List<byte[]> areaPosDatas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TargetData
|
||||||
|
{
|
||||||
|
public TargetData(List<byte[]> data)
|
||||||
|
{
|
||||||
|
targetData = data;
|
||||||
|
}
|
||||||
|
public List<byte[]> targetData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class LoadToSaveTemplate
|
||||||
|
{
|
||||||
|
public static Dictionary<int, MapAreaData> DictMapAreaData = new Dictionary<int, MapAreaData>();
|
||||||
|
public static Dictionary<int, string> DictMapIDFileName = new Dictionary<int, string>();
|
||||||
|
public static Dictionary<int, string> DictMapIDFullFileName = new Dictionary<int, string>();
|
||||||
|
public static Dictionary<int, string> DictGutiName = new Dictionary<int, string>();
|
||||||
|
public static Dictionary<int, string> DictStarName = new Dictionary<int, string>();
|
||||||
|
public static bool LoadMapTemplateAreaData(byte[] src,string FileName,string FullFileName)
|
||||||
|
{
|
||||||
|
byte[] target;
|
||||||
|
|
||||||
|
int _QuestTargetMapID;
|
||||||
|
//地图数据
|
||||||
|
MapAreaData mapAreaData;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
|
||||||
|
//从前4字节取出指针 定位任务信息位置
|
||||||
|
int _QuestInfoPtr = HexHelper.bytesToInt(target, 4, 0x00);
|
||||||
|
//Log.HexTips(0x00, "开始读取任务头部信息,指针->{0}", _QuestInfoPtr);
|
||||||
|
|
||||||
|
//任务目的地MapID
|
||||||
|
_QuestTargetMapID = HexHelper.bytesToInt(target, ModifyQuest.cQuestInfo_TargetMapID_Lenght, _QuestInfoPtr + ModifyQuest.cQuestInfo_TargetMap_Offset);
|
||||||
|
//Log.HexColor(ConsoleColor.Green, _QuestInfoPtr + ModifyQuest.cQuestInfo_TargetMap_Offset, "目的地地图,指针->{0} 【" + MHHelper.Get2MapName(_QuestTargetMapID) + "】", _QuestTargetMapID);
|
||||||
|
|
||||||
|
//区域数量
|
||||||
|
int _AreaCount = MHHelper.GetMapAreaCount(_QuestTargetMapID);
|
||||||
|
//Log.Info(MHHelper.Get2MapName(_QuestTargetMapID) + "的地图数量" + _AreaCount);
|
||||||
|
mapAreaData = new MapAreaData(_AreaCount);
|
||||||
|
|
||||||
|
#region 换区设置
|
||||||
|
|
||||||
|
//换区设置指针
|
||||||
|
int _CAreaSetTopPtr = HexHelper.bytesToInt(target, 4, 0x1C);
|
||||||
|
//Log.HexInfo(0x1C, "换区设置指针->{0}", _CAreaSetTopPtr);
|
||||||
|
|
||||||
|
//读取换区单个区域游标
|
||||||
|
int _CAreaSetTop_CurrPtr = _CAreaSetTopPtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < _AreaCount; i++)
|
||||||
|
{
|
||||||
|
int _One_CurrPtr = HexHelper.bytesToInt(target, 4, _CAreaSetTop_CurrPtr);
|
||||||
|
|
||||||
|
if (_One_CurrPtr == 0x0)
|
||||||
|
{
|
||||||
|
//Log.HexInfo(_CAreaSetTop_CurrPtr, "区域设置"+i+"指针为0,跳过");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<byte[]> datas = new List<byte[]>();
|
||||||
|
int Set_TargetIndex = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (MHHelper.CheckEnd(target, _One_CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target, 1, _One_CurrPtr) == 0)
|
||||||
|
{
|
||||||
|
//Log.HexInfo(_One_CurrPtr, "区域设置结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Log.HexInfo(_CAreaSetTop_CurrPtr, "第" + i + "区,第" + Set_TargetIndex + "个目标,换区设置指针->{0}", _One_CurrPtr);
|
||||||
|
//Log.HexTips(_One_CurrPtr, "第" + i + "区,第" + Set_TargetIndex + "个目标,读取数据,长度{0}", 0x34);
|
||||||
|
datas.Add(HexHelper.ReadBytes(target, 0x34, _One_CurrPtr));
|
||||||
|
Set_TargetIndex++;
|
||||||
|
_One_CurrPtr += 0x34;
|
||||||
|
}
|
||||||
|
mapAreaData.targetDatas[i] = new TargetData(datas);
|
||||||
|
|
||||||
|
_CAreaSetTop_CurrPtr += 0x4;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 区域映射
|
||||||
|
//区域映射指针
|
||||||
|
int _CAreaPosTopPtr = HexHelper.bytesToInt(target, 4, 0x20);
|
||||||
|
//Log.HexInfo(0x20, "换区映射指针->{0}", _CAreaPosTopPtr);
|
||||||
|
//读取单个区域映射游标
|
||||||
|
int _CAreaPosTop_CurrPtr = _CAreaPosTopPtr;
|
||||||
|
for (int i = 0; i < _AreaCount; i++)
|
||||||
|
{
|
||||||
|
//Log.HexTips(_CAreaPosTop_CurrPtr, "第" + i + "区的区域映射,读取数据,长度{0}", 0x20);
|
||||||
|
mapAreaData.areaPosDatas.Add(HexHelper.ReadBytes(target, 0x20, _CAreaPosTop_CurrPtr));
|
||||||
|
_CAreaPosTop_CurrPtr += 0x20;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
target = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DictMapAreaData[_QuestTargetMapID] = mapAreaData;
|
||||||
|
DictMapIDFileName[_QuestTargetMapID] = MHHelper.Get2MapName(_QuestTargetMapID) + FileName;
|
||||||
|
if (DictMapIDFullFileName.ContainsKey(_QuestTargetMapID))
|
||||||
|
{
|
||||||
|
File.Delete(DictMapIDFullFileName[_QuestTargetMapID]);
|
||||||
|
}
|
||||||
|
DictMapIDFullFileName[_QuestTargetMapID] = FullFileName;
|
||||||
|
//Log.HexColor(ConsoleColor.Green, _QuestTargetMapID, "成功,缓存地图 编号{0}" + MHHelper.Get2MapName(_QuestTargetMapID) + "的数据", _QuestTargetMapID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool LoadMaxGuti(byte[] src)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
|
||||||
|
//从前4字节取出指针 定位任务信息位置
|
||||||
|
int _QuestInfoPtr = HexHelper.bytesToInt(target, 4, 0x00);
|
||||||
|
//从前4字节取出指针 定位任务信息位置
|
||||||
|
int _QuestContentPtr = HexHelper.bytesToInt(target, 4, _QuestInfoPtr + 36);
|
||||||
|
int _QuestNametPtr = HexHelper.bytesToInt(target, 4, _QuestContentPtr);
|
||||||
|
string QuestName = HexHelper.ReadBytesToString(src, _QuestNametPtr);
|
||||||
|
|
||||||
|
//固体值
|
||||||
|
int _GuTiValue = HexHelper.bytesToInt(target, 4, 0x48);
|
||||||
|
DictGutiName[_GuTiValue] = QuestName;
|
||||||
|
|
||||||
|
|
||||||
|
//任务星 尝试处理方案
|
||||||
|
int _QuestStart = HexHelper.bytesToInt(target, 1, _QuestInfoPtr + ModifyQuest.cQuestInfo_Star_Offset);
|
||||||
|
DictStarName[_QuestStart] = QuestName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, int> DictTimeTypeCount = new Dictionary<string, int>();
|
||||||
|
public static void GetModeType(byte[] src,string FileName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
|
||||||
|
//从前4字节取出指针 定位任务信息位置
|
||||||
|
int _QuestInfoPtr = HexHelper.bytesToInt(target, 4, 0x00);
|
||||||
|
int _TimeType = HexHelper.bytesToInt(target, 1, _QuestInfoPtr + 2);
|
||||||
|
|
||||||
|
|
||||||
|
string key = FileName.Substring(FileName.Length - 1 - 5) + "_" + "(0x" + _TimeType.ToString("X") + ")";
|
||||||
|
if(!DictTimeTypeCount.ContainsKey(key))
|
||||||
|
{
|
||||||
|
DictTimeTypeCount[key] = 0;
|
||||||
|
}
|
||||||
|
DictTimeTypeCount[key]++;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
61
Log.cs
Normal file
61
Log.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MHFQuestReader
|
||||||
|
{
|
||||||
|
public static class Log
|
||||||
|
{
|
||||||
|
static bool bShowHex = true;
|
||||||
|
public static void HexInfo(long HexPos,string log, params long[] arr)
|
||||||
|
{
|
||||||
|
if(!bShowHex) return;
|
||||||
|
log = "0x" + HexPos.ToString("X") + ":" +log;
|
||||||
|
if(arr != null)
|
||||||
|
{
|
||||||
|
string[] strarr = new string[arr.Length];
|
||||||
|
for (int i = 0; i < arr.Length; i++)
|
||||||
|
{
|
||||||
|
strarr[i] = arr[i] + "(0x" + arr[i].ToString("X") + ")";
|
||||||
|
}
|
||||||
|
log = String.Format(log, strarr);
|
||||||
|
}
|
||||||
|
//TODO 改成别的方式记录
|
||||||
|
Console.WriteLine(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HexTips(long HexPos, string log, params long[] arr)
|
||||||
|
{
|
||||||
|
if (!bShowHex) return;
|
||||||
|
ConsoleColor src_color = Console.ForegroundColor;
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
HexInfo(HexPos, log, arr);
|
||||||
|
Console.ForegroundColor = src_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HexWar(long HexPos, string log, params long[] arr)
|
||||||
|
{
|
||||||
|
if (!bShowHex) return;
|
||||||
|
ConsoleColor src_color = Console.ForegroundColor;
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
HexInfo(HexPos, log, arr);
|
||||||
|
Console.ForegroundColor = src_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HexColor(ConsoleColor color,long HexPos, string log, params long[] arr)
|
||||||
|
{
|
||||||
|
if (!bShowHex) return;
|
||||||
|
ConsoleColor src_color = Console.ForegroundColor;
|
||||||
|
Console.ForegroundColor = color;
|
||||||
|
HexInfo(HexPos, log, arr);
|
||||||
|
Console.ForegroundColor = src_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Info(string log)
|
||||||
|
{
|
||||||
|
Console.WriteLine(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
MHFQuestReader.csproj
Normal file
12
MHFQuestReader.csproj
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<PublishAot>true</PublishAot>
|
||||||
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
25
MHFQuestReader.sln
Normal file
25
MHFQuestReader.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.9.34728.123
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MHFQuestReader", "MHFQuestReader.csproj", "{9DF60A83-67E5-4729-AB6E-27C7E73ACA94}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{9DF60A83-67E5-4729-AB6E-27C7E73ACA94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9DF60A83-67E5-4729-AB6E-27C7E73ACA94}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9DF60A83-67E5-4729-AB6E-27C7E73ACA94}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9DF60A83-67E5-4729-AB6E-27C7E73ACA94}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {33232194-97D8-476F-9BE6-B3D88993878E}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
17762
MHHelper.cs
Normal file
17762
MHHelper.cs
Normal file
File diff suppressed because it is too large
Load Diff
948
ModifyQuest.cs
Normal file
948
ModifyQuest.cs
Normal file
@ -0,0 +1,948 @@
|
|||||||
|
|
||||||
|
namespace MHFQuestReader
|
||||||
|
{
|
||||||
|
public static class ModifyQuest
|
||||||
|
{
|
||||||
|
|
||||||
|
public const int cMax_MapID = 0x49;
|
||||||
|
public const int cMax_MonsterID = 0x49;
|
||||||
|
public const int cMax_ItemID = 0x031D;
|
||||||
|
public const int cMax_FishID = 0x0017;
|
||||||
|
|
||||||
|
public const int cMax_GuTi = 0x16;
|
||||||
|
public const int cMax_QuestStar = 8;
|
||||||
|
|
||||||
|
public const int cModify_QuestID = 0xEA74;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 道具ID超出最大限制时,修改为【不可燃烧的废物】
|
||||||
|
/// </summary>
|
||||||
|
public const int cModify_OutOfItemID = 0x00AE;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 鱼ID超出最大限制时,修改为【刺身鱼】
|
||||||
|
/// </summary>
|
||||||
|
public const int cModify_OutOfFishID = 0x0002;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dos中无意义数据
|
||||||
|
/// </summary>
|
||||||
|
public const int cNon0x00For2DosPtr = 19;
|
||||||
|
/// <summary>
|
||||||
|
/// MHF任务信息偏移
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestMHFOffset = 12;
|
||||||
|
/// <summary>
|
||||||
|
/// 2Dos任务信息偏移
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuest2DosOffset = 8;
|
||||||
|
/// <summary>
|
||||||
|
/// 任务信息需偏移长度
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestMhfToDosSetLenght = 64;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务信息 指针组 总长度
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuest2DosInfoPtrGourpLenght = 72;
|
||||||
|
/// <summary>
|
||||||
|
/// 移动信息指针组 到的指定位置
|
||||||
|
/// </summary>
|
||||||
|
public const int cSetInfoPtrGourpMoveToStarPos = 0x88;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务内容 指针组 到的指定位置
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestContenPtrGourpMoveToStarPos = 0xD0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动整个任务文本 到的指定位置
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestTextAllMsgMoveToStarPos = 0xF0;
|
||||||
|
/// <summary>
|
||||||
|
/// 移动整个任务文本 到的指定的截止位置
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestTextAllMsgMoveToEndPos = 0x1Ff;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_类型 偏移
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_Type_Offset = 0;
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_类型 长度
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_Type_Lenght = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_星级 偏移
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_Star_Offset = 4;
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_星级 长度
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_Star_Lenght = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_类型 偏移
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_TargetMap_Offset = 32;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_类型 长度
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_TargetMapID_Lenght = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_类型 偏移
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_QuestID_Offset = 42 + 4;//MHF还要+4
|
||||||
|
/// <summary>
|
||||||
|
/// 任务_类型 长度
|
||||||
|
/// </summary>
|
||||||
|
public const int cQuestInfo_QuestID_Lenght = 2;
|
||||||
|
|
||||||
|
public static bool ReadQuset(byte[] src, out string _QuestName, out List<string> Infos, out uint _QuestID)
|
||||||
|
{
|
||||||
|
Infos = new List<string>();
|
||||||
|
_QuestName = "";
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
|
||||||
|
|
||||||
|
//任务信息
|
||||||
|
if (ModifyQuestMap(target, out List<string> out_ModifyQuestMap, out string QuestName, out _QuestID))
|
||||||
|
{
|
||||||
|
Infos.AddRange(out_ModifyQuestMap);
|
||||||
|
if (QuestName == "\u0011")
|
||||||
|
{
|
||||||
|
_QuestName = "_";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_QuestName = QuestName;
|
||||||
|
_QuestName = _QuestName.Trim(' ');
|
||||||
|
_QuestName = _QuestName.Replace(" ", "");
|
||||||
|
_QuestName = _QuestName.Replace("\r", "");
|
||||||
|
_QuestName = _QuestName.Replace("\n", "");
|
||||||
|
_QuestName = _QuestName.Replace("?", "");
|
||||||
|
_QuestName = _QuestName.Replace("\\", "");
|
||||||
|
_QuestName = _QuestName.Replace("/", "");
|
||||||
|
_QuestName = _QuestName.Replace("=", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//支援道具
|
||||||
|
if (FixSuppliesItem(target, out List<string> out_FixSuppliesItem))
|
||||||
|
{
|
||||||
|
Infos.AddRange(out_FixSuppliesItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//任务报酬
|
||||||
|
if (ModifyQuestRewardItem(target, out List<string> out_ModifyQuestRewardItem))
|
||||||
|
{
|
||||||
|
Infos.AddRange(out_ModifyQuestRewardItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//采集点
|
||||||
|
if (FixItemPoint(target, out List<string> out_FixItemPoint))
|
||||||
|
{
|
||||||
|
Infos.AddRange(out_FixItemPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
//鱼
|
||||||
|
if (FixFishGroupPoint(target, out List<string> out_FixFishGroupPoint))
|
||||||
|
{
|
||||||
|
Infos.AddRange(out_FixFishGroupPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (ModifyTextOffset(target, out byte[] out_ModifyTextOffset))
|
||||||
|
// target = out_ModifyTextOffset;
|
||||||
|
//else { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
//if (ModifyQuestBOSS(target, out byte[] out_ModifyQuestBOSS))
|
||||||
|
// target = out_ModifyQuestBOSS;
|
||||||
|
//else { return false; }
|
||||||
|
|
||||||
|
//if (FixMapAreaData(target, out byte[] out_FixMapAreaData))
|
||||||
|
// target = out_FixMapAreaData;
|
||||||
|
//else { return false; }
|
||||||
|
|
||||||
|
//else { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool ModifyQuestMap(byte[] src, out List<string> resultStr,out string QuestName,out uint _QuestID)
|
||||||
|
{
|
||||||
|
resultStr = new List<string>();
|
||||||
|
QuestName = "";
|
||||||
|
resultStr.Add("");
|
||||||
|
resultStr.Add("【任务基本信息】");
|
||||||
|
resultStr.Add("");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
|
||||||
|
//从前4字节取出指针 定位任务信息位置
|
||||||
|
int _QuestInfoPtr = HexHelper.bytesToInt(target, 4, 0x00);
|
||||||
|
Log.HexTips(0x00, "开始读取任务头部信息,指针->{0}", _QuestInfoPtr);
|
||||||
|
|
||||||
|
|
||||||
|
//----Step---- 读取任务数据
|
||||||
|
//任务类型
|
||||||
|
int _QuestType = HexHelper.bytesToInt(target, cQuestInfo_Type_Lenght, _QuestInfoPtr + cQuestInfo_Type_Offset);
|
||||||
|
Log.HexInfo(_QuestInfoPtr + cQuestInfo_Type_Offset, "任务类型->{0}", _QuestType);
|
||||||
|
|
||||||
|
|
||||||
|
//任务星 尝试处理方案
|
||||||
|
int _QuestStart = HexHelper.bytesToInt(target, 1, _QuestInfoPtr + cQuestInfo_Star_Offset);
|
||||||
|
//if (_QuestStart > cMax_QuestStar)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(_QuestInfoPtr + cQuestInfo_Star_Offset, "任务星级超出限制 ->{0},修正为2Dos星最大值{1}", _QuestStart, cMax_QuestStar);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
{
|
||||||
|
Log.HexColor(ConsoleColor.Magenta, _QuestInfoPtr + cQuestInfo_Star_Offset, "任务星级->{0}", _QuestStart);
|
||||||
|
}
|
||||||
|
//Log.HexTips(_QuestInfoPtr + cQuestInfo_Star_Offset, "写入任务星级,MHF为2位,2Dos为1位{0},覆盖第二位无意义数据", _QuestStart);
|
||||||
|
//HexHelper.ModifyIntHexToBytes(target, cMax_QuestStar, _QuestInfoPtr + cQuestInfo_Star_Offset, cQuestInfo_Star_Lenght);
|
||||||
|
|
||||||
|
|
||||||
|
int _QuestTargetMapID = HexHelper.bytesToInt(target, cQuestInfo_TargetMapID_Lenght, _QuestInfoPtr + cQuestInfo_TargetMap_Offset);
|
||||||
|
//if (_QuestTargetMapID > cMax_MapID)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(_QuestInfoPtr + cQuestInfo_TargetMap_Offset, "目的地地图,指针->{0} 超过最大 属于MHF地图", _QuestTargetMapID);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
{
|
||||||
|
Log.HexColor(ConsoleColor.Green, _QuestInfoPtr + cQuestInfo_TargetMap_Offset, "目的地地图,指针->{0} 【"+MHHelper.Get2MapName(_QuestTargetMapID)+ "】", _QuestTargetMapID);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _ModeType = HexHelper.bytesToInt(target, 1, _QuestInfoPtr + 2);
|
||||||
|
////非训练任务
|
||||||
|
//if (!MHHelper.CheckIsXunLianMode(_ModeType))
|
||||||
|
//{
|
||||||
|
// Log.HexTips(_QuestInfoPtr + 2, "任务模式->原始数据{0}", _ModeType);
|
||||||
|
// //如果是昼地图 但不是昼模式
|
||||||
|
// if (MHHelper.CheckIsDayMapID(_QuestTargetMapID)
|
||||||
|
// &&
|
||||||
|
// !MHHelper.CheckIsDayMode(_ModeType)
|
||||||
|
// )
|
||||||
|
// {
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, 0x1C, _QuestInfoPtr + 2, 1);
|
||||||
|
// Log.HexWar(_QuestInfoPtr + 2, "任务模式->修改白天 为{0}", 0x1C);
|
||||||
|
// }
|
||||||
|
// //如果是夜地图 但不是夜模式
|
||||||
|
// else if (MHHelper.CheckIsNightMapID(_QuestTargetMapID)
|
||||||
|
// &&
|
||||||
|
// !MHHelper.CheckIsNightMode(_ModeType)
|
||||||
|
// )
|
||||||
|
// {
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, 0x12, _QuestInfoPtr + 2, 1);
|
||||||
|
// Log.HexWar(_QuestInfoPtr + 2, "任务模式->修改黑夜 为{0}", 0x12);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.HexTips(_QuestInfoPtr + 2, "任务模式 原始数据 是训练模式 ->{0}", _ModeType);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
_QuestID = HexHelper.bytesToUInt(target, cQuestInfo_QuestID_Lenght, _QuestInfoPtr + cQuestInfo_QuestID_Offset);
|
||||||
|
Log.HexTips(_QuestInfoPtr + cQuestInfo_QuestID_Offset, "任务编号【{0}】", _QuestID);
|
||||||
|
//if (_QuestID < 60000)
|
||||||
|
//{
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, cModify_QuestID, _QuestInfoPtr + cQuestInfo_QuestID_Offset, cQuestInfo_QuestID_Lenght);
|
||||||
|
// Log.HexTips(_QuestInfoPtr + cQuestInfo_QuestID_Offset, "任务编号【{0}】小于60000,修正为【{1}】,使其可下载", _QuestID, cModify_QuestID);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//从前4字节取出指针 定位任务信息位置
|
||||||
|
int _QuestContentPtr = HexHelper.bytesToInt(target, 4, _QuestInfoPtr + 36 + 4);//MHF还要+4
|
||||||
|
Log.HexTips(_QuestInfoPtr + 24, "读取任务内容指针,指针->{0}", _QuestContentPtr);
|
||||||
|
|
||||||
|
int _QuestNametPtr = HexHelper.bytesToInt(target, 4, _QuestContentPtr);
|
||||||
|
QuestName = HexHelper.ReadBytesToString(src, _QuestNametPtr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Log.HexColor(ConsoleColor.Green,_QuestNametPtr, "任务名称:" + QuestName); ;
|
||||||
|
|
||||||
|
|
||||||
|
//固体值
|
||||||
|
int _GuTiValue = HexHelper.bytesToInt(target, 4, 0x48);
|
||||||
|
|
||||||
|
|
||||||
|
resultStr.Add("[任务名称]");
|
||||||
|
resultStr.Add(QuestName);
|
||||||
|
|
||||||
|
resultStr.Add("[任务编号]");
|
||||||
|
resultStr.Add(_QuestID.ToString());
|
||||||
|
|
||||||
|
resultStr.Add("[任务星级]");
|
||||||
|
resultStr.Add(_QuestStart.ToString());
|
||||||
|
|
||||||
|
resultStr.Add("[任务模式值]");
|
||||||
|
resultStr.Add(_ModeType.ToString());
|
||||||
|
|
||||||
|
resultStr.Add("[任务地图]");
|
||||||
|
resultStr.Add(MHHelper.Get2MapName(_QuestTargetMapID));
|
||||||
|
|
||||||
|
resultStr.Add("[固体值(怪物强度)]");
|
||||||
|
resultStr.Add(_GuTiValue.ToString());
|
||||||
|
|
||||||
|
//if (_GuTiValue > cMax_GuTi)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(0x48, "固体值超出限制 ->{0},修正为2Dos最大值{1}", _GuTiValue, cMax_GuTi);
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, cMax_GuTi, 0x48, 4);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
{
|
||||||
|
Log.HexColor(ConsoleColor.Blue, 0x48, "固体值 ->{0}", _GuTiValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
//target = null;
|
||||||
|
_QuestID = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 轮询单个报酬组的数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="src"></param>
|
||||||
|
/// <param name="target"></param>
|
||||||
|
/// <param name="_RewardGroupPtr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
static bool QuestRewardGroup(byte[] src,int _RewardGroupPtr, out List<string> resultStr)
|
||||||
|
{
|
||||||
|
resultStr = new List<string>();
|
||||||
|
//加载数据
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);
|
||||||
|
//读取报酬游标
|
||||||
|
int CurrPtr = _RewardGroupPtr;
|
||||||
|
bool isFinish = false;
|
||||||
|
int setCount = 0;
|
||||||
|
while (!isFinish)
|
||||||
|
{
|
||||||
|
//若遇到结束符
|
||||||
|
if (MHHelper.CheckEnd(target, CurrPtr))
|
||||||
|
{
|
||||||
|
isFinish = true;
|
||||||
|
Log.HexInfo(CurrPtr, "遇报酬组结束符");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setCount++;
|
||||||
|
int Pr = HexHelper.bytesToInt(target, 2, CurrPtr);//概率
|
||||||
|
int ItemID = HexHelper.bytesToInt(target, 2, CurrPtr + 0x02);//道具ID
|
||||||
|
int count = HexHelper.bytesToInt(target, 2, CurrPtr + 0x04);//数量
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
resultStr.Add($"{MHHelper.Get2DosItemName(ItemID)}|概率:{Pr}|数量:{count}");
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrPtr += 0x06;//前推游标
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ModifyQuestBOSS(byte[] src, out byte[] target)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
//BOSS(头部信息指针
|
||||||
|
int _BOOSInFoPtr = HexHelper.bytesToInt(target, 4, 0x18);
|
||||||
|
|
||||||
|
Log.HexTips(0x18, "开始读取BOSS(头部信息,指针->{0}", _BOOSInFoPtr);
|
||||||
|
|
||||||
|
//BOSS组指针
|
||||||
|
int _BOOSStarPtr = HexHelper.bytesToInt(target, 4, _BOOSInFoPtr + 0x08);
|
||||||
|
|
||||||
|
Log.HexTips(_BOOSInFoPtr + 0x08, "第一个BOSS指针->{0}", _BOOSStarPtr);
|
||||||
|
|
||||||
|
//读取BOSS组游标
|
||||||
|
int CurrPtr = _BOOSStarPtr;
|
||||||
|
bool isFinish = false;
|
||||||
|
|
||||||
|
int BOSSIndex = 0;
|
||||||
|
//循环取BOSS组
|
||||||
|
while (!isFinish)
|
||||||
|
{
|
||||||
|
//若遇到结束符或无数据
|
||||||
|
if (MHHelper.CheckEnd(target, CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target,1, CurrPtr) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
isFinish = true;
|
||||||
|
Log.HexInfo(CurrPtr, "遇BOSS组信息结束符或无数据");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BOSSIndex++;
|
||||||
|
//报酬组类型
|
||||||
|
int _BOSSID = HexHelper.bytesToInt(target, 0x04, CurrPtr);
|
||||||
|
|
||||||
|
if (_BOSSID > cMax_MonsterID)
|
||||||
|
{
|
||||||
|
Log.HexWar(CurrPtr, "第{0}个BOSS,ID->{1} 大于了 最大ID{2} 属于MHF怪物,该任务无法使用", BOSSIndex, _BOSSID, cMax_MonsterID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.HexColor(ConsoleColor.Green, CurrPtr, "第{0}个BOSS,ID->{1} 【" + MHHelper.Get2BossName(_BOSSID) + "】", BOSSIndex, _BOSSID);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrPtr += 0x04;//前推游标
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex); target = null; return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FixMapAreaData(byte[] src,out byte[] target)
|
||||||
|
{
|
||||||
|
int _QuestTargetMapID;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
|
||||||
|
//从前4字节取出指针 定位任务信息位置
|
||||||
|
int _QuestInfoPtr = HexHelper.bytesToInt(target, 4, 0x00);
|
||||||
|
Log.HexTips(0x00, "开始读取任务头部信息,指针->{0}", _QuestInfoPtr);
|
||||||
|
|
||||||
|
//任务目的地MapID
|
||||||
|
_QuestTargetMapID = HexHelper.bytesToInt(target, ModifyQuest.cQuestInfo_TargetMapID_Lenght, _QuestInfoPtr + ModifyQuest.cQuestInfo_TargetMap_Offset);
|
||||||
|
Log.HexColor(ConsoleColor.Green, _QuestInfoPtr + ModifyQuest.cQuestInfo_TargetMap_Offset, "目的地地图,指针->{0} 【" + MHHelper.Get2MapName(_QuestTargetMapID) + "】", _QuestTargetMapID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (LoadToSaveTemplate.DictMapAreaData.ContainsKey(_QuestTargetMapID))
|
||||||
|
{
|
||||||
|
//区域数量
|
||||||
|
int _AreaCount = MHHelper.GetMapAreaCount(_QuestTargetMapID);
|
||||||
|
Log.Info(MHHelper.Get2MapName(_QuestTargetMapID) + "的地图数量" + _AreaCount);
|
||||||
|
|
||||||
|
MapAreaData srcData2Dos = LoadToSaveTemplate.DictMapAreaData[_QuestTargetMapID];
|
||||||
|
#region 换区设置
|
||||||
|
|
||||||
|
//换区设置指针
|
||||||
|
int _CAreaSetTopPtr = HexHelper.bytesToInt(target, 4, 0x1C);
|
||||||
|
Log.HexInfo(0x1C, "换区设置指针->{0}", _CAreaSetTopPtr);
|
||||||
|
|
||||||
|
//读取换区单个区域游标
|
||||||
|
int _CAreaSetTop_CurrPtr = _CAreaSetTopPtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < _AreaCount; i++)
|
||||||
|
{
|
||||||
|
int _One_CurrPtr = HexHelper.bytesToInt(target, 4, _CAreaSetTop_CurrPtr);
|
||||||
|
|
||||||
|
if (_One_CurrPtr == 0x0)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_CAreaSetTop_CurrPtr, "区域设置" + i + "指针为0,跳过");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcData2Dos.targetDatas.Length <= i)
|
||||||
|
{
|
||||||
|
Log.HexWar(_One_CurrPtr, "第" + i + "区 区域设置,比2Dos区数超限。");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Set_TargetIndex = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (MHHelper.CheckEnd(target, _One_CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target, 1, _One_CurrPtr) == 0)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_One_CurrPtr, "区域设置结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcData2Dos.targetDatas[i].targetData.Count <= Set_TargetIndex)
|
||||||
|
{
|
||||||
|
Log.HexWar(_One_CurrPtr, "第" + i + "区,第" + Set_TargetIndex + "个目标,比2Dos目标数超限。");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] srcOneData = srcData2Dos.targetDatas[i].targetData[Set_TargetIndex];
|
||||||
|
|
||||||
|
HexHelper.ModifyDataToBytes(target, srcOneData, _One_CurrPtr);
|
||||||
|
Log.HexTips(_One_CurrPtr, "第" + i + "区,第" + Set_TargetIndex + "个目标,更换为2Dos数据,长度{0}", srcOneData.Length);
|
||||||
|
|
||||||
|
Set_TargetIndex++;
|
||||||
|
_One_CurrPtr += 0x34;
|
||||||
|
}
|
||||||
|
|
||||||
|
_CAreaSetTop_CurrPtr += 0x4;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 区域映射
|
||||||
|
//区域映射指针
|
||||||
|
int _CAreaPosTopPtr = HexHelper.bytesToInt(target, 4, 0x20);
|
||||||
|
Log.HexInfo(0x20, "换区映射指针->{0}", _CAreaPosTopPtr);
|
||||||
|
//读取单个区域映射游标
|
||||||
|
int _CAreaPosTop_CurrPtr = _CAreaPosTopPtr;
|
||||||
|
for (int i = 0; i < _AreaCount; i++)
|
||||||
|
{
|
||||||
|
if (srcData2Dos.targetDatas.Length <= i)
|
||||||
|
{
|
||||||
|
Log.HexWar(_CAreaPosTop_CurrPtr, "第" + i + "区 换区映射,比2Dos区数超限。");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
byte[] srcOneData = srcData2Dos.areaPosDatas[i];
|
||||||
|
|
||||||
|
HexHelper.ModifyDataToBytes(target, srcOneData, _CAreaPosTop_CurrPtr);
|
||||||
|
Log.HexTips(_CAreaPosTop_CurrPtr, "第" + i + "区的区域映射,更换为2Dos数据,读取数据,长度{0}", srcOneData.Length);
|
||||||
|
_CAreaPosTop_CurrPtr += 0x20;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.HexColor(ConsoleColor.Green, _QuestInfoPtr + ModifyQuest.cQuestInfo_TargetMap_Offset, "目的地地图,在源数据之外");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
target = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报酬
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="src"></param>
|
||||||
|
/// <param name="target"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool ModifyQuestRewardItem(byte[] src,out List<string> resultStr)
|
||||||
|
{
|
||||||
|
resultStr = new List<string>();
|
||||||
|
|
||||||
|
resultStr.Add("");
|
||||||
|
resultStr.Add("【任务报酬】");
|
||||||
|
resultStr.Add("");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
//任务报酬信息指针
|
||||||
|
int _QuestRewardPtr = HexHelper.bytesToInt(target, 4, 0x0C);
|
||||||
|
|
||||||
|
Log.HexTips(0x0C, "开始读取报酬组头部信息,指针->{0}", _QuestRewardPtr); ;
|
||||||
|
|
||||||
|
//读取组报酬游标
|
||||||
|
int CurrPtr = _QuestRewardPtr;
|
||||||
|
bool isFinish = false;
|
||||||
|
|
||||||
|
int GroupIndex = 0;
|
||||||
|
//循环取道具组
|
||||||
|
while (!isFinish)
|
||||||
|
{
|
||||||
|
//若遇到结束符
|
||||||
|
if (MHHelper.CheckEnd(target, CurrPtr))
|
||||||
|
{
|
||||||
|
isFinish = true;
|
||||||
|
Log.HexInfo(CurrPtr, "遇报酬组头部信息结束符");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GroupIndex++;
|
||||||
|
//报酬组类型
|
||||||
|
int _RewardCondition = HexHelper.bytesToInt(target, 0x04, CurrPtr);
|
||||||
|
//报酬组指针
|
||||||
|
int _RewardGroupPtr = HexHelper.bytesToInt(target, 0x04, CurrPtr + 0x04);
|
||||||
|
|
||||||
|
Log.HexTips(CurrPtr, "第{0}报酬组,报酬类型->{1} 报酬组指针->{2}", GroupIndex, _RewardCondition, _RewardGroupPtr);
|
||||||
|
|
||||||
|
resultStr.Add($"--[第{GroupIndex}组报酬]");
|
||||||
|
|
||||||
|
//取组内报酬
|
||||||
|
if (QuestRewardGroup(target, _RewardGroupPtr, out List<string> Single_resultStr))
|
||||||
|
{
|
||||||
|
resultStr.AddRange(Single_resultStr);
|
||||||
|
}
|
||||||
|
CurrPtr += 0x08;//前推游标 读取下一个报酬道具组
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FixSuppliesItem(byte[] src, out List<string> resultStr)
|
||||||
|
{
|
||||||
|
resultStr = new List<string>();
|
||||||
|
resultStr.Add("");
|
||||||
|
resultStr.Add("【支援道具报酬】");
|
||||||
|
resultStr.Add("");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
//支援道具指针
|
||||||
|
int _SuppliesItemPtr = HexHelper.bytesToInt(target, 4, 0x08);
|
||||||
|
Log.HexTips(0x08, "开始读取支援道具指针,指针->{0}", _SuppliesItemPtr);
|
||||||
|
|
||||||
|
int _SuppliesItem_CurrPtr = _SuppliesItemPtr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
resultStr.Add("--[主线支援道具]");
|
||||||
|
|
||||||
|
for (int i = 0; i < 96; i++)
|
||||||
|
{
|
||||||
|
//若遇到结束符或无数据
|
||||||
|
if (MHHelper.CheckEnd(target, _SuppliesItem_CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target, 4, _SuppliesItem_CurrPtr) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_SuppliesItem_CurrPtr, "主线支援道具,结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ItemID = HexHelper.bytesToInt(target, 2, _SuppliesItem_CurrPtr);//道具ID
|
||||||
|
int Count = HexHelper.bytesToInt(target, 2, _SuppliesItem_CurrPtr + 0x02);//数量
|
||||||
|
|
||||||
|
resultStr.Add($"{MHHelper.Get2DosItemName(ItemID)} | 数量{Count}");
|
||||||
|
|
||||||
|
////判断道具ID是否超限
|
||||||
|
//if (ItemID > cMax_ItemID)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(_SuppliesItem_CurrPtr, "主线支援道具,第" + i + "个ID->{0}道具ID超出最大可能{1},属于MHF道具【" + MHHelper.Get2MHFItemName(ItemID) + "】,将其修正为【不可燃烧的废物】ID->{2}", ItemID, cMax_ItemID, cModify_OutOfItemID);
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, cModify_OutOfItemID, _SuppliesItem_CurrPtr, 2);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.HexColor(ConsoleColor.Green, _SuppliesItem_CurrPtr, "主线支援道具第" + i + "个,道具ID->{0} 【" + MHHelper.Get2DosItemName(ItemID) + "】 数量->{1}", ItemID, Count);
|
||||||
|
//}
|
||||||
|
|
||||||
|
_SuppliesItem_CurrPtr += 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
resultStr.Add("--[支线1支援道具]");
|
||||||
|
|
||||||
|
int _SuppliesItem_Zhi_1_CurrPtr = _SuppliesItemPtr + 0x60;
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
//若遇到结束符或无数据
|
||||||
|
if (MHHelper.CheckEnd(target, _SuppliesItem_Zhi_1_CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target, 4, _SuppliesItem_Zhi_1_CurrPtr) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_SuppliesItem_Zhi_1_CurrPtr, "支线1支援道具,结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ItemID = HexHelper.bytesToInt(target, 2, _SuppliesItem_Zhi_1_CurrPtr);//道具ID
|
||||||
|
int Count = HexHelper.bytesToInt(target, 2, _SuppliesItem_Zhi_1_CurrPtr + 0x02);//数量
|
||||||
|
|
||||||
|
resultStr.Add($"{MHHelper.Get2DosItemName(ItemID)} | 数量{Count}");
|
||||||
|
////判断道具ID是否超限
|
||||||
|
//if (ItemID > cMax_ItemID)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(_SuppliesItem_Zhi_1_CurrPtr, "支线1支援道具第" + i + "个,ID->{0}道具ID超出最大可能{1},属于MHF道具【" + MHHelper.Get2MHFItemName(ItemID) + "】,将其修正为【不可燃烧的废物】ID->{2}", ItemID, cMax_ItemID, cModify_OutOfItemID);
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, cModify_OutOfItemID, _SuppliesItem_Zhi_1_CurrPtr, 2);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.HexColor(ConsoleColor.Green, _SuppliesItem_Zhi_1_CurrPtr, "支线1支援道具第" + i + "个主线,道具ID->{0} 【" + MHHelper.Get2DosItemName(ItemID) + "】 数量->{1}", ItemID, Count);
|
||||||
|
//}
|
||||||
|
|
||||||
|
_SuppliesItem_Zhi_1_CurrPtr += 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
resultStr.Add("--[支线2支援道具]");
|
||||||
|
int _SuppliesItem_Zhi_2_CurrPtr = _SuppliesItemPtr + 0x60 + 0x20;
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
//若遇到结束符或无数据
|
||||||
|
if (MHHelper.CheckEnd(target, _SuppliesItem_Zhi_2_CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target, 4, _SuppliesItem_Zhi_2_CurrPtr) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_SuppliesItem_Zhi_2_CurrPtr, "支线2支援道具,结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ItemID = HexHelper.bytesToInt(target, 2, _SuppliesItem_Zhi_2_CurrPtr);//道具ID
|
||||||
|
int Count = HexHelper.bytesToInt(target, 2, _SuppliesItem_Zhi_2_CurrPtr + 0x02);//数量
|
||||||
|
|
||||||
|
resultStr.Add($"{MHHelper.Get2DosItemName(ItemID)} | 数量{Count}");
|
||||||
|
////判断道具ID是否超限
|
||||||
|
//if (ItemID > cMax_ItemID)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(_SuppliesItem_Zhi_2_CurrPtr, "支线2支援道具第" + i + "个,ID->{0}道具ID超出最大可能{1},属于MHF道具【" + MHHelper.Get2MHFItemName(ItemID) + "】,将其修正为【不可燃烧的废物】ID->{2}", ItemID, cMax_ItemID, cModify_OutOfItemID);
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, cModify_OutOfItemID, _SuppliesItem_Zhi_2_CurrPtr, 2);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.HexColor(ConsoleColor.Green, _SuppliesItem_Zhi_2_CurrPtr, "支线2支援道具第" + i + "个主线,道具ID->{0} 【" + MHHelper.Get2DosItemName(ItemID) + "】 数量->{1}", ItemID, Count);
|
||||||
|
//}
|
||||||
|
|
||||||
|
_SuppliesItem_Zhi_2_CurrPtr += 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
//target = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FixItemPoint(byte[] src,out List<string> resultStr)
|
||||||
|
{
|
||||||
|
resultStr = new List<string>();
|
||||||
|
resultStr.Add("");
|
||||||
|
resultStr.Add("【采集点信息】");
|
||||||
|
resultStr.Add("");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
//采集点指针
|
||||||
|
int _ItemPointPtr = HexHelper.bytesToInt(target, 4, 0x38);
|
||||||
|
Log.HexTips(0x38, "开始读取采集点指针,指针->{0}", _ItemPointPtr);
|
||||||
|
|
||||||
|
int _ItemPoint_CurrPtr = _ItemPointPtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < 90; i++)
|
||||||
|
{
|
||||||
|
//若遇到结束符或无数据
|
||||||
|
if (MHHelper.CheckEnd(target, _ItemPoint_CurrPtr)
|
||||||
|
//||
|
||||||
|
//HexHelper.bytesToInt(target, 1, _ItemPoint_CurrPtr) == 0 // 不能判断头部为0 否则当前道具概率为0时,会跳过
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_ItemPoint_CurrPtr, "采集点结束");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
resultStr.Add($"--[采集代号{i}]");
|
||||||
|
|
||||||
|
if (i == 59)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
int ItemStartPtr = HexHelper.bytesToInt(target, 4, _ItemPoint_CurrPtr);
|
||||||
|
|
||||||
|
|
||||||
|
int ItemCurrPtr = ItemStartPtr;
|
||||||
|
|
||||||
|
int setCount = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
//若遇到结束符或无数据
|
||||||
|
if (MHHelper.CheckEnd(target, ItemCurrPtr)
|
||||||
|
//||
|
||||||
|
//HexHelper.bytesToInt(target, 1, ItemCurrPtr) == 0 // 不能判断值为0 否则当前道具概率为0时,会跳过
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(ItemCurrPtr, "第{0}个采集代号,第" + setCount + "个素材 结束符",i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int Pr = HexHelper.bytesToInt(target, 2, ItemCurrPtr);//概率
|
||||||
|
int ItemID = HexHelper.bytesToInt(target, 2, ItemCurrPtr + 0x02);//道具ID
|
||||||
|
|
||||||
|
if (Pr > 0 && ItemID > 0 && ItemID <= 0x031D)
|
||||||
|
{
|
||||||
|
resultStr.Add($"道具:{MHHelper.Get2DosItemName(ItemID)},概率:{Pr}");
|
||||||
|
}
|
||||||
|
|
||||||
|
////判断道具ID是否超限
|
||||||
|
//if (ItemID > cMax_ItemID)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(ItemCurrPtr, "第{0}个采集代号,第" + setCount + "个素材,ID->{1}道具ID超出最大可能{2},属于MHF道具【" + MHHelper.Get2MHFItemName(ItemID) + "】,将其修正为【不可燃烧的废物】ID->{3}", i,ItemID, cMax_ItemID, cModify_OutOfItemID);
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, cModify_OutOfItemID, ItemCurrPtr + 0x02, 2);
|
||||||
|
// ItemID = HexHelper.bytesToInt(target, 2, ItemCurrPtr + 0x02);//道具ID
|
||||||
|
// Log.HexTips(ItemCurrPtr, "重新读取 第{0}个采集代号,第" + setCount + "个素材,道具ID->{1} 【" + MHHelper.Get2DosItemName(ItemID) + "】 概率->{2}", i,ItemID, Pr);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.HexColor(ConsoleColor.Green, ItemCurrPtr, "第{0}个采集代号,第" + setCount + "个素材,道具ID->{1} 【" + MHHelper.Get2DosItemName(ItemID) + "】 概率->{2}", i,ItemID, Pr);
|
||||||
|
//}
|
||||||
|
setCount++;
|
||||||
|
ItemCurrPtr += 0x04;
|
||||||
|
}
|
||||||
|
_ItemPoint_CurrPtr += 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
//target = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FixFishGroupPoint(byte[] src,out List<string> resultStr)
|
||||||
|
{
|
||||||
|
resultStr = new List<string>();
|
||||||
|
resultStr.Add("");
|
||||||
|
resultStr.Add("【钓鱼点信息】");
|
||||||
|
resultStr.Add("");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] target = HexHelper.CopyByteArr(src);//加载数据
|
||||||
|
//鱼群指针
|
||||||
|
int _FishGroupPtr = HexHelper.bytesToInt(target, 4, 0x40);
|
||||||
|
Log.HexTips(0x40, "开始读取鱼群信息,指针->{0}", _FishGroupPtr);
|
||||||
|
int _FishGroup_CurrPtr = _FishGroupPtr;
|
||||||
|
|
||||||
|
int setFishGroup = 0;
|
||||||
|
//鱼群代号 循环
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
//鱼群代号结束符
|
||||||
|
if (
|
||||||
|
_FishGroup_CurrPtr >= target.Length
|
||||||
|
||
|
||||||
|
MHHelper.CheckEnd(target, _FishGroup_CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target, 4, _FishGroup_CurrPtr) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_FishGroup_CurrPtr, $"第{setFishGroup}鱼群代号 结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//鱼群季节循环
|
||||||
|
int _FishSeasonStartPtr = HexHelper.bytesToInt(target, 4, _FishGroup_CurrPtr);
|
||||||
|
int _FishSeason_CurrPtr = _FishSeasonStartPtr;
|
||||||
|
|
||||||
|
|
||||||
|
//鱼群季节循环
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
//鱼群季节结束符
|
||||||
|
if (
|
||||||
|
_FishSeason_CurrPtr >= target.Length
|
||||||
|
||
|
||||||
|
MHHelper.CheckEnd(target, _FishSeason_CurrPtr)
|
||||||
|
||
|
||||||
|
HexHelper.bytesToInt(target, 1, _FishSeason_CurrPtr) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_FishSeason_CurrPtr, $"第{setFishGroup}鱼群代号 第{i}个季节昼夜 结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string DayType = "";
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 0: DayType = "温暖期|白天"; break;
|
||||||
|
case 1: DayType = "繁殖期|白天"; break;
|
||||||
|
case 2: DayType = "寒冷期|白天"; break;
|
||||||
|
case 3: DayType = "温暖期|夜晚"; break;
|
||||||
|
case 4: DayType = "繁殖期|夜晚"; break;
|
||||||
|
case 5: DayType = "寒冷期|夜晚"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
resultStr.Add($"--[鱼群代号{setFishGroup} - {DayType}]");
|
||||||
|
|
||||||
|
int _FishStartPtr = HexHelper.bytesToInt(target, 4, _FishSeason_CurrPtr);
|
||||||
|
int _FishStart_CurrPtr = _FishStartPtr;
|
||||||
|
|
||||||
|
int setFish = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
//鱼结束符
|
||||||
|
if (
|
||||||
|
_FishStart_CurrPtr >= target.Length
|
||||||
|
||
|
||||||
|
MHHelper.CheckEndWith1Byte(target, _FishStart_CurrPtr)
|
||||||
|
//||
|
||||||
|
//HexHelper.bytesToInt(target, 1, _FishStart_CurrPtr) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Log.HexInfo(_FishStart_CurrPtr, $"第{setFishGroup}鱼群代号 第{i}个季节昼夜 第" + setFish + "个鱼 结束符");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pr = HexHelper.bytesToInt(target, 1, _FishStart_CurrPtr);//概率
|
||||||
|
int FishID = HexHelper.bytesToInt(target, 1, _FishStart_CurrPtr + 0x01);//鱼ID
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (Pr > 0 && FishID > 0)
|
||||||
|
{
|
||||||
|
resultStr.Add($"{MHHelper.Get2DosFishName(FishID)} | 概率:{Pr}");
|
||||||
|
}
|
||||||
|
|
||||||
|
////判断道具ID是否超限
|
||||||
|
//if (FishID > cMax_FishID)
|
||||||
|
//{
|
||||||
|
// Log.HexWar(_FishStart_CurrPtr, "第" + setFishGroup + "鱼群,第" + i + "个季节昼夜,第" + setFish + "个鱼 鱼ID->{0} 超出2Dos最大值{1},修正为【刺身鱼】{2}", FishID, cMax_FishID, cModify_OutOfFishID);
|
||||||
|
// HexHelper.ModifyIntHexToBytes(target, cModify_OutOfFishID, _FishStart_CurrPtr + 0x01, 1);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.HexColor(ConsoleColor.Green, _FishStart_CurrPtr, "第" + setFishGroup + "鱼群,第" + i + "个季节昼夜,第" + setFish + "个鱼 鱼ID->{0}【"+MHHelper.Get2DosFishName(FishID)+"】 概率->{1}", FishID, Pr);
|
||||||
|
//}
|
||||||
|
|
||||||
|
setFish++;
|
||||||
|
_FishStart_CurrPtr += 0x02;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FishSeason_CurrPtr += 0x08;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFishGroup++;
|
||||||
|
_FishGroup_CurrPtr += 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
107
Program.cs
Normal file
107
Program.cs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MHFQuestReader
|
||||||
|
{
|
||||||
|
internal class Program
|
||||||
|
{
|
||||||
|
static string loc = Path.GetDirectoryName(AppContext.BaseDirectory) + "\\";
|
||||||
|
|
||||||
|
const string InDir = "Input";
|
||||||
|
const string OutDir = "Out";
|
||||||
|
const string ListFile = "OutListFile.csv";
|
||||||
|
const string Ver = "0.0.1";
|
||||||
|
|
||||||
|
static Dictionary<uint, string> DictQuestID2Name = new Dictionary<uint, string>();
|
||||||
|
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
string title = $"MHFQuestReader Ver.{Ver} By 皓月云 axibug.com";
|
||||||
|
Console.Title = title;
|
||||||
|
Console.WriteLine(title);
|
||||||
|
|
||||||
|
|
||||||
|
if (!Directory.Exists(loc + InDir))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Input文件不存在");
|
||||||
|
Console.ReadLine();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(loc + OutDir))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Out文件不存在");
|
||||||
|
Console.ReadLine();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
|
|
||||||
|
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 (ModifyQuest.ReadQuset(data, out string _QuestName, out List<string> Infos, out uint _QuestID))
|
||||||
|
{
|
||||||
|
DictQuestID2Name[_QuestID] = _QuestName;
|
||||||
|
string newfileName = FileName + "_" + _QuestName + ".txt";
|
||||||
|
string outstring = loc + OutDir + "\\" + newfileName;
|
||||||
|
|
||||||
|
FileHelper.SaveFile(outstring, Infos.ToArray());
|
||||||
|
Console.WriteLine($">>>>>>>>>>>>>>成功处理 第{index}个:{outstring}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errcount++;
|
||||||
|
Console.WriteLine($">>>>>>>>>>>>>>处理失败 第{index}个");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"已处理{files.Length}个文件,其中{errcount}个失败");
|
||||||
|
|
||||||
|
|
||||||
|
string outliststr = string.Empty;
|
||||||
|
foreach (var file in DictQuestID2Name)
|
||||||
|
{
|
||||||
|
outliststr += $"{file.Key},{file.Value}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换编码为UTF-8
|
||||||
|
byte[] utf8Bytes = Encoding.Convert(Encoding.GetEncoding("shift_jis"), Encoding.UTF8, Encoding.GetEncoding("shift_jis").GetBytes(outliststr));
|
||||||
|
|
||||||
|
// 将字节数组转换回字符串
|
||||||
|
outliststr = Encoding.UTF8.GetString(utf8Bytes);
|
||||||
|
|
||||||
|
|
||||||
|
File.WriteAllText(loc + ListFile, outliststr);
|
||||||
|
|
||||||
|
|
||||||
|
string[] tempkeys = LoadToSaveTemplate.DictTimeTypeCount.Keys.OrderBy(w => w).ToArray();
|
||||||
|
|
||||||
|
foreach (var r in tempkeys)
|
||||||
|
{
|
||||||
|
Console.WriteLine(r + ":" + LoadToSaveTemplate.DictTimeTypeCount[r]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ReadLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user