最近一直沉迷造房子,可惜的时一个人造房子挺累,有些物资收集挺麻烦。考虑到自己不愿意用wemod或者其他作弊工具,只是想简单改一下背包物资信息,所以自行写了一下修改工具!
工具不需要游戏启动,只是改动了电脑上的游戏存档!可以放心使用。
软件使用aardio编写,可能会有报毒提示,代码也会贴出来,能动手的朋友自行修改。
软件界面如下:

软件下载附件在这里:
https://wwmz.lanzout.com/b01qhq8la
密码:1zmv
继续贴代码部分,懂得人一看就明白了,物品ID也在这里:
import win.ui;
import win.dlg.message;
import godking.vlistEx;
/*DSG{{*/
mainForm = win.form(text="森林之子存档修改工具";right=531;bottom=635;border="dialog frame";max=false)
mainForm.add(
button={cls="button";text="1.读取存档";left=106;top=23;right=210;bottom=57;z=3};
button2={cls="button";text="2.保存存档";left=359;top=23;right=463;bottom=57;z=5};
groupbox={cls="groupbox";text="读取存档";left=9;top=9;right=264;bottom=549;edge=1;z=2};
groupbox2={cls="groupbox";text="修改保存存档";left=269;top=9;right=524;bottom=548;edge=1;z=1};
static={cls="static";text="Static";left=9;top=558;right=521;bottom=629;color=16711680;transparent=1;z=7};
tips1={cls="static";left=28;top=59;right=253;bottom=75;align="center";color=255;transparent=1;z=8};
tips2={cls="static";left=277;top=61;right=508;bottom=77;align="center";color=255;transparent=1;z=9};
vlist1={cls="vlistEx";text="自定义控件";left=27;top=81;right=254;bottom=539;border=1;edge=1;z=4};
vlist2={cls="vlistEx";text="自定义控件";left=275;top=82;right=514;bottom=537;border=1;edge=1;z=6}
)
/*}}*/
import yang;
import config;
import yang.config;
import fsys;
import process;
import godking
ITEM_TAB1 = {
["01.拉面"] = 421;
["02.能量饮料"] = 439;
["03.早餐零食"] = 425;
["04.即食粮食"] = 438;
["05.药品"] = 437;
["06.巧克力"] = 441;
["07.伏特加酒瓶"] = 414;
["11.手枪子弹"] = 362;
["12.铅弹"] = 364;
["13.霰弹"] = 363;
["14.手雷"] = 381;
["15.燃烧瓶"] = 388;
["16.定时炸弹"] = 417;
["17.C4炸弹块"] = 420;
["18.照明弹"] = 440;
["19.十字弩箭"] = 368;
["21.钢索"] = 523;
["22.钩爪"] = 560;
["23.钢线"] = 418;
["24.布"] = 415;
["25.树枝"] = 392;
}
mainForm.static.text = ` 1、软件不修改程序内存,不属于修改器类程序
2、修改存档后需要重新读档,重要物品不修改,请自行获取(枪等)
3、修改存档时,会自动备份原存档文件到目录Backup中
`
mainForm.tips1.text = "首先点击按钮获取本机游戏存档!"
mainForm.tips2.text = "双击数量进行修改!"
global.onError = function( err,over ){
if(!over){
yang.wlog(tostring(err))
}
if( _STUDIO_INVOKED ) return err;
}
mainForm.text = mainForm.text ++ " V:" ++ yang.version ++ " @ " ++_BUILD_TIME;
mainForm.button.oncommand = function(id,event){
save_path = getAppdata("\LocalLow\Endnight\SonsOfTheForest\Saves");
mainForm.tips1.text = "正在获取存档..."
tab = {fields={"存档类型","存档时间","路径"}};
//console.dump(save_path)
fsys.enum( save_path, "*.*",
function(dir,filename,fullpath,findData){
if(filename=="PlayerInventorySaveData.json"){
sss = string.load(fsys.joinpath(dir,"GameStateSaveData.json"));
data1 = web.json.tryParse(sss);
data2 = web.json.tryParse(data1[['Data']][['GameState']]);
write_time = tostring(time(data2[['SaveTime']]))
if(string.indexOf(fullpath,"SinglePlayer")){
tmp = {
存档类型 = "个人存档";存档时间 = write_time;路径 = fullpath;
}
}
if(string.indexOf(fullpath,"MultiplayerClient")){
tmp = {
存档类型 = "多人存档";存档时间 = write_time;路径 = fullpath;
}
}
table.push(tab,tmp);
}
}
,/*如果此参数为false则忽略子目录*/
);
..table.sortEx(tab,2,1,0/*数据转换*/)
mainForm.vlist1.setTable(tab,/*标题或数组*/,{80,-1,0}/*列宽或数组*/,/*列格式或数组*/,/*字典转为数组*/,/*字符串转为Utf8*/)
mainForm.tips1.text = "共找到【"++#tab++"】份存档,双击选择!"
}
change_data = function(alltab,key,value){
if(!key or !value) return alltab;
allnum = #alltab;
data2 = alltab;
exist = false
for(i=1;allnum;1){
if(data2[i][['ItemId']]==key){
data2[i][['TotalCount']] = value;
exist = true;
}
}
if(exist == false){
///表示遍历的时候不存在啊
tmp = {
"ItemId" = key,
"TotalCount" = value,
"UniqueItems" = table.array()
}
..table.push(data2,tmp);
}
return data2;
}
FILE_PATH = null;
mainForm.vlist2.bkColor2 = 0xA6FFEC;
mainForm.vlist1.bkColor2 = 0xA6FFEC;
read_data = function(row){
/*鼠标左键双击项目事件。此事件会在onEditBegin前触发。*/
if(!row)return;
path = mainForm.vlist1.getItemText(row,3);
if(!path) return;
sss = string.load(path);
save_path = "";
//1、解析初始文本
s1 = web.json.tryParse(sss)
//2、获取用户信息
data = s1[["Data"]][['PlayerInventory']];
//3、格式化用户信息
s2 = web.json.tryParse(data);
//4、获取物品信息
data2 = s2[['ItemInstanceManagerData']][['ItemBlocks']];
FILE_PATH = path;
tab = {fileds={"物品","数量"}}
for k,v in ITEM_TAB1{
tmp = {物品 = k;数量=0;id=v;}
for(i=1;#data2;1){
if(data2[i][['ItemId']]==v){
tmp['数量'] = data2[i][['TotalCount']];
//console.dump(data2[i][['UniqueItems']])
}
}
table.push(tab,tmp)
}
..table.sortEx(tab,3,0,0/*数据转换*/)
mainForm.vlist2.setTable(tab,{"物品","数量"}/*标题或数组*/,{100,100}/*列宽或数组*/,/*列格式或数组*/,/*字典转为数组*/,/*字符串转为Utf8*/)
mainForm.vlist2.setColumnAlign(2,2)
}
mainForm.vlist2.onSortColumn = function(col,desc){
/*点击列标题进行排序。col:列号,从1开始。desc:是否倒序。返回true重置标题栏排序图标*/
import godking
..table.sortEx(owner.getTable(),col,desc,0/*数据转换*/)
owner.update()
return true;
}
save_data = function(){
/*鼠标左键双击项目事件。此事件会在onEditBegin前触发。*/
if(!FILE_PATH)return;
dir = fsys.createDir("/Backup/")
dir = fsys.createDir("/Backup/"++tostring(time(,"%Y-%m-%d %H-%M-%S")));
fsys.copy(FILE_PATH,dir)
sss = string.load(FILE_PATH);
save_path = "";
//1、解析初始文本
s1 = web.json.tryParse(sss)
//2、获取用户信息
data = s1[["Data"]][['PlayerInventory']];
//3、格式化用户信息
s2 = web.json.tryParse(data);
//4、获取物品信息
data2 = s2[['ItemInstanceManagerData']][['ItemBlocks']];
//修改数据
tabdata = mainForm.vlist2.getTable();
for(i=1;#tabdata;1){
k = tonumber(tabdata[i][['id']]);
v = tonumber(tabdata[i][['数量']]);
data2 = change_data(data2,k,v);
}
//赋值返回
s2[['ItemInstanceManagerData']][['ItemBlocks']] = data2;
ddd = web.json.stringify(s2);
//ddd = string.replace(ddd,"@{}","[]")
s1[["Data"]][['PlayerInventory']] = ddd;
res = web.json.stringify(s1);
string.save(FILE_PATH, res);
mainForm.msgOk("修改完成!请重新读档!",3000)
}
mainForm.vlist1.onDblClick = function(row/*行*/,col/*列*/){
read_data(row)
}
mainForm.vlist2.onEditBegin = function(row/*行*/,col/*列*/){
/*鼠标双击单元格进行编辑,返回true允许编辑,否则禁止编辑。
不定义此事件,则默认不允许编辑。此事件会在onDblClick后触发。*/
if(col==2) return true;
return false;
}
mainForm.button2.oncommand = function(id,event){
//console.dump(mainForm.vlist2.getTable())
save_data()
}
mainForm.show();
return win.loopMessage();