错误道具批量修复功能

This commit is contained in:
sin365 2025-12-31 13:50:08 +08:00
parent a83c97166c
commit d2d31601e1
6 changed files with 155 additions and 73 deletions

View File

@ -65,7 +65,7 @@ namespace Axibug.MHFSaveAutoConverter.DataStruct
return this.ToString(); return this.ToString();
} }
public virtual bool FixedData(out string log) public virtual bool FixedData(out string log, out bool bneedFixed)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -286,14 +286,17 @@ namespace Axibug.MHFSaveAutoConverter.DataStruct
return str; return str;
} }
public override bool FixedData(out string log) public override bool FixedData(out string log, out bool bneedFixed)
{ {
if (!SrcVerHad) if (!SrcVerHad)
{ {
log = "没有数据"; log = "没有数据";
bneedFixed = false;
return false; return false;
} }
bneedFixed = false;
log = this.GetType().Name + "\r\n"; log = this.GetType().Name + "\r\n";
byte[] itemiddata = new byte[2]; byte[] itemiddata = new byte[2];
byte[] countdata = new byte[2]; byte[] countdata = new byte[2];
@ -318,19 +321,23 @@ namespace Axibug.MHFSaveAutoConverter.DataStruct
if (SrcVer == MHFVer.GG) if (SrcVer == MHFVer.GG)
{ {
bool needfix = (itemid >= 9749); //9579 月光雲
//9583 月光砂
//bool needfix = (itemid >= 9749);
//bool needfix = (itemid >= 9579);
bool needfix = (itemid >= 9498);
if (needfix) if (needfix)
{ {
//抹除数据 //抹除数据
for (int i = 0; i < SrcCfg.block_single_len; i++) for (int i = 0; i < SrcCfg.block_single_len; i++)
data[startptr + i] = 0x00; data[startptr + i] = 0x00;
log += $"抹除数据:[{block}]{itemid}:{MHHelper.Get2MHFItemName((int)itemid)}:{count}\r\n"; log += $"抹除数据:[{block}]{itemid}:道具->{MHHelper.Get2MHFItemName((int)itemid)} | 数量->{count}\r\n";
bneedFixed = true;
} }
} }
} }
return false; return true;
} }
} }

View File

@ -9,7 +9,12 @@
0x20, 0x20, 0x20, 0x00 // " \0" 0x20, 0x20, 0x20, 0x00 // " \0"
}; };
public static byte[] Decompress(byte[] data) /// <summary>
/// 解压
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] Decompress(byte[] data,bool skiplog = false)
{ {
// 检查文件头 // 检查文件头
if (data.Length < 16 || !data.Take(16).SequenceEqual(HeaderBytes)) if (data.Length < 16 || !data.Take(16).SequenceEqual(HeaderBytes))
@ -17,7 +22,9 @@
Console.WriteLine("存档存档无需解压"); Console.WriteLine("存档存档无需解压");
return data; return data;
} }
Console.WriteLine("存档解压");
if(!skiplog)
Console.WriteLine("存档解压");
using var outputStream = new MemoryStream(); using var outputStream = new MemoryStream();
using var reader = new BinaryReader(new MemoryStream(data)); using var reader = new BinaryReader(new MemoryStream(data));
@ -50,6 +57,11 @@
return outputStream.ToArray(); return outputStream.ToArray();
} }
/// <summary>
/// 压缩
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] Compress(byte[] data) public static byte[] Compress(byte[] data)
{ {
using var outputStream = new MemoryStream(); using var outputStream = new MemoryStream();

View File

@ -161,11 +161,13 @@ namespace Axibug.MHFSaveAutoConverter.DataStruct
{nameof(s_CP) ,s_CP.CreateCfg(0x18644)}, {nameof(s_CP) ,s_CP.CreateCfg(0x18644)},
{nameof(s_知名度) ,s_知名度.CreateCfg(0x18648)}, {nameof(s_知名度) ,s_知名度.CreateCfg(0x18648)},
{nameof(s_知名度称号) ,s_知名度称号.CreateCfg(0x1864C)}, {nameof(s_知名度称号) ,s_知名度称号.CreateCfg(0x1864C)},
{nameof(s_pBookshelfData),s_pBookshelfData.CreateCfg(0x11A8,-1)}, //{nameof(s_pBookshelfData),s_pBookshelfData.CreateCfg(0x11A8,-1)},
{nameof(s_pBookshelfData),s_pBookshelfData.CreateCfg(-1,-1)},
{nameof(s_pGalleryData),s_pGalleryData.CreateCfg(0x19680,1748)}, {nameof(s_pGalleryData),s_pGalleryData.CreateCfg(0x19680,1748)},
{nameof(s_pGardenData花园),s_pGardenData花园.CreateCfg(0x19FB8,68)}, {nameof(s_pGardenData花园),s_pGardenData花园.CreateCfg(0x19FB8,68)},
{nameof(s_pRP),s_pRP.CreateCfg(0x1A076)}, {nameof(s_pRP),s_pRP.CreateCfg(0x1A076)},
{nameof(s_pKQF),s_pKQF.CreateCfg(0x1B080,8)}, //{nameof(s_pKQF),s_pKQF.CreateCfg(0x1B080,8)},
{nameof(s_pKQF),s_pKQF.CreateCfg(-1,8)},
/*单个道具长度8byte前20个是item/道具 后10个是ammo/弹药*/ /*单个道具长度8byte前20个是item/道具 后10个是ammo/弹药*/
{nameof(s_ItemPouch背包),s_ItemPouch背包.CreateCfg(0x168C8,8,20/*+10*/)}, {nameof(s_ItemPouch背包),s_ItemPouch背包.CreateCfg(0x168C8,8,20/*+10*/)},
{nameof(s_Keyquestflag),s_Keyquestflag.CreateCfg(-1,8) }, {nameof(s_Keyquestflag),s_Keyquestflag.CreateCfg(-1,8) },

View File

@ -4,7 +4,9 @@ using Npgsql;
using NpgsqlTypes; using NpgsqlTypes;
using System.Data; using System.Data;
using System.Text; using System.Text;
using System.Xml.Linq;
using static Axibug.MHFSaveAutoConverter.DataStruct.MHFSaveDataCfg; using static Axibug.MHFSaveAutoConverter.DataStruct.MHFSaveDataCfg;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Axibug.MHFSaveAutoConverter.Data namespace Axibug.MHFSaveAutoConverter.Data
{ {
@ -28,6 +30,28 @@ namespace Axibug.MHFSaveAutoConverter.Data
savedataparam.Value = targetdata; savedataparam.Value = targetdata;
return SQLRUN_SRC_DB.ExcuteSQL(str, new List<NpgsqlParameter> { savedataparam }); return SQLRUN_SRC_DB.ExcuteSQL(str, new List<NpgsqlParameter> { savedataparam });
} }
public static bool GetAllCharcterOLD(out List<long> cidList)
{
string sql = $"SELECT id,user_id from characters where is_new_character is false";
cidList = new List<long>();
if (SQLRUN_SRC_DB.QuerySQL(sql, out DataTable dt))
{
DataRowCollection RowsData = dt.Rows;
if (RowsData.Count > 0)
{
for (int i = 0; i < RowsData.Count; i++)
{
cidList.Add((Int32)(RowsData[i][0]));
}
return true;
}
else
Console.WriteLine($"未查询到数据");
}
return false;
}
public static bool loadCharacterOLD(long cid, out string name, out bool is_female, out byte[] data) public static bool loadCharacterOLD(long cid, out string name, out bool is_female, out byte[] data)
{ {
string sql = $"SELECT \"name\",savedata,is_female from \"characters\" WHERE id = {cid}"; string sql = $"SELECT \"name\",savedata,is_female from \"characters\" WHERE id = {cid}";
@ -82,21 +106,23 @@ namespace Axibug.MHFSaveAutoConverter.Data
} }
public static bool FixedSaveData(MHFVer from, MHFVer target, byte[] src, out byte[] targetdata, out string err) public static bool FixedSaveData(MHFVer from, MHFVer target, byte[] src, out byte[] targetdata, out bool needfixed, out string err, bool skiplog = false)
{ {
try try
{ {
byte[] decdata = MHFCompression.Decompress(src); byte[] decdata = MHFCompression.Decompress(src, skiplog);
SaveDataEntity se = new SaveDataEntity(from, target, decdata); SaveDataEntity se = new SaveDataEntity(from, target, decdata, false);
targetdata = se.FixedEquipBox(decdata, out string log); bool ret = se.FixedEquipBox(decdata, out string log, out targetdata, out needfixed);
err = default; err = log;
Console.WriteLine(log); if(needfixed)
return true; Console.WriteLine(log);
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
err = ex.ToString(); err = ex.ToString();
targetdata = default; targetdata = default;
needfixed = false;
return false; return false;
} }
} }

View File

@ -10,7 +10,7 @@ namespace Axibug.MHFSaveAutoConverter.DataStruct
public MHFVer FromVer; public MHFVer FromVer;
public MHFVer TargetVer; public MHFVer TargetVer;
public List<s_Base> saveHandles = new List<s_Base>(); public List<s_Base> saveHandles = new List<s_Base>();
public SaveDataEntity(MHFVer from, MHFVer target, byte[] data) public SaveDataEntity(MHFVer from, MHFVer target, byte[] data, bool bOutReadLog = true)
{ {
FromVer = from; FromVer = from;
TargetVer = target; TargetVer = target;
@ -36,17 +36,21 @@ namespace Axibug.MHFSaveAutoConverter.DataStruct
Console.WriteLine($"处理 {className} 时出错: {ex.Message}"); Console.WriteLine($"处理 {className} 时出错: {ex.Message}");
} }
} }
Console.WriteLine("====读取====");
foreach (var singledata in saveHandles) if (bOutReadLog)
{ {
Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("====读取====");
Console.WriteLine(singledata.GetType().Name);
Console.ForegroundColor = ConsoleColor.White; foreach (var singledata in saveHandles)
string str = singledata.ToString(); {
if (str.Length > 100) Console.ForegroundColor = ConsoleColor.Yellow;
str = str.Substring(0, 100) + "..."; Console.WriteLine(singledata.GetType().Name);
Console.WriteLine(str); Console.ForegroundColor = ConsoleColor.White;
string str = singledata.ToString();
if (str.Length > 100)
str = str.Substring(0, 100) + "...";
Console.WriteLine(str);
}
} }
} }
public byte[] DoConvert() public byte[] DoConvert()
@ -74,31 +78,38 @@ namespace Axibug.MHFSaveAutoConverter.DataStruct
public byte[] FixedEquipBox(byte[] srcdata, out string log) public bool FixedEquipBox(byte[] srcdata, out string log, out byte[] targetdata, out bool needfixed)
{ {
log = null; log = null;
byte[] targetdata = srcdata.ToArray(); targetdata = srcdata.ToArray();
needfixed = false;
Console.WriteLine("====尝试开始写入====");
foreach (var singledata in saveHandles) foreach (var singledata in saveHandles)
{ {
if (!(singledata is s_Itembox itembox)) if (!(singledata is s_Itembox itembox))
continue; continue;
itembox.FixedData(out log); if (!itembox.FixedData(out log, out bool _bneedFixed) || !_bneedFixed)
continue;
//Console.WriteLine("====尝试开始写入====");
needfixed = true;
Console.ForegroundColor = ConsoleColor.Yellow; Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(singledata.GetType().Name); Console.WriteLine(singledata.GetType().Name);
Console.ForegroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.White;
string str = singledata.ToString(); //string str = singledata.ToString();
if (str.Length > 100) //if (str.Length > 100)
str = str.Substring(0, 100) + "..."; // str = str.Substring(0, 100) + "...";
bool ret = singledata.Write(TargetVer, targetdata); bool ret = singledata.Write(TargetVer, targetdata);
Console.WriteLine($"写入:{singledata.GetType().Name} =>{(ret ? "" : "")}"); //Console.WriteLine($"写入:{singledata.GetType().Name} =>{(ret ? "写人成功" : "写入失败")}");
Console.WriteLine(str); //Console.WriteLine(str);
} }
Console.WriteLine("====写入完毕===="); if (needfixed)
return targetdata; {
//Console.WriteLine("====写入完毕====");
}
return true;
} }
} }

View File

@ -1,12 +1,6 @@
using Axibug.MHFSaveAutoConverter.Data; using Axibug.MHFSaveAutoConverter.Data;
using Axibug.MHFSaveAutoConverter.DataStruct;
using Axibug.MHFSaveAutoConverter.SQL;
using HaoYue.MHFUserSrv.Server.Common; using HaoYue.MHFUserSrv.Server.Common;
using MonsterHunterSaveBruteForce;
using Npgsql;
using NpgsqlTypes;
using System; using System;
using System.Runtime.ConstrainedExecution;
using System.Text; using System.Text;
using static Axibug.MHFSaveAutoConverter.DataStruct.MHFSaveDataCfg; using static Axibug.MHFSaveAutoConverter.DataStruct.MHFSaveDataCfg;
@ -95,6 +89,7 @@ namespace Axibug.MHFSaveAutoConverter
Console.WriteLine("输入有误"); Console.WriteLine("输入有误");
continue; continue;
} }
Console.WriteLine("===>操作的角色ID:" + cid); Console.WriteLine("===>操作的角色ID:" + cid);
if (!SaveDataCoverter.loadCharacterOLD(cid, out string name, out bool is_female, out byte[] srcdata)) if (!SaveDataCoverter.loadCharacterOLD(cid, out string name, out bool is_female, out byte[] srcdata))
{ {
@ -154,7 +149,7 @@ namespace Axibug.MHFSaveAutoConverter
MHFVer src; MHFVer src;
while (true) while (true)
{ {
Console.WriteLine("Step1.选择要继承的角色的原始MHF版本: Select the original MHF version of the character you want to inherit:"); Console.WriteLine("Step1.选择要修复的角色的原始MHF版本: Select the original MHF version of the character you want to inherit:");
for (int i = 0; i < verlist.Length; i++) for (int i = 0; i < verlist.Length; i++)
Console.WriteLine($"[{i}]{verlist[i]}"); Console.WriteLine($"[{i}]{verlist[i]}");
@ -174,19 +169,74 @@ namespace Axibug.MHFSaveAutoConverter
Console.WriteLine("输入有误"); Console.WriteLine("输入有误");
return false; return false;
} }
Console.WriteLine("===>操作的角色ID:" + cid);
if (cid > 0)
{
return FixedItemBoxByCid(cid, src);
}
else
{
Console.WriteLine("===>输入-1,进行批量操作修复存档y/n");
string tempinput = Console.ReadLine().ToLower();
bool bconvert = false;
if (tempinput == "y")
{
bconvert = true;
}
else if (tempinput != "n")
{
Console.WriteLine("输入有误");
return false;
}
if (!bconvert)
return false;
if (!SaveDataCoverter.GetAllCharcterOLD(out var cidList))
return false;
for (int i = 0; i < cidList.Count; i++)
{
long targetCid = cidList[i];
FixedItemBoxByCid(targetCid, src,true,false);
}
}
return true;
}
public static bool FixedItemBoxByCid(long cid, MHFVer src,bool skiplog = false,bool dontsave = false)
{
if(!skiplog)
Console.WriteLine("===>操作的角色ID:" + cid);
if (!SaveDataCoverter.loadCharacterOLD(cid, out string name, out bool is_female, out byte[] srcdata)) if (!SaveDataCoverter.loadCharacterOLD(cid, out string name, out bool is_female, out byte[] srcdata))
{ {
Console.WriteLine("读取失败"); Console.WriteLine("读取失败");
return false; return false;
} }
if (!SaveDataCoverter.FixedSaveData(src, src, srcdata, out byte[] targetdata, out string err)) if (!SaveDataCoverter.FixedSaveData(src, src, srcdata, out byte[] targetdata, out bool needfixed, out string err, skiplog))
{ {
Console.WriteLine($"处理失败:{err}"); Console.WriteLine($"处理失败:{err}");
return false; return false;
} }
if (needfixed)
Console.WriteLine($"以上属于玩家:cid=>{cid} name=>{name} ");
else
return false;
if (dontsave)
return false;
if (src >= MHFVer.GG)
{
int srcDataLength = targetdata.Length;
//压缩数据
targetdata = DataStruct.MHFCompression.Compress(targetdata);
Console.WriteLine($"压缩数据,长度:{srcDataLength}=>{targetdata.Length}");
}
if (!SaveDataCoverter.UpdateTargetDB_old(cid, targetdata)) if (!SaveDataCoverter.UpdateTargetDB_old(cid, targetdata))
{ {
Console.WriteLine($"处理失败:{err}"); Console.WriteLine($"处理失败:{err}");
@ -196,31 +246,5 @@ namespace Axibug.MHFSaveAutoConverter
Console.WriteLine($"写入玩家{name}修正数据"); Console.WriteLine($"写入玩家{name}修正数据");
return true; return true;
} }
//public static SaveDataEntity SetData(long cid, string name, byte[] srcdata)
//{
// string path = $"savedata_cid_{cid}_{DateTime.Now.ToString("yyyyMMddHHmmss")}" + "_解密.bin";
// byte[] decdata = MHFCompression.Decompress(srcdata);
// SaveDataEntity se = new SaveDataEntity(MHFVer.FW5, MHFVer.GG, decdata);
// //SaveDataEntity se = new SaveDataEntity(MHFVer.GG, MHFVer.GG, decdata);
// System.IO.File.WriteAllBytes(path, decdata);
// Console.WriteLine($"角色数据{name},已保存数据到{path}");
// Console.WriteLine($"是否升级存档到MHFGG");
// if (Console.ReadLine().ToLower() == "y")
// {
// string updateoutpath = $"升级GG_savedata_cid_{cid}_{DateTime.Now.ToString("yyyyMMddHHmmss")}" + "_已修改.bin";
// byte[] updatedata = se.DoConvert();
// System.IO.File.WriteAllBytes(updateoutpath, updatedata);
// //Console.WriteLine($"是否验证数据是否正确?");
// //if (Console.ReadLine().ToLower() == "y")
// //{
// // new SaveDataEntity(MHFVer.GG, MHFVer.GG, updatedata);
// //}
// }
//}
} }
} }