Начинающий
- Статус
- Оффлайн
- Регистрация
- 1 Авг 2024
- Сообщения
- 26
- Реакции
- 0
Этот C++ код предназначен для внедрения различных визуальных эффектов частиц в игровое программное обеспечение, обычно используемое в читах. Он предоставляет функции для создания "частиц попадания" (Hit particles) в заданной позиции, "частиц карты" (Map particles) для глобальных эффектов окружающей среды и трассеров пуль, используя встроенные игровые системы управления частицами. Код динамически находит необходимые функции через сканирование паттернов в CLIENT_DLL (основной клиентской библиотеке игры) и настраивает эффекты, определенные в VPCF-файлах (файлах Valve Particle System), для кастомизации визуального отклика в игре. Это готовые к использованию фрагменты кода для "пастеров" (тех, кто копирует и интегрирует код), желающих добавить такие функции в свой софт (программное обеспечение
bullet_trace.cpp:
#include "bullet_trace.h"
#include "../../../memory/memory.h"
#include <vector>
#include "../../../core/interfaces/interface.h"
#include "../../../sdk/sdk.h"
#include "../../../dependencies/config/Include/config.h"
#include "../../../sdk/game_class/interfaces/i_resource_system.h"
void c_particle_snapshot::draw(int count, void* data)
{
g_memory->CallVFunc<void>(this, 1U, count, data);
}
void c_particle_manager::create_snapshot(c_strong_handle<c_particle_snapshot>* out_particle_snapshot)
{
__int64 nUnknown = 0;
g_memory->CallVFunc<void>(this, 42, out_particle_snapshot, &nUnknown);
}
void c_particle_manager::draw(c_strong_handle<c_particle_snapshot>* particle_snapshot, int count, void* data)
{
g_memory->CallVFunc<void>(this, 43, particle_snapshot, count, data);
}
void c_game_particle_manager_system::create_effect_index(unsigned int* effect_index, particle_effect* effect_data)
{
using fn_t = void(__fastcall*)(c_game_particle_manager_system*, unsigned int*, particle_effect*);
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "40 57 48 83 EC 20 49 8B ?? 48 8B"));
fn(this, effect_index, effect_data);
}
void c_game_particle_manager_system::create_effect2(unsigned int* pEffectIndex, const char* szName)
{
using fn_t = void(__fastcall*)(void*, uint32_t*, const char*, int, int64_t, int64_t, int64_t, int);
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "4C 8B ?? ?? 48 83 ?? ?? 48 8B 84 24 ?? ?? ?? ?? 48 8B DA"));
fn(this, pEffectIndex, szName, 8, 0, 0, 0, 0);
}
void c_game_particle_manager_system::SetEffect(unsigned int effect_index, int unk, void* clr, int unk2)
{
using fn_t = void(__fastcall*)(c_game_particle_manager_system*, unsigned int, int, void*, int);
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "48 89 5C 24 ?? 48 89 74 24 10 57 48 83 EC ?? ?? ?? ?? ?? ?? ?? ?? ?? 41 8B F8 8B DA 4C"));
try {
fn(this, effect_index, unk, clr, unk2);
}
catch (...) {};
}
void c_game_particle_manager_system::fnInitEffect(int effect_index, unsigned int unk, const c_strong_handle<c_particle_snapshot>* particle_snapshot)
{
using fn_t = bool(__fastcall*)(c_game_particle_manager_system*, int, unsigned int, const c_strong_handle<c_particle_snapshot>*);
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "48 89 74 24 10 57 48 83 EC 30 4C 8B D9 49 8B F9 33 C9 41 8B F0 83 FA FF 0F"));
fn(this, effect_index, unk, particle_snapshot);
}
std::vector<tracer_info> forkillexp{};
void cbullet_tracer::spawn_particle_at_position(const vec3_t& position, int ip) {
if (!g_interface->game_particle_manager_system)
{
using fn_t = c_game_particle_manager_system * (__fastcall*)();
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "48 8b 05 ? ? ? ? c3 cc cc cc cc cc cc cc cc 48 89 5c 24 ? 57"));
g_interface->game_particle_manager_system = fn();
}
auto& explosion = forkillexp.emplace_back();
particle_effect particle_effect_{};
switch (ip)
{
case LIGHTING_BLUE:
{
particle_effect_.name = "particles/inferno_fx/molotov_child_flame01b.vpcf";
break;
}
case LIGHTING_PURPLE:
{
particle_effect_.name = "particles/inferno_fx/spark_explosive_test.vpcf";
break;
}
case LIGHTING_GREEN:
{
particle_effect_.name = "bin/lightning_kill_green.vpcf";
break;
}
case PURPLETIME:
{
particle_effect_.name = "bin/purpletime.vpcf";
break;
}
case GREENTIME:
{
particle_effect_.name = "bin/greentime.vpcf";
break;
}
case BLUETIME:
{
particle_effect_.name = "bin/purpletime.vpcf";
break;
}
}
//particle_effect_.name = "particles/ui/xpshop/xpshop_ambient_embers_bright.vpcf";
//particle_effect_.name = "particles/explosions_fx/explosion_c4_ground_residual_ash.vpcf";
particle_effect_.pad[0] = 8;
g_interface->game_particle_manager_system->create_effect_index(&explosion.effect_index, &particle_effect_);
vec3_t flipped_position = position;
g_interface->game_particle_manager_system->SetEffect(explosion.effect_index, 0, &flipped_position, 0);
explosion.particle_data_ = {};
const int grid_size = 10;
explosion.positions = new vec3_t[grid_size * grid_size];
explosion.times = new float[grid_size * grid_size];
float spacing = 500.0f;
int index = 0;
for (int x = 0; x < grid_size; x++)
{
for (int y = 0; y < grid_size; y++)
{
explosion.positions[index] = vec3_t(
position.x + (x - grid_size / 2) * spacing,
position.y + (y - grid_size / 2) * spacing,
-position.z
);
explosion.times[index] = 0.f;
index++;
}
}
explosion.particle_data_.positions = explosion.positions;
explosion.particle_data_.times2 = explosion.times;
g_interface->particle_manager->create_snapshot(&explosion.handle_snapshot_particle);
g_interface->game_particle_manager_system->fnInitEffect(explosion.effect_index, 0, &explosion.handle_snapshot_particle);
g_interface->particle_manager->draw(&explosion.handle_snapshot_particle, grid_size * grid_size, &explosion.particle_data_);
delete[] explosion.positions;
delete[] explosion.times;
}
std::vector<tracer_info> forhitexp{};
void cbullet_tracer::spawn_particle_hit_at_position
(const vec3_t& position, int ip) {
if (!g_interface->game_particle_manager_system)
{
using fn_t = c_game_particle_manager_system * (__fastcall*)();
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "48 8b 05 ? ? ? ? c3 cc cc cc cc cc cc cc cc 48 89 5c 24 ? 57"));
g_interface->game_particle_manager_system = fn();
}
auto& explosion = forhitexp.emplace_back();
particle_effect particle_effect_{};
switch (ip)
{
case BRUTALPOINTS:
{
particle_effect_.name = "particles/inferno_fx/explosion_incen_ground_splash07a.vpcf";
break;
}
case SALUTBRO:
{
particle_effect_.name = "particles/inferno_fx/explosion_incend_air_falling.vpcf";
break;
}
case EXPLOSIONBLUE:
{
particle_effect_.name = "particles/inferno_fx/explosion_molotov_air.vpcf";
break;
}
case EXPLOSIONGREEN:
{
particle_effect_.name = "particles/inferno_fx/explosion_incend_air_fallingfire.vpcf";
break;
}
case EXPLOSIONPURPLE:
{
particle_effect_.name = "particles/critters/chicken/chicken_gone_feathers_fire.vpcf";
break;
}
case EXPLOSION123:
{
particle_effect_.name = "";
break;
}
}
//particle_effect_.name = "particles/ui/xpshop/xpshop_ambient_embers_bright.vpcf";
//particle_effect_.name = "particles/explosions_fx/explosion_c4_ground_residual_ash.vpcf";
particle_effect_.pad[0] = 8;
g_interface->game_particle_manager_system->create_effect_index(&explosion.effect_index, &particle_effect_);
vec3_t flipped_position = position;
g_interface->game_particle_manager_system->SetEffect(explosion.effect_index, 0, &flipped_position, 0);
explosion.particle_data_ = {};
const int grid_size = 10;
explosion.positions = new vec3_t[grid_size * grid_size];
explosion.times = new float[grid_size * grid_size];
float spacing = 500.0f;
int index = 0;
for (int x = 0; x < grid_size; x++)
{
for (int y = 0; y < grid_size; y++)
{
explosion.positions[index] = vec3_t(
position.x + (x - grid_size / 2) * spacing,
position.y + (y - grid_size / 2) * spacing,
-position.z
);
explosion.times[index] = 0.f;
index++;
}
}
explosion.particle_data_.positions = explosion.positions;
explosion.particle_data_.times2 = explosion.times;
g_interface->particle_manager->create_snapshot(&explosion.handle_snapshot_particle);
g_interface->game_particle_manager_system->fnInitEffect(explosion.effect_index, 0, &explosion.handle_snapshot_particle);
g_interface->particle_manager->draw(&explosion.handle_snapshot_particle, grid_size * grid_size, &explosion.particle_data_);
delete[] explosion.positions;
delete[] explosion.times;
}
std::vector<tracer_info> formap{};
void cbullet_tracer::spawn_particle_map_at_position(int ip, Color_t clr_)
{
if (!settings.cfg().visuals.m_mapeffect)
return;
// Ленивая инициализация particle manager system
if (!g_interface->game_particle_manager_system)
{
using fn_t = c_game_particle_manager_system * (__fastcall*)();
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "48 8b 05 ? ? ? ? c3 cc cc cc cc cc cc cc cc 48 89 5c 24 ? 57"));
g_interface->game_particle_manager_system = fn();
}
// Создаём bullet
auto& bullet = formap.emplace_back();
particle_effect effect{};
switch (ip)
{
case SNOWEFFECT:
effect.name = "particles//inferno_fx//explosion_incend_air_falling.vpcf";
break;
case ASHEFFECT:
effect.name = "particles//explosions_fx//explosion_c4_ground_residual_ash.vpcf";
break;
case RAINEFFECT:
effect.name = "particles/rain_fx/ash.vpcf";
break;
case STAREFFECT:
effect.name = "bin/star.vpcf";
break;
default:
return;
}
// Параметр внутри структуры (обычно lifetime или count)
effect.pad[0x30] = 8;
// Позиция спавна (над игроком)
vec3_t pos = { 0.f, 0.f, 160.f };
// Цвет в формате float
particle_color clr = {
float(clr_.r) / 255.f,
float(clr_.g) / 255.f,
float(clr_.b) / 255.f
};
// Инициализация и отрисовка
g_interface->game_particle_manager_system->create_effect_index(&bullet.effect_index, &effect);
g_interface->particle_manager->create_snapshot(&bullet.handle_snapshot_particle);
g_interface->game_particle_manager_system->SetEffect(bullet.effect_index, 16, &clr, 0); // цвет
g_interface->game_particle_manager_system->SetEffect(bullet.effect_index, 1, &pos, 0); // позиция
g_interface->game_particle_manager_system->SetEffect(bullet.effect_index, 0, &pos, 0); // позиция
// Обязательная инициализация данных для draw
bullet.particle_data_.positions = new vec3_t[1]{ pos };
bullet.particle_data_.times2 = new float[1] { 0.0f };
// Отображаем
g_interface->game_particle_manager_system->fnInitEffect(bullet.effect_index, 0, &bullet.handle_snapshot_particle);
g_interface->particle_manager->draw(&bullet.handle_snapshot_particle, 1, &bullet.particle_data_);
}
std::vector<tracer_info> bullets{};
void cbullet_tracer::add_bullet_trace(vec3_t start, vec3_t end, Color_t clr_)
{
if (!g_interface->game_particle_manager_system)
{
try {
using fn_t = c_game_particle_manager_system * (__fastcall*)();
static fn_t fn = reinterpret_cast<fn_t>(g_memory->find_pattern(CLIENT_DLL, "48 8b 05 ? ? ? ? c3 cc cc cc cc cc cc cc cc 48 89 5c 24 ? 57")); //Pattern create CheatEngine
g_interface->game_particle_manager_system = fn();
}
catch (...)
{
}
}
try {
auto& bullet = bullets.emplace_back();
particle_effect particle_effect_{};
particle_effect_.name = "particles/entity/spectator_utility_trail.vpcf";// "particles/entity/spectator_utility_trail.vpcf";
particle_effect_.pad[0] = 8;
g_interface->game_particle_manager_system->create_effect_index(&bullet.effect_index, &particle_effect_);
particle_color clr = { float(clr_.r), float(clr_.g), float(clr_.b) };
g_interface->game_particle_manager_system->SetEffect(bullet.effect_index, 16, &clr, 0);
bullet.particle_data_ = {};
auto dir = (end - start);
auto stage_2 = start + (dir * 0.3f);
auto stage_3 = start + (dir * 0.5f);
vec3_t positions_[] = { start,stage_2, stage_3,end };
for (int i{}; i < sizeof(positions_) / sizeof(vec3_t); i++) {
particle_information particle_info{};
particle_info.time = 4.f;
particle_info.width = 1.5f;
particle_info.unk2 = 1.f;
g_interface->game_particle_manager_system->SetEffect(bullet.effect_index, 3, &particle_info, 0);
bullet.positions = new vec3_t[i + 1];
bullet.times = new float[i + 1];
for (int j{}; j < i + 1; j++) {
bullet.positions[j] = positions_[j];
bullet.times[j] = 0.015625f/*TICK_INTERVAL*/ * float(j);
}
bullet.particle_data_.positions = bullet.positions;
bullet.particle_data_.times2 = bullet.times;
g_interface->particle_manager->create_snapshot(&bullet.handle_snapshot_particle);
g_interface->game_particle_manager_system->fnInitEffect(bullet.effect_index, 0, &bullet.handle_snapshot_particle);
g_interface->particle_manager->draw(&bullet.handle_snapshot_particle, i + 1, &bullet.particle_data_);
delete[] bullet.positions;
delete[] bullet.times;
}
}
catch (...)
{
//L_PRINT(LOG_WARNING) << "HUI TEBE";
}
}
bullet_trace.h:
#pragma once
#include <mutex>
#include "../../../sdk/game_class/strong_handle.h"
#include "../../../sdk/game_class/color.h"
#include "../../../sdk/math/vector.h"
class particle_effect
{
public:
const char* name{};
char pad[0x30]{};
};
class particle_information
{
public:
float time{};
float width{};
float unk2{};
};
class particle_data
{
public:
vec3_t* positions{};
char pad[0x74]{};
float* times{};
void* unk_ptr{};
char pad2[0x28];
float* times2{};
char pad3[0x98];
void* unk_ptr2{};
};
struct particle_color
{
float r;
float g;
float b;
};
class c_particle_snapshot {
public:
void draw(int count, void* data);
};
class c_game_particle_manager_system
{
public:
void create_effect_index(unsigned int* effect_index, particle_effect* effect_data);
void create_effect2(unsigned int* pEffectIndex, const char* szName);
void SetEffect(unsigned int effect_index, int unk, void* clr, int unk2);
void fnInitEffect(int effect_index, unsigned int unk, const c_strong_handle<c_particle_snapshot>* particle_snapshot);
};
class c_particle_manager
{
public:
void create_snapshot(c_strong_handle<c_particle_snapshot>* out_particle_snapshot);
void draw(c_strong_handle<c_particle_snapshot>* particle_snapshot, int count, void* data);
};
class tracer_info
{
public:
unsigned int effect_index = -1;
vec3_t* positions = nullptr;
float* times = nullptr;
c_strong_handle<c_particle_snapshot> handle_snapshot_particle{};
particle_data particle_data_;
};
class cbullet_tracer
{
public:
void spawn_particle_at_position(const vec3_t& position, int ip);
void spawn_particle_hit_at_position(const vec3_t& position, int ip);
void spawn_particle_map_at_position(int ip, Color_t clr_);
void add_bullet_trace(vec3_t start, vec3_t end, Color_t clr_);
private:
class cbullet_tracer_info
{
public:
cbullet_tracer_info(vec3_t src, vec3_t dst, float time, Color_t color)
{
this->src = src;
this->dst = dst;
this->time = time;
this->color = color;
}
vec3_t src, dst;
float time;
Color_t color;
};
};
inline std::unique_ptr<cbullet_tracer> g_bullet_trace = std::make_unique<cbullet_tracer>();