Другое С/С++ Вопрос - Ответ

san0

Известный
Друг
411
268
Хотелось бы увидеть реализацию подобного на c++
Последний из способов, наверное, наиболее благоприятный по причине низкой посадки по рантайму
C++:
#include <iostream>
#include <vector>
#include <any>
#include <typeindex>
#include <typeinfo>

struct Man1 {
    unsigned long long index = 0LL;
    std::string name = "Name";
    void doSmth11() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->index << std::endl;
    }
   
    void doSmth12() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->name << std::endl; 
    }
};


struct Man2 {
    unsigned long long cost = 2222LL;
    std::string group = "Group";
    void doSmth21() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->cost << std::endl;
    }
   
    void doSmth22() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->group << std::endl; 
    }
};

int main() {
    std::vector<std::any> pool;
   
    pool.push_back(Man1{});
    pool.push_back(Man2{});
   
    for (auto&& e : pool) {
        if (std::type_index(e.type()) == std::type_index(typeid(Man1))) {
            auto restoredMan1 = std::any_cast<Man1>(e);
            restoredMan1.doSmth11();
            restoredMan1.doSmth12();
        } else if (e.type().hash_code() == typeid(Man2).hash_code()) {
            auto restoredMan2 = std::any_cast<Man2>(e);
            restoredMan2.doSmth21();
            restoredMan2.doSmth22();
        }
    }
}
C++:
#include <iostream>
#include <vector>

struct ManEssential { 
    virtual void __unused(void) {};
};

struct Man1 : ManEssential {
    unsigned long long index = 0LL;
    std::string name = "Name";
    void doSmth11() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->index << std::endl;
    }
   
    void doSmth12() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->name << std::endl; 
    }
};


struct Man2 : ManEssential {
    unsigned long long cost = 2222LL;
    std::string group = "Group";
    void doSmth21() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->cost << std::endl;
    }
   
    void doSmth22() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->group << std::endl; 
    }
};

int main() {
    std::vector<ManEssential*> pool;
   
    pool.push_back(new Man2);
    pool.push_back(new Man1);
   
    for (auto&& e : pool) {
        if (auto restoredMan1 = dynamic_cast<Man1*>(e)) {
            restoredMan1->doSmth11();
            restoredMan1->doSmth12();
        } else if (auto restoredMan2 = dynamic_cast<Man2*>(e)) {
            restoredMan2->doSmth21();
            restoredMan2->doSmth22();
        }
    }
}
C++:
#include <iostream>
#include <vector>

struct Man1 {
    unsigned long long index = 0LL;
    std::string name = "Name";
    void doSmth11() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->index << std::endl;
    }
   
    void doSmth12() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->name << std::endl; 
    }
};


struct Man2 {
    unsigned long long cost = 2222LL;
    std::string group = "Group";
    void doSmth21() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->cost << std::endl;
    }
   
    void doSmth22() {
        std::cout << __PRETTY_FUNCTION__ << ' ' << 
            this->group << std::endl; 
    }
};

enum class ManSubtype {
    kMan1,
    kMan2
};

struct ObjectSlicing : public Man1, public Man2 {
    const ManSubtype type;

    template<typename T> 
    ObjectSlicing(const T&& man) : type([=] {
        if constexpr (std::is_same<T, Man1>()) {
            return ManSubtype::kMan1;
        } else if constexpr (std::is_same<T, Man2>()) {
            return ManSubtype::kMan2;
        }
    }()) 
    {}
};

int main() {
    std::vector<class ObjectSlicing> pool;
   
    pool.push_back(ObjectSlicing(Man1{}));
    pool.push_back(ObjectSlicing(Man2{}));
   
    for (auto&& e : pool) {
        if (e.type == ManSubtype::kMan1) {
            Man1 restoredMan1 = e;
            restoredMan1.doSmth11();
            restoredMan1.doSmth12();
        } else if (e.type == ManSubtype::kMan2) {
            Man2 restoredMan2 = e;
            restoredMan2.doSmth21();
            restoredMan2.doSmth22();
        }
       
    }
}
Можно поинтересоваться, откуда информация?
Первоапрельская шутка 2018 года, не воспринимайте всерьез
http://modernescpp.com/index.php/no-new-new
Каким образом можно поменять расположение киллстата по вертикали?
samp.dll + 0x66655 =>
patch 5 bytes to mov eax,00000010, where 0x10 - Y offset
samp.dll + 0x66668 =>
patch 5 bytes to mov eax,00000020, where 0x20 - X offset
 
  • Нравится
Реакции: Yuan и index

Cake_

Потрачен
Проверенный
263
313
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Дайте функцию бега на сф, пожалуйста не кидайте соб
 

ALF

Известный
Проверенный
320
540
Либо я дико туплю, либо это отступы между строчками и отступы самих ников, а не расположение киллиста. Покопавшись, понял, что положение киллстата зависит от игрового разрешения. Тот плагин, который я кидал, как-то подменяет это самое разрешение, но при этом остальные части (худ, чат и т.д). никак не изменяет. При выгрузке плагина, киллстат встаёт на своё место. Интересная задумка, но не могу придумать, как можно заблокировать изменение остальных элементов, чтобы двигать только киллстат. Но спасибо за помощь.
не, ты какую то хрень написал.

DWORD addrX = samp.dll + 0x6665C;
DWORD addrY = samp.dll + 0x66645;
 
  • Нравится
Реакции: Yuan

checkdasound

Известный
Проверенный
963
410
Пытаюсь переделать свой скрипт в аси формат. Все сделал, кроме нормальной эмуляции игровых клавиш. Нынешняя эмуляция работает через раз.
C++:
#include "main.h"

void __cdecl thread(void *pArg)
{
   while (true)
   {
       Sleep(1);
       if (isKeyDown(0x31))
       {
           if (IsCharOnFoot())
           {
               SetGameKeyState(0x20, 255);
               Sleep(10);
               SetGameKeyState(0x20, 0);
               GTAfunc_showStyledText("ON FOOT", 2000, 1);
           }
       }
       if (isKeyDown(0xA0))
       {
           if (IsCharInAnyCar())
           {
               type = CurrentVehicleModelType();
               if (type == 1)
               {
                   SetGameKeyState(0x20, 255);
                   Sleep(10);
                   SetGameKeyState(0x20, 0);
                   GTAfunc_showStyledText("ON BIKE", 2000, 1);
               }
               else if (type == 2) {
                   SetGameKeyState(0x2, -128);
                   Sleep(10);
                   SetGameKeyState(0x2, 0);
                   GTAfunc_showStyledText("ON MOTO", 2000, 1);
               }
           }
       }
   }
}

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
   if (fdwReason == DLL_PROCESS_ATTACH)
   {
       _beginthread(thread, 0, nullptr);
           return TRUE;
   }

}

C++:
#include <windows.h>
#include <process.h>
#include <TlHelp32.h>

DWORD CPed = 0xB6F5F0;
DWORD CPedStatus = 0x530;
DWORD ProcID;
DWORD p1;
HANDLE hProcess;

unsigned int CurrentVehiclePointer = 0xBA18FC;
int Model = 0;
int Status = 0;
int type;
unsigned long temp;

int bike[3] = { 481, 509, 510 };
int moto[11] = { 448, 461, 462, 463, 468, 471, 521, 522, 523, 581, 586 };

using namespace std;

DWORD GetProcId(const char* procname)
{
   PROCESSENTRY32 pe;
   HANDLE hSnap;

   pe.dwSize = sizeof(PROCESSENTRY32);
   hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
   if (Process32First(hSnap, &pe)) {
       do {
           if (strcmp(pe.szExeFile, procname) == 0)
               break;
       } while (Process32Next(hSnap, &pe));
   }
   return pe.th32ProcessID;
}

void SetGameKeyState(BYTE key, BYTE state)
{
   p1 = 0xB73458 + key;
   memset((void*)p1, state, 1);
};

bool isKeyDown(int key)
{
   SHORT keyState = GetKeyState(key);
   return (keyState & 0x8000);
}

void GTAfunc_showStyledText(const char *text, int time, int style)
{
   ((void(__cdecl *) (const char *text, int time, int style)) (0x0069F2B0)) (text, time, style);
}

int CurrentPedStatus()
{
   ProcID = GetProcId("gta_sa.exe");
   hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);

   ReadProcessMemory(hProcess, reinterpret_cast<LPVOID>(CPed), &temp, sizeof(temp), 0);
   CPedStatus = temp + 0x530;

   ReadProcessMemory(hProcess, reinterpret_cast<LPVOID>(CPedStatus), &Status, sizeof(temp), 0);
   return Status;
}

bool IsCharInAnyCar()
{
   Status = CurrentPedStatus();
   if (Status == 50)
   {
       return true;
   }
   else
   {
       return false;
   }
}

bool IsCharOnFoot()
{
   Status = CurrentPedStatus();
   if (Status == 1)
   {
       return true;
   }
   else
   {
       return false;
   }
}

int CurrentVehicleModelType()
{
   unsigned int CurrentVehiclePointer = *(unsigned int*)0xBA18FC;
   unsigned short model = *(unsigned short*)(CurrentVehiclePointer + 34);
   if (IsCharInAnyCar())
   {
       for (int counter = 0; counter < 3; counter++)
       {
           if (model == bike[counter])
           {
               return 1;
           }
       }
       for (int counter = 0; counter < 11; counter++)
       {
           if (model == moto[counter])
           {
               return 2;
           }
       }
   } else {
       return 0;
   }
}

static struct _Keys
{
   bool        bPressed;
   DWORD       dwStartTime;
}kPressingKeys[256];

BOOL  State_Key(int Key, DWORD dwTimeOut)
{
   if (HIWORD(GetKeyState(Key)))
   {
       if (!kPressingKeys[Key].bPressed || (kPressingKeys[Key].dwStartTime && (kPressingKeys[Key].dwStartTime + dwTimeOut) <= GetTickCount()))
       {
           kPressingKeys[Key].bPressed = TRUE;
           if (dwTimeOut > NULL)
               kPressingKeys[Key].dwStartTime = GetTickCount();
           return TRUE;
       }
   }
   else
       kPressingKeys[Key].bPressed = FALSE;
   return FALSE;
}
 

CleanLegend

Известный
Всефорумный модератор
478
935
Пытаюсь переделать свой скрипт в аси формат. Все сделал, кроме нормальной эмуляции игровых клавиш. Нынешняя эмуляция работает через раз.
C++:
#include "main.h"

void __cdecl thread(void *pArg)
{
   while (true)
   {
       Sleep(1);
       if (isKeyDown(0x31))
       {
           if (IsCharOnFoot())
           {
               SetGameKeyState(0x20, 255);
               Sleep(10);
               SetGameKeyState(0x20, 0);
               GTAfunc_showStyledText("ON FOOT", 2000, 1);
           }
       }
       if (isKeyDown(0xA0))
       {
           if (IsCharInAnyCar())
           {
               type = CurrentVehicleModelType();
               if (type == 1)
               {
                   SetGameKeyState(0x20, 255);
                   Sleep(10);
                   SetGameKeyState(0x20, 0);
                   GTAfunc_showStyledText("ON BIKE", 2000, 1);
               }
               else if (type == 2) {
                   SetGameKeyState(0x2, -128);
                   Sleep(10);
                   SetGameKeyState(0x2, 0);
                   GTAfunc_showStyledText("ON MOTO", 2000, 1);
               }
           }
       }
   }
}

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
   if (fdwReason == DLL_PROCESS_ATTACH)
   {
       _beginthread(thread, 0, nullptr);
           return TRUE;
   }

}

C++:
#include <windows.h>
#include <process.h>
#include <TlHelp32.h>

DWORD CPed = 0xB6F5F0;
DWORD CPedStatus = 0x530;
DWORD ProcID;
DWORD p1;
HANDLE hProcess;

unsigned int CurrentVehiclePointer = 0xBA18FC;
int Model = 0;
int Status = 0;
int type;
unsigned long temp;

int bike[3] = { 481, 509, 510 };
int moto[11] = { 448, 461, 462, 463, 468, 471, 521, 522, 523, 581, 586 };

using namespace std;

DWORD GetProcId(const char* procname)
{
   PROCESSENTRY32 pe;
   HANDLE hSnap;

   pe.dwSize = sizeof(PROCESSENTRY32);
   hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
   if (Process32First(hSnap, &pe)) {
       do {
           if (strcmp(pe.szExeFile, procname) == 0)
               break;
       } while (Process32Next(hSnap, &pe));
   }
   return pe.th32ProcessID;
}

void SetGameKeyState(BYTE key, BYTE state)
{
   p1 = 0xB73458 + key;
   memset((void*)p1, state, 1);
};

bool isKeyDown(int key)
{
   SHORT keyState = GetKeyState(key);
   return (keyState & 0x8000);
}

void GTAfunc_showStyledText(const char *text, int time, int style)
{
   ((void(__cdecl *) (const char *text, int time, int style)) (0x0069F2B0)) (text, time, style);
}

int CurrentPedStatus()
{
   ProcID = GetProcId("gta_sa.exe");
   hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);

   ReadProcessMemory(hProcess, reinterpret_cast<LPVOID>(CPed), &temp, sizeof(temp), 0);
   CPedStatus = temp + 0x530;

   ReadProcessMemory(hProcess, reinterpret_cast<LPVOID>(CPedStatus), &Status, sizeof(temp), 0);
   return Status;
}

bool IsCharInAnyCar()
{
   Status = CurrentPedStatus();
   if (Status == 50)
   {
       return true;
   }
   else
   {
       return false;
   }
}

bool IsCharOnFoot()
{
   Status = CurrentPedStatus();
   if (Status == 1)
   {
       return true;
   }
   else
   {
       return false;
   }
}

int CurrentVehicleModelType()
{
   unsigned int CurrentVehiclePointer = *(unsigned int*)0xBA18FC;
   unsigned short model = *(unsigned short*)(CurrentVehiclePointer + 34);
   if (IsCharInAnyCar())
   {
       for (int counter = 0; counter < 3; counter++)
       {
           if (model == bike[counter])
           {
               return 1;
           }
       }
       for (int counter = 0; counter < 11; counter++)
       {
           if (model == moto[counter])
           {
               return 2;
           }
       }
   } else {
       return 0;
   }
}

static struct _Keys
{
   bool        bPressed;
   DWORD       dwStartTime;
}kPressingKeys[256];

BOOL  State_Key(int Key, DWORD dwTimeOut)
{
   if (HIWORD(GetKeyState(Key)))
   {
       if (!kPressingKeys[Key].bPressed || (kPressingKeys[Key].dwStartTime && (kPressingKeys[Key].dwStartTime + dwTimeOut) <= GetTickCount()))
       {
           kPressingKeys[Key].bPressed = TRUE;
           if (dwTimeOut > NULL)
               kPressingKeys[Key].dwStartTime = GetTickCount();
           return TRUE;
       }
   }
   else
       kPressingKeys[Key].bPressed = FALSE;
   return FALSE;
}
Для нормальной эмуляции клавиш нужно хукать функцию, которая отвечает за нажатие игровых клавиш. https://git.prime-hack.net/SR_team/AsiBase/src/branch/master/sys/SREvents.cpp#L432
Как вариант можешь вызывать функции SF или WinAPI. и не используй RPM и WPM в dll
 

Шурик

Активный
216
43
Столкнулся с такой проблемой:
- В цикле стоит проверка на зажатую клавишу (VK_LMENU), если нажата - выводит сообщение. Если же я с рабочего стола перейду в игру (через Alt + Tab), то это сообщение будет выводиться до первого нажатия на клавишу Alt. Использовал функцию SF->getGame()->isKeyDown и ImGui::IsKeyDown - результат один.

P.S. Замечу, сама игра не обрабатывают эту клавишу (ну тип персонаж не ходит на альте), а данные функции обрабатывают.

Есть ли способ решить данную проблему?
 

_=Gigant=_

Известный
144
222
Cannot open include file: 'd3dx9.h'
Как это пофиксить? До переустановки студии всё было нормально. DirectX 9 установлен.

located in VC++ Directories

F3ygysJ.jpg
 
  • Нравится
Реакции: atizoff

ImPasha

Software Developer & System Administrator
Друг
1,788
2,141