#include "main.h"
// Settings
// ================================================== ==============================
std::string gName = "ArmA 2 OA";
std::string winName = "Base";
// Variables
// ================================================== ==============================
std:
fstream LogFile;
const MARGINS Margin = { -1, -1, -1, -1 };
bool running{ true };
dx:
irectX DX;
ObjManager objManager;
// Game Variables
// ================================================== ==============================
HANDLE gHandle;
HWND gHwnd;
RECT gRect;
unsigned int gWidth;
unsigned int gHeight;
// Menu & Hack Config
// ================================================== ==============================
menu::Menu Menu;
std::shared_ptr<menu::Item> MenuDistEnemies(new menu::Item("Enemies", LoadSetting("Enemies"), 0, 10000, 500));
std::shared_ptr<menu::Item> MenuDistFriends(new menu::Item("Friends", LoadSetting("Friends"), 0, 10000, 500));
std::shared_ptr<menu::Item> MenuDistOccupiedVehicles(new menu::Item("OcVehicles", LoadSetting("OcVehicles"), 0, 10000, 200));
std::shared_ptr<menu::Item> MenuDistBodies(new menu::Item("Bodies", LoadSetting("Bodies"), 0, 1000, 100));
std::shared_ptr<menu::Item> MenuDistNPCs(new menu::Item("NPCs", LoadSetting("NPCs"), 0, 2000, 200));
std::shared_ptr<menu::Item> MenuDistVehicles(new menu::Item("Vehicles", LoadSetting("Vehicles"), 0, 1000, 100));
std::shared_ptr<menu::Item> MenuDistItems(new menu::Item("Items", LoadSetting("Items"), 0, 200, 20));
std::shared_ptr<menu::Item> MenuUnlockVehicles(new menu::Item("UnVehicles", LoadSetting("UnVehicles"), 0, 1, 1));
std::shared_ptr<menu::Item> MenuUnlimitedAmmo(new menu::Item("UnAmmo", 0, 0, 1, 1));
std::vector<std::string> ListFriends;
// Color
// ================================================== ==============================
const D3DCOLOR COLOR_ENEMIES{ D3DCOLOR_ARGB(255, 200, 0, 0) };
const D3DCOLOR COLOR_FRIENDS{ D3DCOLOR_ARGB(255, 0, 200, 0) };
const D3DCOLOR COLOR_DEAD{ D3DCOLOR_ARGB(255, 200, 100, 0) };
const D3DCOLOR COLOR_NPC{ D3DCOLOR_ARGB(255, 240, 240, 0) };
const D3DCOLOR COLOR_VEHICLE{ D3DCOLOR_ARGB(255, 20, 150, 220) };
const D3DCOLOR COLOR_ITEMS{ D3DCOLOR_ARGB(255, 200, 150, 220) };
void Update() {
using namespace engine;
while (running) {
if (GetForegroundWindow() == gHwnd) {
std::vector<DrawObject> DrawBuf;
// World
auto worldPointer = WorldPointer::Singleton();
auto world = worldPointer->GetWorld();
if (world == NULL) break;
// LocalPlayer
auto localPlayer = world->GetCameraOn()->GetUnit();
Vector3 localPlayerCoordinates = localPlayer->GetEntityVisualState()->GetCoordinates();
// ItemCaches
for (int a = 0; a < 3; a++) {
auto entitiesDistributed = world->GetEntitiesDistributed(a);
for (int b = 0; b < 3; b++) {
auto entityList = entitiesDistributed->GetTable(b);
auto size = entitiesDistributed->GetTableSize(b);
if (size > 0)
for (int c = 0; c < size; c++) {
auto entity = entityList->GetEntityById(c);
Vector3 pos = entity->GetEntityVisualState()->GetCoordinates();
if (MenuDistItems->GetVal() <= Vector3::Substract(localPlayerCoordinates, pos).Length()) continue;
std::string name(entity->GetCfgVehicle()->GetEntityName()->GetString());
if (name == "USBasicAmmunitionBox_EP1") {
name += " " + std::to_string(entity->GetEntityInventory()->GetWeaponTableSize());
name += " | " + std::to_string(entity->GetEntityInventory()->GetItemTableSize());
DrawBuf.push_back(DrawObject(name, pos));
}
}
}
}
objManager.SetDrawObjects(DrawBuf);
// PlayerNames
std::vector<PlayerName> PlayerBuf;
auto networkManager = NetworkManager::Singleton();
auto scoreboard = networkManager->GetScoreboard();
auto scoreboardTable = scoreboard->GetScoreBoardTable();
for (int i = 0; i < scoreboard->GetTableSize(); i++) {
auto scoreboardEntry = scoreboardTable->GetEntryById(i);
PlayerBuf.push_back(PlayerName(scoreboardEntry->GetPlayername()->GetString(), scoreboardEntry->GetId()));
}
objManager.SetPlayerNames(PlayerBuf);
}
Sleep(1000);
}
}
void Render() {
using namespace engine;
DX.BeginScene();
if (GetForegroundWindow() == gHwnd) {
// TransData
auto transData = TransData::Singleton();
transData->Update();
// Draw ItemCaches
std::vector<DrawObject> DrawBuf = objManager.GetDrawObjects();
for (int i = 0; i < DrawBuf.size(); i++) {
Vector3 draw;
transData->WorldToScreen(DrawBuf[i].coordinates, draw);
if (draw.z > 0.01f)
DX.DrawString(DrawBuf[i].str, draw.x, draw.y, COLOR_ITEMS);
}
// World
auto worldPointer = WorldPointer::Singleton();
auto world = worldPointer->GetWorld();
if (world == NULL) return;
// LocalPlayer
auto localPlayer = world->GetCameraOn()->GetUnit();
Vector3 localPlayerCoordinates = localPlayer->GetEntityVisualState()->GetCoordinates();
// Unlimited Ammo
if (MenuUnlimitedAmmo->GetVal()) {
auto weaponTable = localPlayer->GetWeaponTable();
for (int i = 0; i < localPlayer->GetWeaponTableSize(); i++) {
auto weapon = weaponTable->GetWeaponById(i);
auto stance = weapon->GetWeaponType()->GetStance();
if (stance == 1 || stance == 2) { // 1 = MainHand, 2 = OffHand, 0 = Other
weapon->GetMagazine()->SetAmmo(5);
}
}
}
// Entities
auto entityTablePointer = world->GetEntityTablePointer();
auto entityTable = entityTablePointer->GetEntityTable();
for (int i = 0; i < entityTablePointer->GetEntityTableSize(); i++) {
auto unitInfo = entityTable->GetUnitInfoById(i);
auto unit = unitInfo->GetUnit();
auto entityVS = unit->GetEntityVisualState();
auto cfgVehicle = unit->GetCfgVehicle();
Vector3 coordinates = entityVS->GetCoordinates();
Vector3 draw;
transData->WorldToScreen(coordinates, draw);
int dist = Vector3::Substract(localPlayerCoordinates, coordinates).Length();
// Draw Entity
// ================================================== ==============================
if (draw.z > 0.01f) {
std::string info;
int playerID = unit->GetPlayerID();
int isDead = unit->GetIsDead();
if (playerID > 1 && !isDead) { // Player
if (MenuDistEnemies->GetVal() < dist && MenuDistFriends->GetVal() < dist || dist <= 1) continue;
std::string name = objManager.GetPlayerName(playerID);
// Is Player a friend?
D3DCOLOR color;
if (std::find(ListFriends.begin(), ListFriends.end(), name) != ListFriends.end()) {
if (MenuDistFriends->GetVal() < dist) continue;
color = COLOR_FRIENDS;
}
else {
if (MenuDistEnemies->GetVal() < dist) continue;
color = COLOR_ENEMIES;
}
// Torso
Vector3 coordinatesTorso = entityVS->GetTorsoCoordinates();
Vector3 drawTorso;
transData->WorldToScreen(coordinatesTorso, drawTorso);
DX.DrawLine(draw.x, draw.y, drawTorso.x, drawTorso.y, 2, color);
// Head
Vector3 coordinatesHead = entityVS->GetHeadCoordinates();
Vector3 drawHead;
transData->WorldToScreen(coordinatesHead, drawHead);
DX.DrawLine(drawTorso.x, drawTorso.y, drawHead.x, drawHead.y, 2, color);
// Info
info.append(name);
info.append(" [").append(std::to_string(dist)).append("]");
DX.DrawString(info, draw.x + 12, draw.y, color);
}
else if (playerID > 0 && isDead) { // Dead
if (MenuDistBodies->GetVal() < dist) continue;
// Torso
Vector3 coordinatesTorso = entityVS->GetTorsoCoordinates();
Vector3 drawTorso;
transData->WorldToScreen(coordinatesTorso, drawTorso);
DX.DrawLine(draw.x, draw.y, drawTorso.x, drawTorso.y, 2, COLOR_DEAD);
// Head
Vector3 coordinatesHead = entityVS->GetHeadCoordinates();
Vector3 drawHead;
transData->WorldToScreen(coordinatesHead, drawHead);
DX.DrawLine(drawTorso.x, drawTorso.y, drawHead.x, drawHead.y, 2, COLOR_DEAD);
}
else if (playerID == 1) { // NPC
if (MenuDistNPCs->GetVal() < dist) continue;
// Torso
Vector3 coordinatesTorso = entityVS->GetTorsoCoordinates();
Vector3 drawTorso;
transData->WorldToScreen(coordinatesTorso, drawTorso);
DX.DrawLine(draw.x, draw.y, drawTorso.x, drawTorso.y, 2, COLOR_NPC);
// Head
Vector3 coordinatesHead = entityVS->GetHeadCoordinates();
Vector3 drawHead;
transData->WorldToScreen(coordinatesHead, drawHead);
DX.DrawLine(drawTorso.x, drawTorso.y, drawHead.x, drawHead.y, 2, COLOR_NPC);
// Info
info.append("NPC");
info.append(" [").append(std::to_string(dist)).append("]");
DX.DrawString(info, draw.x + 12, draw.y, COLOR_NPC);
}
else { // Vehicle
auto vehicle = unitInfo->GetVehicle();
// Unlock Vehicle
if (MenuUnlockVehicles->GetVal() == 1 && dist <= 5)
vehicle->UnlockVehicle();
if (MenuDistVehicles->GetVal() < dist && MenuDistOccupiedVehicles->GetVal() < dist) continue;
std::vector<DWORD> passengers;
std::vector<DWORD> gunners;
// Driver
auto driver = vehicle->GetDriver();
auto driverID = 0;
if (driver->GetAddress() > 0)
driverID = driver->GetPlayerID();
// Passengers
auto passengerTable = vehicle->GetPassengerTable();
for (int a = 0; a < vehicle->GetMaxPassengers(); a++) {
auto passenger = passengerTable->GetUnitById(a);
if (passenger->GetAddress() > 0) {
auto passengerID = passenger->GetPlayerID();
if (passengerID > 0)
passengers.push_back(passengerID);
}
}
// Gunners
auto turretTable = vehicle->getTurretTable();
for (int a = 0; a < vehicle->GetTurretTableSize(); a++) {
auto gunner = turretTable->GetTurretById(a)->GetUnit();
if (gunner->GetAddress() > 0) {
auto gunnerID = gunner->GetPlayerID();
if (gunnerID > 0)
gunners.push_back(gunnerID);
}
}
if (driverID > 0 || passengers.size() > 0 || gunners.size() > 0) { // Occupied vehicle
if (MenuDistOccupiedVehicles->GetVal() < dist) continue;
info.append(cfgVehicle->GetEntityName()->GetString());
info.append(" [").append(std::to_string(dist)).append("]\n");
if (driverID > 0)
info.append(objManager.GetPlayerName(driverID)).ap pend("\n");
for (int a = 0; a < passengers.size(); a++)
info.append(objManager.GetPlayerName(passengers[a])).append("\n");
for (int a = 0; a < gunners.size(); a++)
info.append("> ").append(objManager.GetPlayerName(gunners[a])).append("\n");
DX.DrawString(info, draw.x, draw.y, COLOR_ENEMIES);
}
else { // Empty vehicle
if (MenuDistVehicles->GetVal() < dist) continue;
info.append(cfgVehicle->GetEntityName()->GetString());
info.append(" [").append(std::to_string(dist)).append("]");
DX.DrawString(info, draw.x, draw.y, COLOR_VEHICLE);
}
}
}
}
Menu.Render(DX);
}
DX.EndScene();
Sleep(10);
}
void InitMenu() {
Menu.AddItem(MenuDistEnemies);
Menu.AddItem(MenuDistFriends);
Menu.AddItem(MenuDistOccupiedVehicles);
Menu.AddItem(MenuDistBodies);
Menu.AddItem(MenuDistNPCs);
Menu.AddItem(MenuDistVehicles);
Menu.AddItem(MenuDistItems);
Menu.AddItem(MenuUnlockVehicles);
Menu.AddItem(MenuUnlimitedAmmo);
{ // Load Friends from confing.ini name00;name01;name02; ...
char buf[4096]{ 0 };
int len = GetPrivateProfileString("Friends", "Names", "", buf, sizeof(buf), "./config.ini");
std::stringstream ss(buf);
std::string str;
while (std::getline(ss, str, ';')) {
if (!str.empty())
ListFriends.push_back(str);
}
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstacne, LPSTR lpCmdLine, int nCmdShow) {
// Init LogFile
// ================================================== ==============================
LogFile.open("log.txt", std::ios_base:
ut | std::ios_base::app);
Log("Init Main");
// Init Game
// ================================================== ==============================
if (!UpdateGame()) {
Log("UpdateGame failed");
return 1;
}
// Init WinMain
// ================================================== ==============================
WNDCLASSEX wClass;
wClass.cbClsExtra = NULL;
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.cbWndExtra = NULL;
wClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
wClass.hCursor = LoadCursor(0, IDC_ARROW);
wClass.hIcon = LoadIcon(0, IDI_APPLICATION);
wClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
wClass.hInstance = hInstance;
wClass.lpfnWndProc = WinProc;
wClass.lpszClassName = winName.c_str();
wClass.lpszMenuName = winName.c_str();
wClass.style = CS_VREDRAW | CS_HREDRAW;
if (!RegisterClassEx(&wClass)) {
Log("RegisterClassEx failed");
return 1;
}
HWND hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_LAYERED, winName.c_str(), winName.c_str(), WS_POPUP, 0, 0, gWidth, gHeight, 0, 0, 0, 0);
SetLayeredWindowAttributes(hwnd, 0, 1, LWA_ALPHA);
SetLayeredWindowAttributes(hwnd, 0, RGB(0, 0, 0), LWA_COLORKEY);
ShowWindow(hwnd, SW_SHOW);
// Init DirectX
// ================================================== ==============================
if (!DX.Init(hwnd, gWidth, gHeight)) {
Log("Init DirectX failed");
return 1;
}
// Init Menu
// ================================================== ==============================
InitMenu();
// Init Update
// ================================================== ==============================
std::thread update(Update);
update.detach();
// Main Loop
// ================================================== ==============================
MSG msg;
while (running) {
if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
DispatchMessage(&msg);
TranslateMessage(&msg);
}
if (!UpdateGame()) {
Log("UpdateGame failed");
running = false;
return 1;
}
MoveWindow(hwnd, gRect.left, gRect.top, gWidth, gHeight, 0);
}
return 0;
}
LRESULT CALLBACK WinProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch (Message) {
case WM_PAINT:
Render();
break;
case WM_CREATE:
DwmExtendFrameIntoClientArea(hWnd, &Margin);
break;
case WM_DESTROY:
running = false;
PostQuitMessage(1);
break;
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
break;
}
return 0;
}
static BOOL CALLBACK GameEnumWindows(HWND hwnd, LPARAM lParam) {
char title[MAX_PATH];
GetWindowText(hwnd, title, MAX_PATH);
std::string buf(title);
if (buf.find(gName) != std::string::npos) {
gHwnd = hwnd;
return false;
}
return true;
}
bool UpdateGame() {
if (!EnumWindows(GameEnumWindows, NULL)) {
DWORD pid;
GetWindowRect(gHwnd, &gRect);
GetWindowThreadProcessId(gHwnd, &pid);
gHandle = OpenProcess(PROCESS_VM_READ, 0, pid);
if (!gHandle) {
Log("OpenProcess failed with error" + std::to_string(GetLastError()));
return false;
}
DWORD dwStyle = GetWindowLong(gHwnd, GWL_STYLE);
if (dwStyle & WS_BORDER) {
gRect.top += 31;
gRect.bottom -= 8;
gRect.left += 8;
gRect.right -= 8;
}
gWidth = gRect.right - gRect.left;
gHeight = gRect.bottom - gRect.top;
return true;
}
return false;
}
int LoadSetting(std::string name) {
return GetPrivateProfileInt("Settings", name.c_str(), 0, "./config.ini");
}
void Log(std::string hStr) {
LogFile << hStr << "\n";
}