mhfdat的道具读取

This commit is contained in:
sin365 2024-05-10 18:28:39 +08:00
commit 6fdc6327e7
6 changed files with 18697 additions and 0 deletions

56
FileHelper.cs Normal file
View File

@ -0,0 +1,56 @@
using System.Text;
namespace MHFOldShopTools
{
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;
}
}
}
}

226
HexHelper.cs Normal file
View File

@ -0,0 +1,226 @@
using System.Text;
namespace MHFOldShopTools
{
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;
}
}
}

12
MHFOldShopTools.csproj Normal file
View 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
MHFOldShopTools.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34511.84
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MHFOldShopTools", "MHFOldShopTools.csproj", "{9413CA44-D3D2-4342-9F64-9625E6EE6AAF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9413CA44-D3D2-4342-9F64-9625E6EE6AAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9413CA44-D3D2-4342-9F64-9625E6EE6AAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9413CA44-D3D2-4342-9F64-9625E6EE6AAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9413CA44-D3D2-4342-9F64-9625E6EE6AAF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {347C8075-6DA6-45FB-A47A-05A9F335DF1A}
EndGlobalSection
EndGlobal

18220
MHHelper.cs Normal file

File diff suppressed because it is too large Load Diff

158
Program.cs Normal file
View File

@ -0,0 +1,158 @@
using System.Text;
namespace MHFOldShopTools
{
internal class Program
{
static string loc = Path.GetDirectoryName(AppContext.BaseDirectory) + "\\";
const string InDir = "Input";
const string OutDir = "Out";
const string Ver = "0.1";
static void Main(string[] args)
{
string title = $"MHFOldShopTools 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;
//}
//if (!Directory.Exists(loc + PosFile2DosDir))
//{
// Console.WriteLine("Templete文件不存在");
// Console.ReadLine();
// return;
//}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
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(".bin"))
{
continue;
}
index++;
Console.WriteLine($">>>>>>>>>>>>>>开始处理 第{index}个文件 {FileName}<<<<<<<<<<<<<<<<<<<");
FileHelper.LoadFile(files[i], out byte[] data);
ReaderItems(data);
Console.WriteLine($">>>>>>>>>>>>>>处理完毕");
}
while (true)
{
Console.ReadLine();
}
}
static int StartPtr = 0x539A78;
const int _singelItemDatalenght = 12;
static void ReaderItems(byte[] data)
{
List<ShopItem> items = new List<ShopItem>();
int ToUpCount = 712;
for (int i = 0; i < ToUpCount; i++)
{
items.Add(GetShopItemInfo(data, StartPtr + (-1 * i * _singelItemDatalenght)));
}
for (int i = items.Count - 1; i >= 0; i--)
{
ShopItem item = items[i];
string ItemInfo;
if (item.UnKnow)
ItemInfo = $"{"0x" + item.Ptr.ToString("X") + ":"} | 解析失败";
else
ItemInfo = $"{ "0x" + item.Ptr.ToString("X") + ":"} | {item.ItemID} ({MHHelper.Get2MHFItemName(item.ItemID)}) | {item.Point}点 | {item.Group}{GetShopName(item.Group)}| [{item.OtherData[0].ToString("X")} {item.OtherData[1].ToString("X")} {item.OtherData[2].ToString("X")} {item.OtherData[3].ToString("X")}]";
Console.WriteLine(ItemInfo);
}
}
static string GetShopName(int gourp)
{
switch (gourp)
{
case 0:return "基本道具";
case 1:return "采集素材";
case 2:return "素材HR99以下";
case 3:return "汎用素材HR100以上";
case 4:return "装饰品";
case 5:return "其他道具";
default:
return "未定义";
}
}
static ShopItem GetShopItemInfo(byte[] data, int StartPos)
{
int ItemID = -1;
int Point = -1;
int Group = -1;
bool UnKnow = false;
try
{
ItemID = HexHelper.bytesToInt(data, 4, StartPos);
Point = HexHelper.bytesToInt(data, 4, StartPos + 4);
Group = HexHelper.bytesToInt(data, 1, StartPos + 4 + 4);
UnKnow = false;
}
catch(Exception ex)
{
Console.WriteLine($"获取错误"+ex.ToString());
UnKnow = true;
}
ShopItem item = new ShopItem()
{
Ptr = StartPos,
ItemID = ItemID,
Point = Point,
Group = Group,
OtherData = new int[]{ data[StartPos + 4 + 4 + 0],data[StartPos + 4 + 4 + 1], data[StartPos + 4 + 4 + 2], data[StartPos + 4 + 4 + 3] },
UnKnow = UnKnow
};
return item;
}
struct ShopItem
{
public int Ptr;
public int ItemID;
public int Point;
public int Group;
public int[] OtherData;
public bool UnKnow;
}
}
}