Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
 Аватар для dailydose
671 / 217 / 88
Регистрация: 21.07.2016
Сообщений: 1,036
Записей в блоге: 2

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

02.08.2016, 18:57. Показов 1443. Ответов 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, памятью, классами и прочим. А то что пока писал трейнер, выполнил практически все достижения в игре - это чистая случайность
Миниатюры
Нужна конструктивная критика по оформлению и читабельности кода (Game Trainer C++)  
Вложения
Тип файла: zip GameTrainer.zip (285.1 Кб, 6 просмотров)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.08.2016, 18:57
Ответы с готовыми решениями:

Нужна конструктивная критика: советы, замечания по заданному фрагменту кода
Есть входные данные, которые я кладу в вектор 5 1 2 3 4 5 Ваша критика #include &lt;iostream&gt; #include &lt;vector&gt;

Нужна конструктивная критика
Добрый день, форумчане. Я только сегодня начал проходить ООП. С указателями еще не подружился. Если можно, вы можете указать на ошибки,...

Нужна конструктивная критика
Недавно залил сайт (удалено топикстартером). Нужна оценка со стороны, в разделе &quot;СТЕНДЫ&quot; категория &quot;ПРОБКОВЫЕ&quot;. С точки...

7
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
02.08.2016, 20:42
Цитата Сообщение от dailydose Посмотреть сообщение
Хотелось бы узнать мнения опытных пользователей по поводу моей первой программы.
По поводу работы программы, или по поводу её реализации на C++?
1
807 / 534 / 158
Регистрация: 27.01.2015
Сообщений: 3,017
Записей в блоге: 1
02.08.2016, 21:46
dailydose, вы когда писали трейнер, понимали каждую написанную строчку?
Или вы его писали по шаблону чужого кода?
1
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
02.08.2016, 22:16
Цитата Сообщение от dailydose Посмотреть сообщение
Первым делом правится файл settings.h под конкретную игру, а именно указывается процесс игры, заголовок трейнера, и информация об указателях на данные.
Ну вот вам точка развития - сделать так чтобы информация не в settings.h указывалась, а к примеру в sttings.txt (или в settings.ini) - т.е. считывание этих данных без перекомпиляции, причем для любого количества игр, т.е. чтобы тренер сам определял какая игра из известного ему списка запущена. Да кстати, у некоторых игр все эти данные хранятся не в сегмете данных а в куче, т.е. адрес при каждом запуске разный. Как этот вопрос решается?
1
807 / 534 / 158
Регистрация: 27.01.2015
Сообщений: 3,017
Записей в блоге: 1
02.08.2016, 22:27
Fulcrum_013, этот парень находил статический адрес по цепочке указателей через CE
1
 Аватар для dailydose
671 / 217 / 88
Регистрация: 21.07.2016
Сообщений: 1,036
Записей в блоге: 2
03.08.2016, 08:28  [ТС]
Цитата Сообщение от 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
Вот и всё получили указатель, который всегда указывает на адрес жизней.
Миниатюры
Нужна конструктивная критика по оформлению и читабельности кода (Game Trainer C++)  
0
 Аватар для dailydose
671 / 217 / 88
Регистрация: 21.07.2016
Сообщений: 1,036
Записей в блоге: 2
03.08.2016, 08:34  [ТС]
З.Ы. в интернете много есть способов найти указатели на нужный адрес - так что переделать этот трейнер под другую игру не должно вызвать трудностей
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
03.08.2016, 09:49
Цитата Сообщение от dailydose Посмотреть сообщение
в интернете много есть способов найти указатели на нужный адрес
Например перерыть всю кучу и найти нужный ключ. Проходили еще 12 лет назад. Вылез ньюанс - под Win98 US Edition Api дает неправильные адреса. Вроде все читается/пишется и даже ищется но Java-машина в результате крешится, вернее даже не крешится а отваливаются некоторый функционал запущенной из под нее программы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.08.2016, 09:49
Помогаю со студенческими работами здесь

Нужна конструктивная критика подбираемому конфигу ПК
День добрый! Набросал предварительный вариант новой конфигурации ПК, прошу конструктивно покритиковать. Буду рад советам и...

Оцените сборку, пожалуйста! Нужна конструктивная критика
Доброго времени суток! Планирую в ближайшее время брать первый стационарный ПК. Взгляните, пожалуйста, свежим взглядом на сборку...

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

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

Игра "Тетрис" - нужна конструктивная критика
Написал за пару дней упорного и нелегкого постижения F# :) В коде многое не нравится: - бесконечный цикл ожидания ввода клавиши...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru