Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
dailydose
659 / 205 / 88
Регистрация: 21.07.2016
Сообщений: 1,024
Записей в блоге: 2
Завершенные тесты: 1
#1

Нужна конструктивная критика по оформлению и читабельности кода (Game Trainer C++) - C++

02.08.2016, 18:57. Просмотров 464. Ответов 7
Метки нет (Все метки)

Относительно недавно начал изучать C++. Для обучения решил написать трейнер попутно изучая язык/читая необходимую литературу разного рода.

Хотелось бы узнать мнения опытных пользователей по поводу моей первой программы.
Конкретно интересует оформление кода, его читабельность, учитывая мою неопытность наверняка в коде есть места которые можно улучшить...

Полностью исходный код здесь выложить не позволяет форум, ввиду ограничения по количеству вводимых символов в сообщении, поэтому приложил архив во вложения и залил на http://pastebin.com/u/dailydose
Цитата Сообщение от класс трейнер
Цитата Сообщение от Trainer.h
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#pragma once
#ifndef TRAINER_H
#define TRAINER_H
 
#include "lib/Game.h"
 
class Trainer
{
public:
    Trainer();
    ~Trainer();
 
    void start();
 
    static DWORD getProcessIdByName(char* processName);
    static bool gameIsRun();
    static bool trainerIsRun();
 
private:
    enum Msg { MSG_WAIT_FOR_START, MSG_HOTKEYS };
 
    LPSTR sound[3];
    bool bGodMode, bNoReload;
    Game game;
 
    bool gameOnFocus();
    LPSTR getResource(int resourceId);
 
    inline void speech(int type);
 
    static void printMsg(Msg type);
};
 
#endif
Цитата Сообщение от Trainer.cpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#include "lib/config.h"
#include "lib/Trainer.h"
#include "lib/Game.h"
#include "resource.h"
 
Trainer::Trainer()
{
    sound[0] = getResource(SND_OFF);
    sound[1] = getResource(SND_ON);
    sound[2] = getResource(SND_MONEY);
    bGodMode = false;
    bNoReload = false;
    printMsg(MSG_HOTKEYS);
}
 
Trainer::~Trainer(){}
 
void Trainer::start()
{
    while (true)
    {
        // Close Trainer IF GAME is NOT RUNNING
        if (!gameIsRun())
        {
            break;
        }
 
        // Continue IF GAME is not active || PLAYER is DEAD
        if (!gameOnFocus() || game.playerIsDead())
        {
            Sleep(1000);
            continue;
        }
 
        // Rewrite data if FREEZE FLAG enabled
        if (bGodMode)
        {
            game.updatePoints();
        }
        if (bNoReload)
        {
            game.updateAmmo();
        }
 
        // Keyboard handling
        if (GetAsyncKeyState(KEY_GODMODE) & 1)
        {
            bGodMode = !bGodMode;
            game.freezePoints();
            speech(bGodMode);
        }
        if (GetAsyncKeyState(KEY_AMMO) & 1)
        {
            bNoReload = !bNoReload;
            game.freezeAmmo();
            speech(bNoReload);
        }
 
        #ifdef MONEY_EXISTS
        if (GetAsyncKeyState(KEY_MONEY) & 1)
        {
            game.addMoney((TYPE_MONEY)MONEY_AMMOUNT);
            speech(2);
        }
        #endif
        Sleep(50);
    }
}
 
DWORD Trainer::getProcessIdByName(char* processName)
{
    DWORD pid = 0;
 
    // Create toolhelp snapshot.
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);
 
    // Walkthrough all processes.
    if (Process32First(snapshot, &process))
    {
        do
        {
            // Compare process.szExeFile based on format of name, i.e., trim file path
            // trim .exe if necessary, etc.
            if (_stricmp(process.szExeFile, processName) == 0)
            {
                pid = process.th32ProcessID;
                break;
            }
        } while (Process32Next(snapshot, &process));
    }
 
    CloseHandle(snapshot);
    return pid;
}
 
bool Trainer::gameIsRun()
{
    return 0 != getProcessIdByName(GAME_PROCESS);
}
 
bool Trainer::trainerIsRun()
{
    HANDLE mutex = CreateMutex(NULL, TRUE, TRAINER_TITLE);
 
    if (mutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
    {
        HWND existingApp = FindWindow(0, TEXT(TRAINER_TITLE));
        if (existingApp)
        {
            ShowWindow(existingApp, SW_RESTORE);
            SetForegroundWindow(existingApp);
            return true;
        }
    }
 
    SetConsoleTitle(TRAINER_TITLE);
    system("color a");
    printMsg(MSG_WAIT_FOR_START);
 
    return false;
}
 
bool Trainer::gameOnFocus()
{
    DWORD idActive;
    GetWindowThreadProcessId(GetForegroundWindow(), &idActive);
    return idActive == getProcessIdByName(GAME_PROCESS);
}
 
// MSDN.function
LPSTR Trainer::getResource(int resourseId)
{
    HMODULE hInst = GetModuleHandle(NULL);
    if(!hInst)
    {
        return FALSE;
    }  
    LPSTR lpRes; 
    HANDLE hResInfo, hRes; 
 
    // Find the WAVE resource. 
 
    hResInfo = FindResource(hInst, MAKEINTRESOURCE(resourseId), "WAVE");
    if (hResInfo == NULL) 
        return FALSE; 
 
    // Load the WAVE resource. 
 
    hRes = LoadResource(hInst, (HRSRC)hResInfo); 
    if (hRes == NULL) 
        return FALSE; 
 
    // Lock the WAVE resource and play it. 
 
    lpRes = (LPSTR)LockResource(hRes); 
    if (lpRes != NULL)
    {  
        UnlockResource(hRes); 
    } 
 
    // Free the WAVE resource and return success or failure. 
 
    FreeResource(hRes); 
    return lpRes; 
}
 
inline void Trainer::speech(int type)
{
    sndPlaySound(sound[type], SND_MEMORY | SND_ASYNC | SND_NODEFAULT);
}
 
void Trainer::printMsg(Msg type)
{
    system("cls");
    std::cout << std::endl << std::endl << std::endl
        << "\t$$$$$$_$$$$$___$$$$__$$$$$$_$$__$$_$$$$$__$$$$$______________$$$$" << std::endl
        << "\t__$$___$$__$$_$$__$$___$$___$$$_$$_$$_____$$__$$_______$$___$___$$" << std::endl
        << "\t__$$___$$$$$__$$$$$$___$$___$$_$$$_$$$$___$$$$$______$$$$$$___$$$" << std::endl
        << "\t__$$___$$__$$_$$__$$___$$___$$__$$_$$_____$$__$$_______$$___$___$$" << std::endl
        << "\t__$$___$$__$$_$$__$$_$$$$$$_$$__$$_$$$$$__$$__$$_____________$$$$" << std::endl << std::endl
        << "\t\t* * * * * * * * * * * * * * * * * * *"                << std::endl
        << "\t\t* * * * * * * * * * * * * * * * * * *"                << std::endl
        << "\t\t* *                               * *"                << std::endl;
 
    if(type == MSG_WAIT_FOR_START)
    {
        std::cout
            << "\t\t\t Waiting for start:" << std::endl 
            << "\t\t\t " << GAME_PROCESS << std::endl;
    }
    else if(type == MSG_HOTKEYS)
    {
        std::cout
            << "\t\t* *   F" << (KEY_GODMODE - 111) << " - toggle God Mode        * *" << std::endl
            << "\t\t* *   F" << (KEY_AMMO - 111)    << " - toggle No Reload       * *" << std::endl
            << "\t\t* *   F" << (KEY_MONEY - 111)   << " - add 10000$             * *" << std::endl;
    }
 
    std::cout
            << "\t\t* *                               * *" << std::endl
            << "\t\t* * * * * * * * * * * * * * * * * * *" << std::endl
            << "\t\t* * * * * * * * * * * * * * * * * * *" << std::endl;
}
Собственно как оно работает:
Первым делом правится файл settings.h под конкретную игру, а именно указывается процесс игры, заголовок трейнера, и информация об указателях на данные.
Затем если игра не запущена, то ожидает её запуска
Когда игра закрывается, то и сам трейнер прекращает свою работу
Далее в бесконечном цикле каждые 50мс выполняется следующее:
-Проверяем нажатие клавиш: F6 переключает режим бессмертия, F7 - бесконечные патроны, F8 добавляет 10000$
-Проверяем флаги: bGodmode == true ? обновляем текущее количество жизней (и брони, если она есть в игре) на сохраненное, т.е. то которое запомнила программа при нажатии F6; тоже самое и с bNoReload на F7 только с уже с гранатами,патронами в магазине и запасе

З.Ы. Трейнер создавался с целью обучения работать с WinApi, памятью, классами и прочим. А то что пока писал трейнер, выполнил практически все достижения в игре - это чистая случайность
0
Миниатюры
Нужна конструктивная критика по оформлению и читабельности кода (Game Trainer C++)  
Вложения
Тип файла: zip GameTrainer.zip (285.1 Кб, 5 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2016, 18:57
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Нужна конструктивная критика по оформлению и читабельности кода (Game Trainer C++) (C++):

Нужна конструктивная критика: удалось ли мне уловить хоть частицу ООП в моём проекте?
Добрый день, дорогие форумчане. Меня, как и многих, волнует мое будущее, и...

Собственная реализация паттерна "Слушатель" - нужна конструктивная критика
Добрый день, наворотил код по работе с паттерном слушатель - есть класс...

Требуется конструктивная критика
Я не волшебник, только учусь. Для обучения выбрал алгоритм поиска пути A*. Вот...

Поиск популярного триплета. Конструктивная критика
Добрый день. Недавно помогал решать задачу про триплеты, и захотелось услышать...

Повышение уникальности, читабельности и чистоты кода
Хотелось бы услышать предложения, как можно исправить несколько моментов в этом...

Совет по оформлению кода
Есть программа, работает нормально. Обрабатывает из файла двумерный массив и...

7
castaway
Эксперт С++
4926 / 3033 / 453
Регистрация: 10.11.2010
Сообщений: 11,089
Записей в блоге: 10
Завершенные тесты: 1
02.08.2016, 20:42 #2
Цитата Сообщение от dailydose Посмотреть сообщение
Хотелось бы узнать мнения опытных пользователей по поводу моей первой программы.
По поводу работы программы, или по поводу её реализации на C++?
1
Ferrari F1
791 / 521 / 156
Регистрация: 27.01.2015
Сообщений: 3,025
Записей в блоге: 1
Завершенные тесты: 1
02.08.2016, 21:46 #3
dailydose, вы когда писали трейнер, понимали каждую написанную строчку?
Или вы его писали по шаблону чужого кода?
1
Fulcrum_013
Заблокирован
02.08.2016, 22:16 #4
Цитата Сообщение от dailydose Посмотреть сообщение
Первым делом правится файл settings.h под конкретную игру, а именно указывается процесс игры, заголовок трейнера, и информация об указателях на данные.
Ну вот вам точка развития - сделать так чтобы информация не в settings.h указывалась, а к примеру в sttings.txt (или в settings.ini) - т.е. считывание этих данных без перекомпиляции, причем для любого количества игр, т.е. чтобы тренер сам определял какая игра из известного ему списка запущена. Да кстати, у некоторых игр все эти данные хранятся не в сегмете данных а в куче, т.е. адрес при каждом запуске разный. Как этот вопрос решается?
1
Ferrari F1
791 / 521 / 156
Регистрация: 27.01.2015
Сообщений: 3,025
Записей в блоге: 1
Завершенные тесты: 1
02.08.2016, 22:27 #5
Fulcrum_013, этот парень находил статический адрес по цепочке указателей через CE
1
dailydose
659 / 205 / 88
Регистрация: 21.07.2016
Сообщений: 1,024
Записей в блоге: 2
Завершенные тесты: 1
03.08.2016, 08:28  [ТС] #6
Цитата Сообщение от castaway Посмотреть сообщение
По поводу работы программы, или по поводу её реализации на C++?
По поводу реализации. Работоспособность с друзьями тестил на разных играх в сингл-плеере Killing Floor (x86), Killing Floor 2 (x64) - нареканий на данный момент нет.
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
вы когда писали трейнер, понимали каждую написанную строчку?
Когда начинал - нет, с того момента прошло месяц-два. Много копал в интернете как писать в память,читать, как получать информацию о ней(VirtualQueryEx). Где-то даже и готовый участки кода брал, НО, не тупо их копировал а разбирался почему и как, предварительно прочесав MSDN, stackoverflow и прочее.
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Или вы его писали по шаблону чужого кода?
Эм сколько в интернете не искал - везде одно и тоже: Создаём трейнер, ага, делаем форму, на ней кнопочку hack, и функция которая пишет в память WriteProcessMemory по нажатию этой кнопочки - всё.
Исходников полноценных тренеров не находил.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну вот вам точка развития - сделать так чтобы информация не в settings.h указывалась, а к примеру в sttings.txt (или в settings.ini) - т.е. считывание этих данных без перекомпиляции
Эту фичу хотел реализовать, т.е. брать данные о конкретной игре, об указателях на основе конфига, но ничего толкового из этого не вышло - решил оставить всё так как есть.

Цитата Сообщение от Ferrari F1 Посмотреть сообщение
этот парень находил статический адрес по цепочке указателей через CE
Допустим адрес жизней 0x2C3443BC, который каждый раз при перезапуске/смене уровня меняется. Я нахожу указатель на этот адрес и получаю:
["Core.dll" + 0x168A4C] -> 2FE3A000
[2FE3A000 + 0x43C] -> 3D9AAF00
[3D9AAF00 + 0x3C8] -> 2C344000
[2C344000 + 0x3BC] -> 2C3443BC
Вот и всё получили указатель, который всегда указывает на адрес жизней.
0
Миниатюры
Нужна конструктивная критика по оформлению и читабельности кода (Game Trainer C++)  
dailydose
659 / 205 / 88
Регистрация: 21.07.2016
Сообщений: 1,024
Записей в блоге: 2
Завершенные тесты: 1
03.08.2016, 08:34  [ТС] #7
З.Ы. в интернете много есть способов найти указатели на нужный адрес - так что переделать этот трейнер под другую игру не должно вызвать трудностей
0
Fulcrum_013
Заблокирован
03.08.2016, 09:49 #8
Цитата Сообщение от dailydose Посмотреть сообщение
в интернете много есть способов найти указатели на нужный адрес
Например перерыть всю кучу и найти нужный ключ. Проходили еще 12 лет назад. Вылез ньюанс - под Win98 US Edition Api дает неправильные адреса. Вроде все читается/пишется и даже ищется но Java-машина в результате крешится, вернее даже не крешится а отваливаются некоторый функционал запущенной из под нее программы.
0
03.08.2016, 09:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2016, 09:49
Привет! Вот еще темы с решениями:

Массивы, критика кода
Дорогие друзья, такой вопрос что не так в моем коде?#include &lt;iostream&gt;...

Разработал класс Money денежного счета, нужна критика и совет с функцией
Доброго времени суток! Очень прошу помоши, прошу бегло взглянуть на мой...

Небольшой шаблонный класс matrix: комментарии/критика относительно кода с точки зрения правильности написания
В плане своего общего развития написал не большой шаблонный класс matrix. Хочу...

[Нужна критика] Как правильно копировать объект-потомок по ссылке\указателю на родителя? + Пара мелких уточнений
Захотелось провести эксперимент и создать функцию для работы с обёрткой массива...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru