关于修改浴火银河2全高清硬盘版

我记得2013年的时候 写过一个修改欲火银河2HD的飞船数据的文章

飞船数据是ships.bin这几天心烦又偷偷玩了一下,又想改装备items.bin,然后时间少不想自己研究

于是看了下别人怎么改,确实有人改,但是写出来乱七八糟,也可能是自己的文档习惯不同吧

于是:


欲火银河2全高清硬盘版

Galaxy on Fire 2™ Full HD


不说那么多,二进制打开items.bin文件:

关于修改浴火银河2全高清硬盘版_第1张图片

出于偷懒,我写了个程序查找0-1-2-3-...这样的偏移,以得到固定的存储空间,实际上不存在

稍微观察一下也不难发现,红色箭头所示,总是有0x00000000 0x00000000 0xXXXXXXXX 这样的三个DWORD

再看第一个红色箭头,值是0x1E000000,转换为x86字节序是0x0000001E,十进制的30,数一下选中部分的DWORD数量

正好也是30,再看绿色箭头不难看出,总是一个DWORD+一个DWORD这样一对一对的奸夫淫妇

而且,第一个DWORD为零时,第二个DWORD是0,1,2,3...这样递增的,像飞船的存储方式,可以认为是ID

那么暂定为非固定大小结构体:

typedef struct _tagValue{
	DWORD Flags;					// property flags
	DWORD Value;					// property value
} VALUE, *PVALUE;

typedef struct _tagEquipment{		// "items.bin"
	union {
		struct {
			DWORD Reserved1;		// 0x00000000
			DWORD Reserved2;		// 0x00000000
			DWORD NumOfDWORD;		// how many dwords followed
			VALUE Values[1];
		};
		DWORD Dummy[1];
	};
} EQUIP, *PEQUIP;

说到这里应该可以自己写程序编辑这些bin了吧

算了,贴上DLL部分的代码,也好做备份,有空的时候传到资源,大家有需要的就狠狠的下吧

(目前仅限修改飞船和物品)

1.gof2.h

// ****************************************************************************************************
// 文件: GOF2\\gof2.h
// 作者: 虎胆游侠(blog.csdn.net/prsniper; [email protected])
// 时间: 2015-11-13 05:45:21
// 注释:
// 这只是一个.h文件, 用力包含吧
// ****************************************************************************************************
#ifndef __GOF2HD_H_
#define __GOF2HD_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifdef __GOF2HD_DLL_INC_
#define __V32_DLL_API_		// 内部编译标识
#endif

#include "v32_prefix.h"		// 预编译宏, 切换内外部编译

// auto include
#include "v32_api.h"

#include "types.h"

// exports
V32API int __stdcall CacheOpen(const char *szFileName);
V32API int __stdcall CacheSave(const char *szFileName, int bRelease);
V32API int __stdcall GetSpace(DWORD dwSpaceId, PSHIPS *ppShips);
V32API int __stdcall GetShipValue(PSHIPS pShips, int dwIndex, DWORD *pdwValue);
V32API int __stdcall SetShipValue(PSHIPS pShips, int dwIndex, DWORD dwValue);
V32API int __stdcall GetItem(DWORD dwIndex, PEQUIP *ppItem);
V32API int __stdcall GetItemValue(PEQUIP pItem, int dwIndex, DWORD *pdwValue);
V32API int __stdcall SetItemValue(PEQUIP pItem, int dwIndex, DWORD dwValue);

#include "v32_subfix.h"		// 预编译宏, 切换内外部编译

#endif

2.types.h

// ****************************************************************************************************
// 文件: GOF2\\types.h
// 作者: 虎胆游侠(blog.csdn.net/prsniper; [email protected])
// 时间: 2015-11-13 05:35:15
// 注释:
// 类型定义
// ****************************************************************************************************
#ifndef __GOF2HD_TYPE_H_
#define __GOF2HD_TYPE_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//typedef unsigned long		ThisIsAFuckingType;
//typedef unsigned long		FuckYouAndYourMotherFatherSisterYourSonAndYourDaughter;
//typedef unsigned long		DWORD;
//typedef unsigned long		DOUBLEWORD;
//typedef unsigned long		DWORD;
//typedef unsigned long		DWORD;
//typedef unsigned long		DWORD;
//typedef unsigned long		DWORD;
//typedef unsigned int		DWORD;	// Multiple typedef alias type is legal, but this one
typedef unsigned long		DWORD;
typedef unsigned char		BYTE;

// Begin type definitions
#pragma pack(1)
typedef struct _tagUnits{
	union {
		struct {
			BYTE Byte1;
			BYTE Byte2;
			BYTE Byte3;
			BYTE Byte4;
		};
		DWORD Value;
	};
} UNITS, *PUNITS;
#pragma pack()

typedef struct _tagValue{
	DWORD Flags;					// property flags
	DWORD Value;					// property value
} VALUE, *PVALUE;

typedef struct _tagEquipment{		// "items.bin"
	union {
		struct {
			DWORD Reserved1;		// 0x00000000
			DWORD Reserved2;		// 0x00000000
			DWORD NumOfDWORD;		// how many dwords followed
			VALUE Values[1];
		};
		DWORD Dummy[1];
	};
} EQUIP, *PEQUIP;

typedef struct _tagShips{			// "ships.bin"
	union {
		struct {
			DWORD Identifier;		// spaceship id
			DWORD Capacity;			// HP
			DWORD Volume;			// cargo hold space
			DWORD Price;			// standard price
			DWORD Primary;			// max 1st weapon count
			DWORD Secondary;		// max 2nd weapon count
			DWORD Turret;			// max turret count
			DWORD Equipment;		// equipment capacity
			DWORD Operation;		// operability
		};
		DWORD Dummy[1];
	};
} SHIPS, *PSHIPS;
// End type definitions

#include "v32_subfix.h"		// 预编译宏, 切换内外部编译

#endif

3.gof2.cpp

// ****************************************************************************************************
// 文件: GOF2\\gof2.cpp
// 作者: 虎胆游侠(blog.csdn.net/prsniper; [email protected])
// 时间: 2015-11-13 05:50:05
// 注释:
// 操作函数
// ****************************************************************************************************
#include <stdio.h>
#include <malloc.h>
#include "v32_api.h"

//using namespace Valiant;

#define __GOF2HD_DLL_INC_
#include "gof2.h"

void *g_pBuffer = NULL;		// global data
int g_dwCount = 0;			// byte size

// 转换字节序
DWORD fnTurnBytes(DWORD dwNumber)
{
	UNITS u1, u;
	u1.Value = dwNumber;

	u.Byte1 = u1.Byte4;		// dwNumber << 24;	// 低位补零
	u.Byte2 = u1.Byte3;		// (dwNumber << 8) & 0xFF0000;
	u.Byte3 = u1.Byte2;		// (dwNumber >> 8) & 0xFF00;
	u.Byte4 = u1.Byte1;		// (dwNumber >> 24) & 0xFF;

	return u.Value;
}

V32API int __stdcall CacheOpen(const char *szFileName)
{
	FILE *pf;
	long dwSize;
	void *p;

	pf = fopen(szFileName, "rb");
	if(pf == NULL)
	{
		return 0;
	}

	fseek(pf, 0, SEEK_END);
	dwSize = ftell(pf);
	if(dwSize <= 0)
	{
		fclose(pf);
		return -1;
	}

	p = malloc(dwSize);
	if(p == NULL)
	{
		fclose(pf);
		return -2;
	}

	fseek(pf, 0, SEEK_SET);
	fread(p, sizeof(char), dwSize, pf);
	fclose(pf);

	if(g_pBuffer)
	{
		free(g_pBuffer);
		g_pBuffer = p;
		g_dwCount = (int)dwSize;
	}
	return 1;
}

V32API int __stdcall CacheSave(const char *szFileName, int bRelease)
{
	FILE *pf;
	int dwRet;

	if(szFileName != NULL)
	{
		if(g_pBuffer == NULL)
		{
			return 0;
		}
		pf = fopen(szFileName, "wb");
		dwRet = fwrite(g_pBuffer, sizeof(char), g_dwCount, pf);
		fclose(pf);
		if(dwRet != g_dwCount)
		{
			return -1;
		}
	}
	if(bRelease)
	{
		//Valiant::SafeFree(g_pBuffer);
		SafeFree(g_pBuffer);	// using namespace Valiant;
		g_dwCount = 0;
		return 2;
	}
	return 1;
}

V32API int __stdcall GetSpace(DWORD dwSpaceId, PSHIPS *ppShips)
{
	union {
		PSHIPS pShips;
		void *p;
	};
	int dwCount;

	if(ppShips == NULL)
	{
		return 0;
	}

	p = g_pBuffer;
	if(pShips == NULL)
	{
		return -1;
	}

	dwSpaceId = fnTurnBytes(dwSpaceId);
	dwCount = 0;
	while(dwCount < g_dwCount)
	{
		if(pShips->Identifier == dwSpaceId)
		{
			*ppShips = pShips;
			return 1;
		}
		dwCount += sizeof(SHIPS);
		pShips++;
	}
	//if(dwCount >= g_dwCount)
	return -2;	// not found
}

V32API int __stdcall GetShipValue(PSHIPS pShips, int dwIndex, DWORD *pdwValue)
{
	if(pShips == NULL || pdwValue == NULL)
	{
		return 0;
	}
	if(dwIndex >= (sizeof(SHIPS) / sizeof(DWORD)) || dwIndex < 0)
	{
		return -1;
	}
	*pdwValue = fnTurnBytes(pShips->Dummy[dwIndex]);
	return 1;
}

V32API int __stdcall SetShipValue(PSHIPS pShips, int dwIndex, DWORD dwValue)
{
	if(pShips == NULL)
	{
		return 0;
	}
	if(dwIndex >= (sizeof(SHIPS) / sizeof(DWORD)) || dwIndex < 0)
	{
		return -1;
	}
	pShips->Dummy[dwIndex] = fnTurnBytes(dwValue);
	return 1;
}

V32API int __stdcall GetItem(DWORD dwIndex, PEQUIP *ppItem)
{
	union {
		PEQUIP pItem;
		int dwNum;
		char *p1;
		void *p;
	};
	union {
		int dwCount;
		void *pDummy;
	};

	if(ppItem = NULL)
	{
		return 0;
	}

	p = g_pBuffer;
	if(pItem == NULL)
	{
		return -1;
	}

	pDummy = g_pBuffer;
	while(dwIndex)
	{
		p1 += (pItem->NumOfDWORD + 3) * sizeof(DWORD);
		if((dwNum - dwCount) >= g_dwCount)
		{
			return -2;	// not found
		}
		dwIndex--;
	}
	*ppItem = pItem;
	return 1;
}

V32API int __stdcall GetItemValue(PEQUIP pItem, int dwIndex, DWORD *pdwValue)
{
	int dwRet;

	if(pItem == NULL)
	{
		return 0;
	}
	dwRet = (int)fnTurnBytes(pItem->NumOfDWORD) + 3;
	if(pdwValue == NULL)
	{
		return dwRet;
	}
	if(dwIndex >= dwRet || dwIndex < 0)
	{
		return -1;
	}
	*pdwValue = fnTurnBytes(pItem->Dummy[dwIndex]);
	return 1;
}

V32API int __stdcall SetItemValue(PEQUIP pItem, int dwIndex, DWORD dwValue)
{
	int dwRet;

	if(pItem == NULL)
	{
		return 0;
	}
	dwRet = (int)fnTurnBytes(pItem->NumOfDWORD) + 3;
	if(dwIndex >= dwRet || dwIndex < 0)
	{
		return -1;
	}
	pItem->Dummy[dwIndex] = fnTurnBytes(dwValue);
	return 1;
}

4.api.cpp

// ****************************************************************************************************
// 文件: GOF2\\api.cpp
// 作者: 虎胆游侠(blog.csdn.net/prsniper; [email protected])
// 时间: 2015-11-13 06:42:13
// 注释:
// 入口模块
// ****************************************************************************************************
//#include <windows.h>
#include "v32_api.h"

#define __GOF2HD_DLL_INC_
#include "gof2.h"

using namespace Valiant;

#ifdef _DEBUG
#pragma comment(lib, "Debug\\V32.lib")
#else
#pragma comment(lib, "Release\\V32.lib")
#endif

// *** DLL入口函数 ***
//BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
int __stdcall DllMain(VT32 hModule, VT32 ul_reason_for_call, VT32 lpReserved)
{
	//printf("DllMain(%p, %d, %p);\r\n", hModule, ul_reason_for_call, lpReserved);
	switch(ul_reason_for_call.Value32){
	case V32_PROCESS_ATTACH:
	case V32_PROCESS_DETACH:
	case V32_THREAD_ATTACH:		// 线程创建并调用
	case V32_THREAD_DETACH:		// 线程结束并解除
		break;
	default:
		return 0;	// FALSE
	}
	return 1;	// TRUE
}

这里用到了V32.dll基础类库,不过都是memcpy啊之类的自己用汇编写裸函数,同时封装为C++基类,还有一些SafeFree之类的宏定义和类型声明

就这样吧

你可能感兴趣的:(关于修改浴火银河2全高清硬盘版)