实际上,我对C++非常陌生,尽管我以前用Java编程过。您认为我有什么方法可以提高可读性、可维护性和性能,并使其更面向对象吗?
/*
Control + 0 = enable aimbot
*/
#include "stdafx.h"
#include <math.h>
const float pi = 3.14159265358979f;
/*
* I am using int* as if it were the same thing as int**, int***, etc.
* Another more elegant looking method is to use int as if it were int*, int**, etc
* but it is more prone to undefined behaviour and I am more likely to get away with the first method.
* See: http://stackoverflow.com/questions/16256158/dereferencing-a-double-level-pointer-results-in-different-behaviour-from-derefer
*/
int* getClosestPointer(int** basePointer, int offsets[], int levels) {
for (int i = 0; i < levels; i++) {
basePointer = (int**) (*basePointer + offsets[i] / sizeof(int));
}
return (int*) basePointer;
}
/*
[Player base] = A
[A + 34] = X
[A + 38] = Y
[A + 3C] = Z
[A + 40] = Crosshair X
[A + 44] = Crosshair Y
[A + F4] = HP
[A + 154] = Grenades
*/
int playerBaseXOffsets[] = { 0x34 };
int playerBaseYOffsets[] = { 0x38 };
int playerBaseZOffsets[] = { 0x3C };
int playerBaseCXOffsets[] = { 0x40 };
int playerBaseCYOffsets[] = { 0x44 };
int playerBaseHPOffsets[] = { 0xF4 };
int playerBaseAmmoOffsets[] = { 0x368, 0x14, 0 };
int playerBaseGrenadesOffsets[] = { 0x154 };
typedef struct Player {
int** basePointer;
float* xPointer;
float* yPointer;
float* zPointer;
float* cXPointer;
float* cYPointer;
int* hpPointer;
int* ammoPointer;
int* grenadesPointer;
Player() {
}
Player(int** basePtr) {
basePointer = basePtr;
xPointer = (float*) getClosestPointer(basePointer, playerBaseXOffsets, sizeof(playerBaseXOffsets) / sizeof(playerBaseXOffsets[0]));
yPointer = (float*) getClosestPointer(basePointer, playerBaseYOffsets, sizeof(playerBaseYOffsets) / sizeof(playerBaseYOffsets[0]));
zPointer = (float*) getClosestPointer(basePointer, playerBaseZOffsets, sizeof(playerBaseZOffsets) / sizeof(playerBaseZOffsets[0]));
cXPointer = (float*) getClosestPointer(basePointer, playerBaseCXOffsets, sizeof(playerBaseCXOffsets) / sizeof(playerBaseCXOffsets[0]));
cYPointer = (float*) getClosestPointer(basePointer, playerBaseCYOffsets, sizeof(playerBaseCYOffsets) / sizeof(playerBaseCYOffsets[0]));
hpPointer = getClosestPointer(basePointer, playerBaseHPOffsets, sizeof(playerBaseHPOffsets) / sizeof(playerBaseHPOffsets[0]));
ammoPointer = getClosestPointer(basePointer, playerBaseAmmoOffsets, sizeof(playerBaseAmmoOffsets) / sizeof(playerBaseAmmoOffsets[0]));
grenadesPointer = getClosestPointer(basePointer, playerBaseGrenadesOffsets, sizeof(playerBaseGrenadesOffsets) / sizeof(playerBaseGrenadesOffsets[0]));
}
} Player;
Player players[32] = { };
/* Pythagorean's theorem (flavour for 3D) */
float getDistanceBetween(Player one, Player two) {
return sqrt(
(*(one.xPointer)-*(two.xPointer))*(*(one.xPointer)-*(two.xPointer))
+ (*(one.yPointer)-*(two.yPointer))*(*(one.yPointer)-*(two.yPointer))
+ (*(one.zPointer)-*(two.zPointer))*(*(one.zPointer)-*(two.zPointer))
);
}
int getNumberOfPlayers() {
return *((int*) ((UINT) GetModuleHandleW(0) + 0xE4E10));
}
Player* getClosestTarget() {
float smallestDistance;
int index = -1;
for (int i = 1; i < getNumberOfPlayers(); i++) {
if (*(players[i].hpPointer) > 0) {
float tempDistance = getDistanceBetween(players[0], players[i]);
if (index == -1 || tempDistance < smallestDistance) {
smallestDistance = tempDistance;
index = i;
}
}
}
if (index == -1) {
return NULL;
} else {
return &players[index];
}
}
/* Gets the crosshair horizontal angle in degrees. */
float getCX(Player me, Player target) {
float deltaX = *(target.xPointer) - *(me.xPointer);
float deltaY = *(me.yPointer) - *(target.yPointer);
if (*(target.xPointer) > *(me.xPointer) && *(target.yPointer) < *(me.yPointer)) {
return atanf(deltaX/deltaY) * 180.0f / pi;
} else if(*(target.xPointer) > *(me.xPointer) && *(target.yPointer) > *(me.yPointer)) {
return atanf(deltaX/deltaY) * 180.0f / pi + 180.0f;
} else if(*(target.xPointer) < *(me.xPointer) && *(target.yPointer) > *(me.yPointer)) {
return atanf(deltaX/deltaY) * 180.0f / pi - 180.0f;
} else {
return atanf(deltaX/deltaY) * 180.0f / pi + 360.0f;
}
}
/* Gets the crosshair vertical angle in degrees. */
float getCY(Player me, Player target) {
float deltaZ = *(target.zPointer) - *(me.zPointer);
float dist = getDistanceBetween(me, target);
return asinf(deltaZ/dist) * 180.0f / pi;
}
int main() {
bool aimbotEnabled = false;
Player* closestTargetPointer = NULL;
// [Base + DF73C] = Player 1 base
players[0] = Player((int**) ((UINT) GetModuleHandleW(0) + 0xDF73C));
int** extraPlayersBase = *((int***) ((UINT) GetModuleHandleW(0) + 0xE5F00));
while (true) {
// [Base + E5F00] = A
// [A + 0,4,8...] = Player 2/3/4... base
for (int i = 0; i < getNumberOfPlayers() - 1; i++) {
players[i + 1] = Player(extraPlayersBase + i * 4 / sizeof(int*));
}
if (GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState('0')) {
aimbotEnabled = !aimbotEnabled;
Sleep(500);
}
if (aimbotEnabled) {
closestTargetPointer = getClosestTarget();
if (closestTargetPointer != NULL) {
*(players[0].cXPointer) = getCX(players[0], *closestTargetPointer);
*(players[0].cYPointer) = getCY(players[0], *closestTargetPointer);
}
}
Sleep(10);
}
}
DWORD WINAPI Main(LPVOID lpParam) {
main();
return S_OK;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
CreateThread(NULL, 0, &Main, NULL, 0, NULL);
}
return TRUE;
}发布于 2013-07-30 03:48:50
你的C++很像C。首先,我要利用C++:
std::vector而不是数组。例如: std::vector播放器;players.reserve( 32 );这将创建一个足以容纳32 Players的向量。如果您需要更多的空间,当您添加更多的玩家时,该向量将自动增长。通过使用players.at(index)访问元素,您将得到范围检查。要获取vector中的元素数,可以使用players.size()而不是使用sizeof数组除法。struct类型胡枝子是C中的一个常见成语,因为在C中,需要用struct限定struct标识符才能使用它们:void foo(struct Bacon* bacon)。在C++中,您不必这样做。因此,我将把您对Player的定义更改为: class Player { public: // contents };Player中的变量。这意味着它们应该在类的private部分中定义(在public:之上)。如果您需要访问其他函数或类中的变量,则可以提供访问器函数: class Player { int** basePointer;public: int** getBasePointer() const {返回basePointer;};struct作为吊舱,我建议您在需要时制作成员const并复制一份。这不是必须的,但却减少了发生意外变化的可能性。struct是类)可以而且很可能应该像类一样设计,而不是像POD那样设计。enum作为偏移量:枚举偏移量{ playerBaseXOffset = 0x34,playerBaseYOffset = 0x38 /* . */ };如果希望以后有更多的偏移量,则使用std::vector:std::vector playerBaseXOffsets{ 0x34 };// C++11语法。注意最后一个示例中的{和}。使用(和)代替编译,但意味着完全不同的东西!(它将默认构造0x34 =52个对象。)player_one_base_offset比0xDF73C更可读性和可理解性。static_cast<type>(object),而不是C风格的(type)object转换,但在您的情况下,我认为它只会降低可读性而不会带来太大的好处。最后,与代码无关的是:要么是毕达哥拉斯定理,要么是毕达哥拉斯定理。
发布于 2013-07-29 22:49:13
<cmath>而不是<math.h>。classes,这看起来更好,功能也更好,特别是因为它是一款游戏。例如,Player可以变成类而不是struct,这样就可以保持private。还应该有一个Game类来保存玩家的集合并处理游戏。您只需通过创建一个game在main()中启动游戏。请注意,main()不应该访问游戏中超出启动能力的任何内容。std::vector of Players的观点,这也允许您使用容器的迭代器访问每个玩家。如果有C++11,则有两个选项,取决于编译器是否支持基于范围的for-循环:如果它支持.用于(auto & player :player){ std::cout << player;}如果它没有.对于(auto = players.cbegin();iter != players.cend();++iter) { std::cout << * iter;}在您的游戏中,您将只对游戏类中的这个向量进行操作。这一点很重要,因为它不应该通过接口公开。您可以自由地定义显示函数(或重载operator<<),但不能破坏封装。getCX()和getCY()中的参数应该是const-ref,因为它们没有修改: float getCX(Player const& me,Player const& target) {} float getCY(Player const& me,Player const& target) {}playerBaseOffsets看起来应该是const。我还喜欢比单个数组更简洁的东西,比如enum。还可以将其放入namespace中以避免名称冲突。nullptr而不是NULL,则使用C++11。<cstddef>以便使用std::size_t。https://codereview.stackexchange.com/questions/26503
复制相似问题