mirror of
https://github.com/0TheSpy/Seaside.git
synced 2026-10-10 03:43:16 +08:00
Add files via upload
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
#ifndef CONFIG
|
||||
#define CONFIG
|
||||
#pragma once
|
||||
|
||||
#include "Options.hpp"
|
||||
#include "Singleton.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
std::vector<char> HexToBytes(const std::string& hex) {
|
||||
std::vector<char> res;
|
||||
|
||||
for (auto i = 0u; i < hex.length(); i += 2) {
|
||||
std::string byteString = hex.substr(i, 2);
|
||||
char byte = (char)strtol(byteString.c_str(), NULL, 16);
|
||||
res.push_back(byte);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
std::string BytesToString(unsigned char* data, int len) {
|
||||
constexpr char hexmap[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
std::string res(len * 2, ' ');
|
||||
for (int i = 0; i < len; ++i) {
|
||||
res[2 * i] = hexmap[(data[i] & 0xF0) >> 4];
|
||||
res[2 * i + 1] = hexmap[data[i] & 0x0F];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
std::vector<std::string> Split(const std::string& str, const char* delim) {
|
||||
std::vector<std::string> res;
|
||||
char* pTempStr = _strdup(str.c_str());
|
||||
char* context = NULL;
|
||||
char* pWord = strtok_s(pTempStr, delim, &context);
|
||||
while (pWord != NULL) {
|
||||
res.push_back(pWord);
|
||||
pWord = strtok_s(NULL, delim, &context);
|
||||
}
|
||||
|
||||
free(pTempStr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
class Config : public Singleton<Config> {
|
||||
public:
|
||||
void Save() {
|
||||
std::ofstream fout("seaside210616.cfg", std::ios::binary);
|
||||
const auto sz = sizeof(Options);
|
||||
const auto var_sz = sizeof(Var<bool>);
|
||||
const auto cnt = sz / var_sz;
|
||||
for (auto i = 0; i < cnt; i++) {
|
||||
const auto el = &(*(Var<int>*)(&g_Options)) + i;
|
||||
auto name = el->name;
|
||||
auto val = el->value;
|
||||
auto sizeof_val = el->size;
|
||||
fout << name << "\t" << BytesToString((unsigned char*)*(int*)&val, sizeof_val) << std::endl;
|
||||
}
|
||||
fout.close();
|
||||
}
|
||||
|
||||
bool file_exists(std::string filename) {
|
||||
std::ifstream ifile(filename);
|
||||
return (bool)ifile;
|
||||
}
|
||||
|
||||
void Load() {
|
||||
|
||||
opt.loading = 1;
|
||||
|
||||
if (file_exists("seaside210616.cfg") ) {
|
||||
std::ifstream fin("seaside210616.cfg", std::ios::binary);
|
||||
std::stringstream ss;
|
||||
ss << fin.rdbuf();
|
||||
|
||||
|
||||
auto lines = Split(ss.str(), "\n");
|
||||
|
||||
for (auto line : lines) {
|
||||
auto data = Split(line, "\t");
|
||||
const auto sz = sizeof(Options);
|
||||
const auto var_sz = sizeof(Var<bool>);
|
||||
const auto cnt = sz / var_sz;
|
||||
for (auto i = 0; i < cnt; i++) {
|
||||
const auto& el = &(*(Var<bool>*)(&g_Options)) + i;
|
||||
if (data[0] == el->name) {
|
||||
auto bytes = HexToBytes(data[1]);
|
||||
memcpy(*(void**)&el->value, bytes.data(), el->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
fin.close();
|
||||
|
||||
OnLoadCfg();
|
||||
}
|
||||
else iff.g_pGameUI->CreateCommandMsgBox("Seaside Error", "Unable to find configuration file!", true, false, "", "", "", "", "");
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,407 @@
|
||||
#ifndef EVENTLISTEN
|
||||
#define EVENTLISTEN
|
||||
#pragma once
|
||||
|
||||
#pragma comment( lib, "Winmm.lib" )
|
||||
|
||||
#include "Interfaces.hpp"
|
||||
#include "sdk/c_baseentity.h"
|
||||
#include "Options.hpp"
|
||||
|
||||
|
||||
struct bullet
|
||||
{
|
||||
bullet(int userID, Vector pos, int dmg, bool hs, float curtime)
|
||||
{
|
||||
this->userid = userid;
|
||||
this->hs = hs;
|
||||
this->curtime = curtime;
|
||||
this->time = curtime + 0.0f;
|
||||
this->pos = pos;
|
||||
this->dmg = dmg;
|
||||
}
|
||||
int userid;
|
||||
bool hs;
|
||||
float time;
|
||||
float curtime;
|
||||
Vector pos;
|
||||
int dmg;
|
||||
};
|
||||
std::vector<bullet> bulletdata;
|
||||
|
||||
#define PI 3.14159265
|
||||
|
||||
class EventListener : public IGameEventListener2
|
||||
{
|
||||
public:
|
||||
EventListener()
|
||||
{
|
||||
if (!iff.g_pGameEvents->AddListener(this, "bullet_impact", false))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << "Can't add listener bullet_impact\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (!iff.g_pGameEvents->AddListener(this, "player_hurt", false))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << "Can't add listener player_hurt\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (!iff.g_pGameEvents->AddListener(this, "vote_cast", false))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << "Can't add listener vote_cast\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (!iff.g_pGameEvents->AddListener(this, "game_newmap", false))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << "Can't add listener game_newmap\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << "Event Listener created\n";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
~EventListener()
|
||||
{
|
||||
iff.g_pGameEvents->RemoveListener(this);
|
||||
}
|
||||
|
||||
int GetEventDebugID() override
|
||||
{
|
||||
return EVENT_DEBUG_ID_INIT;
|
||||
}
|
||||
|
||||
virtual void FireGameEvent(IGameEvent* event)
|
||||
{
|
||||
|
||||
if (*g_Options.hitmarker || *g_Options.hitsound) {
|
||||
if (!strcmp(event->GetName(), "player_hurt"))
|
||||
{
|
||||
short hitgroup = event->GetInt("hitgroup");
|
||||
short attacker = event->GetInt("attacker");
|
||||
short userid = event->GetInt("userid");
|
||||
short dmg_health = event->GetInt("dmg_health");
|
||||
|
||||
if (iff.g_pEngineClient->GetPlayerForUserID(attacker) == iff.g_pEngineClient->GetLocalPlayer()) {
|
||||
|
||||
int pid = iff.g_pEngineClient->GetPlayerForUserID(userid);
|
||||
C_BasePlayer* pEntity = (C_BasePlayer*)iff.g_pEntityList->GetClientEntity(pid);
|
||||
Vector pos = pEntity->GetBonePosition(8);
|
||||
|
||||
if (hitgroup == 1)
|
||||
{
|
||||
bool badInput = false;
|
||||
int i_dec = 0;
|
||||
|
||||
if (*g_Options.hitsound) {
|
||||
try
|
||||
{
|
||||
i_dec = std::stoi(g_Options.hspath.value->mystring);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
badInput = true;
|
||||
PlaySoundA(g_Options.hspath.value->mystring, NULL, SND_ASYNC);
|
||||
}
|
||||
|
||||
if (!badInput && FindResource(opt.hModuleGlobal, MAKEINTRESOURCE(i_dec), "WAVE")) {
|
||||
PlaySoundA((char*)i_dec, opt.hModuleGlobal, SND_RESOURCE | SND_ASYNC);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (*g_Options.hitmarker)
|
||||
bulletdata.push_back(bullet(userid, pos, dmg_health, 1, iff.g_pGlobals->curtime));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool badInput = false;
|
||||
int i_dec = 0;
|
||||
|
||||
if (*g_Options.hitsound) {
|
||||
try
|
||||
{
|
||||
i_dec = std::stoi(g_Options.obpath.value->mystring);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
badInput = true;
|
||||
PlaySoundA(g_Options.obpath.value->mystring, NULL, SND_ASYNC);
|
||||
}
|
||||
|
||||
if (!badInput && FindResource(opt.hModuleGlobal, MAKEINTRESOURCE(i_dec), "WAVE")) {
|
||||
PlaySoundA((char*)i_dec, opt.hModuleGlobal, SND_RESOURCE | SND_ASYNC);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (*g_Options.hitmarker)
|
||||
bulletdata.push_back(bullet(userid, pos, dmg_health, 0, iff.g_pGlobals->curtime));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!strcmp(event->GetName(), "bullet_impact"))
|
||||
{
|
||||
|
||||
short userid = event->GetInt("userid");
|
||||
int localplayer = iff.g_pEngineClient->GetLocalPlayer();
|
||||
|
||||
|
||||
if (iff.g_pEngineClient->GetPlayerForUserID(userid) == localplayer) {
|
||||
|
||||
|
||||
float x = event->GetFloat("x");
|
||||
float y = event->GetFloat("y");
|
||||
float z = event->GetFloat("z");
|
||||
|
||||
C_BasePlayer* pEntity = (C_BasePlayer*)iff.g_pEntityList->GetClientEntity(localplayer);
|
||||
Vector src = pEntity->GetOrigin() + pEntity->GetViewOffset();
|
||||
Vector dst = { x,y,z };
|
||||
|
||||
Vector ang = pEntity->GetAngles();
|
||||
|
||||
ang.x -= 90.0f; ang.y -= 90.0f;
|
||||
|
||||
static float margin = 3.0f;
|
||||
static float coeff = 1.5f;
|
||||
src.x += cos(ang.x * PI / 180) * margin * sin(ang.y * PI / 180) + cos(ang.y * PI / 180) * margin * coeff;
|
||||
src.y += -cos(ang.x * PI / 180) * margin * cos(ang.y * PI / 180) + sin(ang.y * PI / 180) * margin * coeff;
|
||||
src.z += sin(ang.x * PI / 180) * margin;
|
||||
|
||||
|
||||
if (*g_Options.beamtrace) {
|
||||
|
||||
BeamInfo_t beamInfo;
|
||||
beamInfo.m_nType = *g_Options.beamtype;
|
||||
beamInfo.m_pszModelName = g_Options.beampath.value->mystring;
|
||||
|
||||
beamInfo.m_nModelIndex = -1;
|
||||
beamInfo.m_flHaloScale = 0.0f;
|
||||
beamInfo.m_pStartEnt = pEntity;
|
||||
beamInfo.m_pEndEnt = NULL;
|
||||
|
||||
beamInfo.m_vecEnd = dst;
|
||||
beamInfo.m_vecStart = src;
|
||||
beamInfo.m_flLife = *g_Options.beamlife;
|
||||
beamInfo.m_flFadeLength = *g_Options.beamfadelength;
|
||||
beamInfo.m_flAmplitude = *g_Options.beamamplitude;
|
||||
beamInfo.m_nSegments = *g_Options.beamsegments;
|
||||
beamInfo.m_bRenderable = true;
|
||||
|
||||
beamInfo.m_flSpeed = *g_Options.beamspeed;
|
||||
beamInfo.m_nStartFrame = *g_Options.beamstartframe;
|
||||
beamInfo.m_flFrameRate = *g_Options.beamframerate;
|
||||
beamInfo.m_flWidth = *g_Options.beamwidth;
|
||||
beamInfo.m_flEndWidth = *g_Options.beamwidth;
|
||||
|
||||
beamInfo.m_flBlue = g_Options.beamcolor.value->b * 255.0f;
|
||||
beamInfo.m_flGreen = g_Options.beamcolor.value->g * 255.0f;
|
||||
beamInfo.m_flRed = g_Options.beamcolor.value->r * 255.0f;
|
||||
beamInfo.m_flBrightness = g_Options.beamcolor.value->a * 255.0f;
|
||||
|
||||
beamInfo.m_nFlags = *g_Options.beamflags;
|
||||
Beam_t* myBeam = iff.g_pViewRenderBeams->CreateBeamPoints(beamInfo);
|
||||
if (myBeam) iff.g_pViewRenderBeams->DrawBeam(myBeam);
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (*g_Options.attacheffects) {
|
||||
|
||||
switch (g_Options.effects.value->type) {
|
||||
|
||||
case 0:
|
||||
{
|
||||
switch (g_Options.effects.value->selectedc)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
iff.g_pEffects->Smoke(dst, -1, g_Options.effects.value->fx_fsize, g_Options.effects.value->fx_fspeed);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
iff.g_pEffects->Dust(dst, Vector(0.0f, 0.0f, 1.0f), g_Options.effects.value->fx_fsize, g_Options.effects.value->fx_fspeed);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
iff.g_pEffects->Sparks(dst, g_Options.effects.value->fx_magnitude, g_Options.effects.value->fx_traillength);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
iff.g_pEffects->MuzzleFlash(dst, CalcAngle(dst, src), g_Options.effects.value->fx_fsize, g_Options.effects.value->fx_itype);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
iff.g_pEffects->MetalSparks(dst, Vector( 0.0f, 0.0f, 0.0f ) );
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
iff.g_pEffects->Ricochet(dst, Vector(0.0f, 0.0f, 1.0f));
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
iff.g_pEffects->EnergySplash(dst, src, g_Options.effects.value->fx_bexplosive);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
CEffectData asscock;
|
||||
asscock.m_fFlags = g_Options.effects.value->fflags;
|
||||
asscock.m_vOrigin = dst;
|
||||
asscock.m_vStart = src;
|
||||
asscock.m_vNormal.Init(0.0f, 0.0f, 1.0f);
|
||||
asscock.m_flScale = g_Options.effects.value->fscale;
|
||||
asscock.m_nColor = g_Options.effects.value->icolors;
|
||||
asscock.m_flMagnitude = g_Options.effects.value->fmagtinude;
|
||||
asscock.m_flRadius = g_Options.effects.value->fradius;
|
||||
iff.DispatchEffect(opt.DispatchEffect.at(g_Options.effects.value->selectedc).c_str(), asscock);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
case 2:
|
||||
{
|
||||
switch (g_Options.effects.value->selectedc)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
CTeslaInfo teslaInfo;
|
||||
teslaInfo.m_flBeamWidth = g_Options.effects.value->fbeamwidth;
|
||||
teslaInfo.m_flRadius = g_Options.effects.value->teslaradius;
|
||||
teslaInfo.m_nEntIndex = -1;
|
||||
teslaInfo.m_vColor.Init(g_Options.effects.value->teslacolor[0], g_Options.effects.value->teslacolor[1], g_Options.effects.value->teslacolor[2]);
|
||||
teslaInfo.m_vPos = dst;
|
||||
teslaInfo.m_flTimeVisible = g_Options.effects.value->fltimevisible;
|
||||
teslaInfo.m_nBeams = g_Options.effects.value->ibeams;
|
||||
teslaInfo.m_pszSpriteName = g_Options.effects.value->szSpriteName;
|
||||
iff.FX_Tesla(teslaInfo);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
case 1:
|
||||
{
|
||||
|
||||
dlight_t* pDlight = iff.g_pEfx->CL_AllocDlight(1);
|
||||
pDlight->origin = dst;
|
||||
pDlight->radius = g_Options.effects.value->frad;
|
||||
pDlight->color.r = g_Options.effects.value->dlightcolor[0]*255.0f;
|
||||
pDlight->color.g = g_Options.effects.value->dlightcolor[1] * 255.0f;
|
||||
pDlight->color.b = g_Options.effects.value->dlightcolor[2] * 255.0f;
|
||||
|
||||
pDlight->color.exponent = 5;
|
||||
pDlight->die = iff.g_pGlobals->curtime + g_Options.effects.value->fdie;
|
||||
pDlight->decay = 0;
|
||||
pDlight->key = g_Options.effects.value->key;
|
||||
pDlight->style = g_Options.effects.value->style;
|
||||
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (*g_Options.votereveal) {
|
||||
if (!strcmp(event->GetName(), "vote_cast"))
|
||||
{
|
||||
int vote = event->GetInt("vote_option");
|
||||
int id = event->GetInt("entityid");
|
||||
if (iff.g_pChatElement)
|
||||
{
|
||||
player_info_t pinfo;
|
||||
iff.g_pEngineClient->GetPlayerInfo(id, &pinfo);
|
||||
|
||||
if (pinfo.name) {
|
||||
#ifdef DEBUG
|
||||
printf("%s voted %d\n", pinfo.name, vote);
|
||||
#endif
|
||||
iff.g_pChatElement->ChatPrintf2(0, 0, std::string("").
|
||||
append(" \x06").
|
||||
append(pinfo.name).
|
||||
append(" \x01").
|
||||
append("voted").
|
||||
append((vote == 0 ? std::string(" \x04").append("YES") : std::string(" \x02").append("NO"))).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(event->GetName(), "game_newmap"))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("game_newmap\n");
|
||||
#endif
|
||||
OnLevelInit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef GETVFUNC
|
||||
#define GETVFUNC
|
||||
|
||||
#pragma once
|
||||
|
||||
inline void**& getvtable(void* inst, size_t offset = 0)
|
||||
{
|
||||
return *reinterpret_cast<void***>((size_t)inst + offset);
|
||||
}
|
||||
|
||||
inline const void** getvtable(const void* inst, size_t offset = 0)
|
||||
{
|
||||
return *reinterpret_cast<const void***>((size_t)inst + offset);
|
||||
}
|
||||
|
||||
template<typename Fn>
|
||||
inline Fn getvfunc(const void* inst, size_t index, size_t offset = 0)
|
||||
{
|
||||
return reinterpret_cast<Fn>(getvtable(inst, offset)[index]);
|
||||
}
|
||||
|
||||
|
||||
template <typename Fn = void*>
|
||||
Fn get_vfunc(void* class_base, const size_t index)
|
||||
{
|
||||
return (*reinterpret_cast<Fn**>(class_base))[index];
|
||||
}
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
inline char* MakeControlChars(char str[1024]) {
|
||||
char name[1024];
|
||||
strcpy(name, str);
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
if (name[i] == 0x5C && name[i + 1] == 0x78)
|
||||
{
|
||||
char controlchar[3]; controlchar[0] = name[i + 2]; controlchar[1] = name[i + 3]; controlchar[2] = 0x0;
|
||||
short x = std::stoul(controlchar, nullptr, 16);
|
||||
name[i] = x;
|
||||
for (int j = i + 4; j < 1024; j++)
|
||||
{
|
||||
name[j - 3] = name[j];
|
||||
if (name[j] == 0x0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (name[i] == 0x0)
|
||||
break;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,201 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
VMTHook* SoundHook = nullptr;
|
||||
void __fastcall hkEmitSound1(void* _this, int edx, IRecipientFilter& filter, int iEntIndex, int iChannel, char* pSoundEntry, unsigned int nSoundEntryHash, const char* pSample, float flVolume, int nSeed, float flAttenuation, int iFlags, int iPitch, const Vector* pOrigin, const Vector* pDirection, void* pUtlVecOrigins, bool bUpdatePositions, float soundtime, int speakerentity, int unk) {
|
||||
static auto ofunc = SoundHook->GetOriginal<decltype(&hkEmitSound1)>(5);
|
||||
|
||||
if (*g_Options.soundhook_count) {
|
||||
soundlist vv = GetCfgWavpathBySoundHash(nSoundEntryHash);
|
||||
|
||||
if (vv.cfgindex != -1)
|
||||
{
|
||||
Sounds ff = g_Options.models.value->arr[vv.cfgindex].sounds[vv.sndindex];
|
||||
return ofunc(iff.g_pEngineSound, edx, filter, iEntIndex, iChannel, pSoundEntry, -1, ff.wavpath, ff.volume, nSeed, flAttenuation, 0, ff.pitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity, unk);
|
||||
}
|
||||
}
|
||||
|
||||
return ofunc(iff.g_pEngineSound, edx, filter, iEntIndex, iChannel, pSoundEntry, nSoundEntryHash, pSample, flVolume, nSeed, flAttenuation, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity, unk);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
VMTHook* DMEHook = nullptr;
|
||||
|
||||
void replacemat(int d)
|
||||
{
|
||||
IMaterial* material;
|
||||
|
||||
if (g_Options.materials.value->arr[d].customtextureselected != -1)
|
||||
if (g_Options.customtextures.value->arr[g_Options.materials.value->arr[d].customtextureselected].texturelink != nullptr)
|
||||
material = (IMaterial*)g_Options.customtextures.value->arr[g_Options.materials.value->arr[d].customtextureselected].texturelink;
|
||||
else material = iff.g_pMaterialSystem->FindMaterial("__err", TEXTURE_GROUP_MODEL);
|
||||
else
|
||||
material = iff.g_pMaterialSystem->FindMaterial(g_Options.materials.value->arr[d].texture, TEXTURE_GROUP_MODEL);
|
||||
material->SetMaterialVarFlag(MATERIAL_VAR_WIREFRAME, g_Options.materials.value->arr[d].wireframe);
|
||||
material->SetMaterialVarFlag(MATERIAL_VAR_FLAT, g_Options.materials.value->arr[d].flat);
|
||||
material->SetMaterialVarFlag(MATERIAL_VAR_NO_DRAW, g_Options.materials.value->arr[d].nodraw);
|
||||
material->ColorModulate(g_Options.materials.value->arr[d].coloralpha.x, g_Options.materials.value->arr[d].coloralpha.y, g_Options.materials.value->arr[d].coloralpha.z);
|
||||
material->AlphaModulate(g_Options.materials.value->arr[d].coloralpha.w);
|
||||
iff.g_pMdlRender->ForcedMaterialOverride(material);
|
||||
}
|
||||
|
||||
void __stdcall DrawModelExecute(IMatRenderContext* ctx, const DrawModelState_t& state, const ModelRenderInfo_t& pInfo, matrix3x4_t* pCustomBoneToWorld)
|
||||
{
|
||||
static auto ofunc = DMEHook->GetOriginal<void(__thiscall*)(IVModelRender*, IMatRenderContext*, const DrawModelState_t&, const ModelRenderInfo_t&, matrix3x4_t*)>(21);
|
||||
|
||||
if (iff.g_pMdlRender->IsForcedMaterialOverride() || opt.loading || !*g_Options.dmeloop_count)
|
||||
return ofunc(iff.g_pMdlRender, ctx, state, pInfo, pCustomBoneToWorld);
|
||||
|
||||
|
||||
const char* szName = iff.g_pMdlInfo->GetModelName(pInfo.pModel);
|
||||
|
||||
if (g_Options.materials.value->arr[3].active)
|
||||
if (strstr(szName, "player/legacy/t") != nullptr)
|
||||
replacemat(3);
|
||||
|
||||
if (g_Options.materials.value->arr[4].active)
|
||||
if (strstr(szName, "player/legacy/ct") != nullptr)
|
||||
replacemat(4);
|
||||
|
||||
if (strstr(szName, "weapons/v_")) {
|
||||
int namehash = fnv2::hashRuntime(szName);
|
||||
|
||||
|
||||
bool is_arm = strstr(szName, "arms") != nullptr;
|
||||
bool is_sleeve = strstr(szName, "sleeve") != nullptr;
|
||||
bool is_wep = !is_arm && !is_sleeve;
|
||||
|
||||
|
||||
for (int d = 0; d < g_Options.materials.value->itemcount; d++)
|
||||
{
|
||||
|
||||
if (d == 1 && !is_arm) continue;
|
||||
if (d == 2 && !is_sleeve) continue;
|
||||
if (d == 0 && !is_wep) continue;
|
||||
|
||||
if (d == 3 || d == 4) continue;
|
||||
if ((d > 2 && d != 5) && namehash != g_Options.materials.value->arr[d].model_hash) continue;
|
||||
|
||||
if (d == 5 && !strstr(szName, "knife")) continue;
|
||||
|
||||
if (g_Options.materials.value->arr[d].active) {
|
||||
replacemat(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ofunc(iff.g_pMdlRender, ctx, state, pInfo, pCustomBoneToWorld);
|
||||
|
||||
iff.g_pMdlRender->ForcedMaterialOverride(nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VMTHook* CacheHook = nullptr;
|
||||
MDLHandle_t __fastcall hkFindMDL(void* ecx, void* edx, char* FilePath)
|
||||
{
|
||||
static auto oFindMDL = CacheHook->GetOriginal<MDLHandle_t(__thiscall*)(void*, char*)>(10);
|
||||
|
||||
|
||||
if (g_Options.models.value->arr[2].active && strstr(FilePath, "models/weapons/v_models/arms") && !strstr(FilePath, "gloves"))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Replacing %s with %s\n", FilePath, g_Options.models.value->arr[2].vmodel_repl);
|
||||
#endif
|
||||
sprintf(FilePath, g_Options.models.value->arr[2].vmodel_repl);
|
||||
}
|
||||
|
||||
if (g_Options.models.value->arr[3].active && strstr(FilePath, "models/weapons/v_knife"))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Replacing %s with %s\n", FilePath, g_Options.models.value->arr[3].vmodel_repl);
|
||||
#endif
|
||||
sprintf(FilePath, g_Options.models.value->arr[3].vmodel_repl);
|
||||
}
|
||||
|
||||
for (int i = 4; i < g_Options.models.value->itemcount; i++)
|
||||
{
|
||||
if (g_Options.models.value->arr[i].active && g_Options.models.value->arr[i].findMDLmethode && strstr(FilePath, g_Options.models.value->arr[i].vmodel_orig))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Replacing %s with %s\n", FilePath, g_Options.models.value->arr[i].vmodel_repl);
|
||||
#endif
|
||||
sprintf(FilePath, g_Options.models.value->arr[i].vmodel_repl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return oFindMDL(ecx, FilePath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VMTHook* ClientModeHook = nullptr;
|
||||
static void __stdcall hkdoPostScreenEffects(void* param) noexcept
|
||||
{
|
||||
static auto ofunc = ClientModeHook->GetOriginal<void(__thiscall*)(IClientMode*, void*)>(44);
|
||||
|
||||
if (*g_Options.entityloop_count) {
|
||||
if (iff.g_pEngineClient->IsInGame())
|
||||
{
|
||||
int localplayer_index = iff.g_pEngineClient->GetLocalPlayer();
|
||||
C_BasePlayer* localplayer = static_cast<C_BasePlayer*>(iff.g_pEntityList->GetClientEntity(localplayer_index));
|
||||
|
||||
for (int i = iff.g_pEngineClient->GetMaxClients() + 1; i <= iff.g_pEntityList->GetHighestEntityIndex(); ++i)
|
||||
{
|
||||
C_BasePlayer* pEntity = (C_BasePlayer*)iff.g_pEntityList->GetClientEntity(i);
|
||||
|
||||
if (!pEntity)
|
||||
continue;
|
||||
|
||||
bool bDormant = pEntity->IsDormant();
|
||||
|
||||
if (bDormant)
|
||||
continue;
|
||||
|
||||
int cfgindex = GetCfgIndexByClassId(fnv2::hashRuntime(pEntity->GetClientClass()->GetName()));
|
||||
|
||||
if (cfgindex != -1)
|
||||
{
|
||||
if (g_Options.models.value->arr[cfgindex].active_scale)
|
||||
pEntity->GetModelScale() = g_Options.models.value->arr[cfgindex].scale;
|
||||
|
||||
if (g_Options.models.value->arr[cfgindex].active_w)
|
||||
{
|
||||
char* model = g_Options.models.value->arr[cfgindex].wmodel_repl;
|
||||
pEntity->SetModelIndex(iff.g_pMdlInfo->GetModelIndex(model));
|
||||
if (const auto modelprecache = iff.g_pNetworkStringTableContainer->FindTable("modelprecache"))
|
||||
modelprecache->AddString(false, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ofunc(iff.g_ClientMode, param);
|
||||
}
|
||||
|
||||
|
||||
VMTHook* VGUISurfHook = nullptr;
|
||||
void __fastcall hkLockCursor(void* _this)
|
||||
{
|
||||
static auto ofunc = VGUISurfHook->GetOriginal<decltype(&hkLockCursor)>(67);
|
||||
|
||||
if (opt.show) {
|
||||
iff.g_pVGuiSurface->UnlockCursor();
|
||||
iff.g_pInputSystem->ResetInputState();
|
||||
return;
|
||||
}
|
||||
|
||||
ofunc(iff.g_pVGuiSurface);
|
||||
}
|
||||
|
||||
|
||||
VMTHook* FileSystemHook = nullptr;
|
||||
|
||||
int __stdcall hkGetUnverifiedFileHashes(void* _this, void* someclass, int nMaxFiles)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
#include "Interfaces.hpp"
|
||||
#include "PatternScan.hpp"
|
||||
|
||||
IF iff;
|
||||
|
||||
void* IF::GetInterface(const char* dllname, const char* interfacename)
|
||||
{
|
||||
tCreateInterface CreateInterface = (tCreateInterface)GetProcAddress(GetModuleHandleA(dllname), "CreateInterface");
|
||||
int returnCode = 0;
|
||||
void* ointerface = CreateInterface(interfacename, &returnCode);
|
||||
#ifdef DEBUG
|
||||
printf("%s = %x\n", interfacename, ointerface);
|
||||
#endif
|
||||
return ointerface;
|
||||
}
|
||||
|
||||
PVOID FindHudElement(const char* name)
|
||||
{
|
||||
void* pointer1 = (void*)(FindPatternV2("client.dll", "B9 ? ? ? ? E8 ? ? ? ? 8B 5D 08") + 1);
|
||||
static void* pThis = *reinterpret_cast<DWORD**>(pointer1);
|
||||
void* pointer2 = (void*)(FindPatternV2("client.dll", "55 8B EC 53 8B 5D 08 56 57 8B F9 33 F6 39 77 28"));
|
||||
static auto find_hud_element
|
||||
= reinterpret_cast<DWORD(__thiscall*)(void*, const char*)>(
|
||||
pointer2
|
||||
);
|
||||
return (void*)find_hud_element(pThis, name);
|
||||
}
|
||||
|
||||
|
||||
#define VTBL(classptr) (*(DWORD*)classptr)
|
||||
#define PVFN_(classptr, offset) (VTBL(classptr) + offset)
|
||||
#define VFN_(classptr, offset) *(DWORD*)PVFN_(classptr, offset)
|
||||
#define VFN(classptr, offset) VFN_(classptr, (offset * sizeof(void*)))
|
||||
|
||||
|
||||
void IF::Init()
|
||||
{
|
||||
g_pEntityList = (IClientEntityList*)GetInterface("client.dll", "VClientEntityList003");
|
||||
g_pGameUI = (CGameUI*)GetInterface("client.dll", "GameUI011");
|
||||
g_pVGuiPanel = (vgui::IPanel*)GetInterface("vgui2.dll", "VGUI_Panel009");
|
||||
g_pGameEvents = (CGameEventManager*)GetInterface("engine.dll", "GAMEEVENTSMANAGER002");
|
||||
g_pEngineClient = (IVEngineClient*)GetInterface("engine.dll", "VEngineClient014");
|
||||
g_pEnginetrace = (IEngineTrace*)GetInterface("engine.dll", "EngineTraceClient004");
|
||||
g_pEnginevgui = (IEngineVGui*)GetInterface("engine.dll", "VEngineVGui001");
|
||||
g_pVGui = (vgui::IVGui*)GetInterface("vgui2.dll", "VGUI_ivgui008");
|
||||
g_pClient = (IBaseClientDLL*)GetInterface("client.dll", "VClient018");
|
||||
g_pMdlInfo = (IVModelInfoClient*)GetInterface("engine.dll", "VModelInfoClient004");
|
||||
g_pMdlRender = (IVModelRender*)GetInterface("engine.dll", "VEngineModel016");
|
||||
g_pMaterialSystem = (IMaterialSystem*)GetInterface("materialsystem.dll", "VMaterialSystem080");
|
||||
g_pCVar = (ICvar*)GetInterface("vstdlib.dll", "VEngineCvar007");
|
||||
g_pVGuiSystem = (vgui::ISystem*)GetInterface("vgui2.dll", "VGUI_System010");
|
||||
g_pVGuiSchemeManager = (vgui::ISchemeManager*)GetInterface("vgui2.dll", "VGUI_Scheme010");
|
||||
g_pVGuiInput = (vgui::IInput*)GetInterface("vgui2.dll", "VGUI_Input005");
|
||||
g_pFullFileSystem = (IFileSystem*)GetInterface("filesystem_stdio.dll", "VFileSystem017");
|
||||
g_pGameConsole = (IGameConsole*)GetInterface("client.dll", "GameConsole004");
|
||||
g_pEfx = (IVEfx*)GetInterface("engine.dll", "VEngineEffects001");
|
||||
g_pPhysProps = (IPhysicsSurfaceProps*)GetInterface("vphysics.dll", "VPhysicsSurfaceProps001");
|
||||
g_pRenderView = (IVRenderView*)GetInterface("engine.dll", "VEngineRenderView014");
|
||||
g_pDebugOverlay = (IVDebugOverlay*)GetInterface("engine.dll", "VDebugOverlay004");
|
||||
g_pEffects = (IEffects*)GetInterface("client.dll", "IEffects001");
|
||||
g_pStudioRender = (IStudioRender*)GetInterface("studiorender.dll", "VStudioRender026");
|
||||
|
||||
typedef PVOID(__cdecl* oKeyValuesSystem)();
|
||||
oKeyValuesSystem pkeyValuesSystem = (oKeyValuesSystem)GetProcAddress(GetModuleHandleA("vstdlib.dll"), "KeyValuesSystem");
|
||||
keyValuesSystem = (IKeyValuesSystem*)pkeyValuesSystem();
|
||||
#ifdef DEBUG
|
||||
printf("KeyValuesSystem = %x\n", keyValuesSystem);
|
||||
#endif
|
||||
myConMsg = (CONMSGPROC)GetProcAddress(GetModuleHandleA("tier0.dll"), "?ConMsg@@YAXPBDZZ");
|
||||
myConColorMsg = (CONCOLORMSGPROC)GetProcAddress(GetModuleHandleA("tier0.dll"), "?ConColorMsg@@YAXABVColor@@PBDZZ");
|
||||
|
||||
g_pGlobals = **(CGlobalVarsBase***)(FindPatternV2("client.dll", "A1 ? ? ? ? 5E 8B 40 10") + 1);
|
||||
g_pInput = *(CInput**)(FindPatternV2("client.dll", "B9 ? ? ? ? F3 0F 11 04 24 FF 50 10") + 1);
|
||||
g_pViewRenderBeams = *(IViewRenderBeams**)(FindPatternV2("client.dll", "B9 ?? ?? ?? ?? A1 ?? ?? ?? ?? FF 10 A1 ?? ?? ?? ?? B9") + 0x1);
|
||||
#ifdef DEBUG
|
||||
printf("g_pGlobals = %x\n", g_pGlobals);
|
||||
printf("g_pInput = %x\n", g_pInput);
|
||||
printf("g_pViewRenderBeams = %x\n", g_pViewRenderBeams);
|
||||
#endif
|
||||
FX_Tesla = (FX_TeslaFn)FindPatternV2("client.dll", "55 8B EC 81 EC ? ? ? ? 56 57 8B F9 8B 47 18");
|
||||
#ifdef DEBUG
|
||||
printf("FX_TeslaFn %x\n", FX_Tesla);
|
||||
#endif
|
||||
BloodSprayFn = (FX_BloodSprayFn)FindPatternV2("client.dll", "55 8B EC 8B 4D 08 F3 0F 10 51 ? 8D");
|
||||
#ifdef DEBUG
|
||||
printf("FX_BloodSprayFn %x\n", BloodSprayFn);
|
||||
#endif
|
||||
DispatchEffect = (FXDispatchEffect)FindPatternV2("client.dll", "55 8B EC 83 E4 F8 83 EC 20 56 57 8B F9 C7 44 24");
|
||||
#ifdef DEBUG
|
||||
printf("DispatchEffect %x\n", DispatchEffect);
|
||||
#endif
|
||||
g_pChatElement = (CHudChat*)FindHudElement("CHudChat");
|
||||
#ifdef DEBUG
|
||||
printf("Chat element %x\n", g_pChatElement);
|
||||
#endif
|
||||
|
||||
LoadFromFile = (void*)FindPatternV2("client.dll", "55 8B EC 83 EC 0C 53 8B 5D 08 56 8B F1 3B");
|
||||
#ifdef DEBUG
|
||||
printf("LoadFromFile %x\n", LoadFromFile);
|
||||
#endif
|
||||
g_pD3DDevice9 = **(IDirect3DDevice9***)(FindPatternV2("shaderapidx9.dll", "A1 ? ? ? ? 50 8B 08 FF 51 0C") + 1);
|
||||
#ifdef DEBUG
|
||||
printf("g_pD3DDevice9 %x\n", g_pD3DDevice9);
|
||||
#endif
|
||||
g_pMemAlloc = *(IMemAlloc**)(GetProcAddress(GetModuleHandle("tier0.dll"), "g_pMemAlloc"));
|
||||
#ifdef DEBUG
|
||||
printf("g_pMemAlloc %x\n", g_pMemAlloc);
|
||||
#endif
|
||||
|
||||
g_pClientState = **reinterpret_cast<CClientState***>(getvfunc<uintptr_t>(g_pEngineClient, 12) + 0x10);
|
||||
#ifdef DEBUG
|
||||
printf("g_pClientState %x\n", g_pClientState);
|
||||
#endif
|
||||
|
||||
CHudElement* g_pHudElement = (CHudElement*)FindHudElement("CCSGO_HudDeathNotice");
|
||||
#ifdef DEBUG
|
||||
printf("Hud element %x\n", g_pHudElement);
|
||||
#endif
|
||||
|
||||
auto SteamClient = ((ISteamClient * (__cdecl*)(void))GetProcAddress(GetModuleHandleA("steam_api.dll"), "SteamClient"))();
|
||||
g_SteamGameCoordinator = (ISteamGameCoordinator*)SteamClient->GetISteamGenericInterface((void*)1, (void*)1, "SteamGameCoordinator001");
|
||||
g_SteamUser = SteamClient->GetISteamUser((void*)1, (void*)1, "SteamUser019");
|
||||
#ifdef DEBUG
|
||||
printf("SteamClient %X\n", SteamClient);
|
||||
printf("g_SteamGameCoordinator %X\n", g_SteamGameCoordinator);
|
||||
printf("g_SteamUser %X\n", g_SteamUser);
|
||||
#endif
|
||||
|
||||
g_pClientLeafSystem = (IClientLeafSystem*)GetInterface("client.dll", "ClientLeafSystem002");
|
||||
#ifdef DEBUG
|
||||
printf("g_pClientLeafSystem %x\n", g_pClientLeafSystem);
|
||||
#endif
|
||||
g_pNetworkStringTableContainer = (INetworkStringTableContainer*)GetInterface("engine.dll", "VEngineClientStringTable001");
|
||||
#ifdef DEBUG
|
||||
printf("g_pNetworkStringTableContainer %x\n", g_pNetworkStringTableContainer);
|
||||
#endif
|
||||
|
||||
getPlayerViewmodelArmConfigForPlayerModel = relativeToAbsolute<decltype(getPlayerViewmodelArmConfigForPlayerModel)>(FindPatternV2("client.dll", "E8 ? ? ? ? 89 87 ? ? ? ? 6A") + 1);
|
||||
|
||||
g_pMdlCache = (IMDLCache*)GetInterface("datacache.dll", "MDLCache004");
|
||||
g_pEngineSound = (IEngineSound*)GetInterface("engine.dll", "IEngineSoundClient003");
|
||||
|
||||
g_pClientShadowMgr = *(IClientShadowMgr**)(FindPatternV2("client.dll", "A1 ? ? ? ? FF 90 ? ? ? ? 6A 00 6A 00") + 1);
|
||||
#ifdef DEBUG
|
||||
printf("g_pClientShadowMgr %x\n", g_pClientShadowMgr);
|
||||
#endif
|
||||
g_ViewRender = *(CCSViewRender**)(FindPatternV2("client.dll", "A1 ? ? ? ? B9 ? ? ? ? C7 05 ? ? ? ? ? ? ? ? FF 10") + 1);
|
||||
#ifdef DEBUG
|
||||
printf("g_ViewRender %x\n", g_ViewRender);
|
||||
#endif
|
||||
g_ClientMode = **(IClientMode***)((*(DWORD**)g_pClient)[10] + 0x5);
|
||||
#ifdef DEBUG
|
||||
printf("g_ClientMode %x\n", g_ClientMode);
|
||||
#endif
|
||||
|
||||
g_pInputSystem = (IInputSystem*)GetInterface("inputsystem.dll", "InputSystemVersion001");
|
||||
g_pVGuiSurface = (vgui::ISurface*)GetInterface("vguimatsurface.dll", "VGUI_Surface031");
|
||||
|
||||
prime = (uint8_t*)FindPatternV2("client.dll", "A1 ? ? ? ? 85 C0 75 07 83 F8 05 0F 94 C0 C3");
|
||||
#ifdef DEBUG
|
||||
printf("Prime found at %x\n", prime);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
auto is_code_ptr(void* ptr) -> bool
|
||||
{
|
||||
constexpr const DWORD protect_flags = PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
|
||||
|
||||
MEMORY_BASIC_INFORMATION out;
|
||||
VirtualQuery(ptr, &out, sizeof out);
|
||||
|
||||
return out.Type
|
||||
&& !(out.Protect & (PAGE_GUARD | PAGE_NOACCESS))
|
||||
&& out.Protect & protect_flags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
#ifndef INTERFACES
|
||||
#define INTERFACES
|
||||
#pragma once
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#define CLIENT_DLL
|
||||
|
||||
#include "GetVfunc.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include "sdk/icliententitylist.h"
|
||||
#include "sdk/CGameUI.h"
|
||||
#include "sdk/GameEventManager.h"
|
||||
#include "sdk/cdll_int.h"
|
||||
#include "sdk/ISurface.h"
|
||||
#include "sdk/IEngineVgui.h"
|
||||
#include "sdk/ivmodelinfo.h"
|
||||
#include "sdk/idatacache.h"
|
||||
#include "sdk/ILocalize.h"
|
||||
#include "sdk/IGameUI.h"
|
||||
#include "sdk/dt_recv.h"
|
||||
#include "sdk/client_class.h"
|
||||
#include "sdk/enginetrace.h"
|
||||
#include "sdk/gameconsole.h"
|
||||
#include "sdk/ivrenderview.h"
|
||||
#include "sdk/ivdebugoverlay.h"
|
||||
#include "sdk/vphysics_interface.h"
|
||||
#include "sdk/iefx.h"
|
||||
#include "sdk/c_input.h"
|
||||
#include "sdk/IEffects.h"
|
||||
#include "sdk/iviewrender_beams.h"
|
||||
#include "sdk/sdk_hud_chat.h"
|
||||
#include "sdk/fx.h"
|
||||
#include "sdk/globalvars_base.h"
|
||||
#include "sdk/IInput.h"
|
||||
#include "sdk/icliententity.h"
|
||||
#include "sdk/iclient.h"
|
||||
#include "sdk/cdll_int.h"
|
||||
#include "sdk/baseclientstate.h"
|
||||
#include "imgui/imgui_impl_dx9.h"
|
||||
#include "sdk/flashlighteffect.h"
|
||||
#include "sdk/inetchannel.h"
|
||||
#include "sdk/steam.h"
|
||||
#include "sdk/animationlayer.h"
|
||||
#include "sdk/clientleafsystem.h"
|
||||
#include "sdk/filesystem.h"
|
||||
#include "sdk/modelloader.h"
|
||||
#include "sdk/IEngineSound.h"
|
||||
#include "sdk/iclientshadowmgr.h"
|
||||
#include "sdk/cs_view_scene.h"
|
||||
#include "sdk/iclientmode.h"
|
||||
#include "sdk/itexture.h"
|
||||
#include "sdk/precipitation_shared.h"
|
||||
#include "sdk/iinputsystem.h"
|
||||
#include "vpkparser.h"
|
||||
#include "sdk/itempents.h"
|
||||
#include "sdk/c_te_legacytempents.h"
|
||||
|
||||
#include "XorStr.hpp"
|
||||
|
||||
PVOID FindHudElement(const char* name);
|
||||
|
||||
auto is_code_ptr(void* ptr) -> bool;
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
class IF {
|
||||
public:
|
||||
IClientEntityList* g_pEntityList = nullptr;
|
||||
CGameUI* g_pGameUI = nullptr;
|
||||
vgui::IPanel* g_pVGuiPanel = nullptr;
|
||||
CGameEventManager* g_pGameEvents = nullptr;
|
||||
IVEngineClient* g_pEngineClient = nullptr;
|
||||
vgui::ISurface* g_pVGuiSurface = nullptr;
|
||||
IEngineVGui* g_pEnginevgui = nullptr;
|
||||
vgui::IVGui* g_pVGui = nullptr;
|
||||
IBaseClientDLL* g_pClient = nullptr;
|
||||
IVModelInfoClient* g_pMdlInfo = nullptr;
|
||||
IVModelRender* g_pMdlRender = nullptr;
|
||||
IMaterialSystem* g_pMaterialSystem = nullptr;
|
||||
IKeyValuesSystem* keyValuesSystem = nullptr;
|
||||
ICvar* g_pCVar = nullptr;
|
||||
vgui::ISystem* g_pVGuiSystem = nullptr;
|
||||
vgui::ISchemeManager* g_pVGuiSchemeManager = nullptr;
|
||||
vgui::IInput* g_pVGuiInput = nullptr;
|
||||
IFileSystem* g_pFullFileSystem = nullptr;
|
||||
vgui::ILocalize* g_pVGuiLocalize = nullptr;
|
||||
IEngineTrace* g_pEnginetrace = nullptr;
|
||||
IVEfx* g_pEfx = nullptr;
|
||||
IGameConsole* g_pGameConsole = nullptr;
|
||||
IPhysicsSurfaceProps* g_pPhysProps = nullptr;
|
||||
IVRenderView* g_pRenderView = nullptr;
|
||||
IVDebugOverlay* g_pDebugOverlay = nullptr;
|
||||
CGlobalVarsBase* g_pGlobals = nullptr;
|
||||
CInput* g_pInput = nullptr;
|
||||
IEffects* g_pEffects = nullptr;
|
||||
IViewRenderBeams* g_pViewRenderBeams = nullptr;
|
||||
IStudioRender* g_pStudioRender = nullptr;
|
||||
CHudChat* g_pChatElement = nullptr;
|
||||
using FX_TeslaFn = void(__thiscall*)(CTeslaInfo&);
|
||||
FX_TeslaFn FX_Tesla = nullptr;
|
||||
using FX_BloodSprayFn = bool(__cdecl*)(const CEffectData&);
|
||||
FX_BloodSprayFn BloodSprayFn = nullptr;
|
||||
using FXDispatchEffect = int(__fastcall*)(const char* name, const CEffectData&);
|
||||
FXDispatchEffect DispatchEffect = nullptr;
|
||||
void Init();
|
||||
void* GetInterface(const char* dllname, const char* interfacename);
|
||||
typedef void(__cdecl* CONMSGPROC)(const char*, ...);
|
||||
CONMSGPROC myConMsg = nullptr;
|
||||
typedef void(__cdecl* CONCOLORMSGPROC)(Color& clr, const char*, ...);
|
||||
CONCOLORMSGPROC myConColorMsg = nullptr;
|
||||
PVOID LoadFromFile = nullptr;
|
||||
IDirect3DDevice9* g_pD3DDevice9 = nullptr;
|
||||
IMemAlloc* g_pMemAlloc = nullptr;
|
||||
ISteamGameCoordinator* g_SteamGameCoordinator = nullptr;
|
||||
ISteamUser* g_SteamUser = nullptr;
|
||||
CClientState* g_pClientState = nullptr;
|
||||
CHudElement* g_pHudElement = nullptr;
|
||||
IClientLeafSystem* g_pClientLeafSystem = nullptr;
|
||||
INetworkStringTableContainer* g_pNetworkStringTableContainer = nullptr;
|
||||
std::add_pointer_t<const char** __fastcall(const char* playerModelName)> getPlayerViewmodelArmConfigForPlayerModel;
|
||||
IMDLCache* g_pMdlCache = nullptr;
|
||||
IModelLoader* g_ModelLoader = nullptr;
|
||||
IEngineSound* g_pEngineSound = nullptr;
|
||||
IClientShadowMgr* g_pClientShadowMgr = nullptr;
|
||||
CCSViewRender* g_ViewRender = nullptr;
|
||||
IClientMode* g_ClientMode = nullptr;
|
||||
CGlobalVarsBase* g_Globals = nullptr;
|
||||
IInputSystem* g_pInputSystem = nullptr;
|
||||
ITempEnts* g_pTempEnts = nullptr;
|
||||
uint8_t* prime;
|
||||
char oldprime[5];
|
||||
};
|
||||
|
||||
extern IF iff;
|
||||
|
||||
typedef void* (__cdecl* tCreateInterface)(const char* name, int* returnCode);
|
||||
|
||||
template <typename T>
|
||||
static constexpr auto relativeToAbsolute(uintptr_t address) noexcept
|
||||
{
|
||||
return (T)(address + 4 + *reinterpret_cast<std::int32_t*>(address));
|
||||
}
|
||||
|
||||
|
||||
namespace vgui {
|
||||
inline vgui::IInput* input()
|
||||
{
|
||||
return iff.g_pVGuiInput;
|
||||
}
|
||||
|
||||
inline vgui::ISchemeManager* scheme()
|
||||
{
|
||||
return iff.g_pVGuiSchemeManager;
|
||||
}
|
||||
|
||||
inline vgui::ISurface* surface()
|
||||
{
|
||||
return iff.g_pVGuiSurface;
|
||||
}
|
||||
|
||||
inline vgui::ISystem* system()
|
||||
{
|
||||
return iff.g_pVGuiSystem;
|
||||
}
|
||||
|
||||
inline vgui::IVGui* ivgui()
|
||||
{
|
||||
return iff.g_pVGui;
|
||||
}
|
||||
|
||||
inline vgui::IPanel* ipanel()
|
||||
{
|
||||
return iff.g_pVGuiPanel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ICvar2 : public ICvar
|
||||
{
|
||||
public:
|
||||
ConVar* FindVar2(const char* var)
|
||||
{
|
||||
printf("Trying to find var %s\n", var);
|
||||
typedef ConVar* (*oFindVar)(void*, const char*);
|
||||
return getvfunc<oFindVar>(this, 16)(this, var);
|
||||
}
|
||||
|
||||
template <typename... Values>
|
||||
void ConsoleColorPrintf2(const Color& MsgColor, const char* szMsgFormat, Values... Parameters)
|
||||
{
|
||||
printf("Trying to print %s\n", szMsgFormat);
|
||||
typedef void(*oConsoleColorPrintf)(void*, const Color&, const char*, ...);
|
||||
return getvfunc<oConsoleColorPrintf>(this, 25)(this, MsgColor, szMsgFormat, Parameters...);
|
||||
}
|
||||
};
|
||||
|
||||
struct model_t
|
||||
{
|
||||
void* fnHandle;
|
||||
char szName[260];
|
||||
__int32 nLoadFlags;
|
||||
__int32 nServerCount;
|
||||
__int32 type;
|
||||
__int32 flags;
|
||||
Vector vecMins;
|
||||
Vector vecMaxs;
|
||||
float radius;
|
||||
char pad[0x1C];
|
||||
};
|
||||
|
||||
|
||||
void AngleVectors(const Vector& angles, Vector* forward, Vector* right, Vector* up);
|
||||
|
||||
enum ItemDefinitionIndex
|
||||
{
|
||||
ITEM_NONE = 0,
|
||||
WEAPON_DEAGLE = 1,
|
||||
WEAPON_ELITE = 2,
|
||||
WEAPON_FIVESEVEN = 3,
|
||||
WEAPON_GLOCK = 4,
|
||||
WEAPON_AK47 = 7,
|
||||
WEAPON_AUG = 8,
|
||||
WEAPON_AWP = 9,
|
||||
WEAPON_FAMAS = 10,
|
||||
WEAPON_G3SG1 = 11,
|
||||
WEAPON_GALILAR = 13,
|
||||
WEAPON_M249 = 14,
|
||||
WEAPON_M4A1 = 16,
|
||||
WEAPON_MAC10 = 17,
|
||||
WEAPON_P90 = 19,
|
||||
WEAPON_UMP45 = 24,
|
||||
WEAPON_XM1014 = 25,
|
||||
WEAPON_BIZON = 26,
|
||||
WEAPON_MAG7 = 27,
|
||||
WEAPON_NEGEV = 28,
|
||||
WEAPON_SAWEDOFF = 29,
|
||||
WEAPON_TEC9 = 30,
|
||||
WEAPON_TASER = 31,
|
||||
WEAPON_HKP2000 = 32,
|
||||
WEAPON_MP7 = 33,
|
||||
WEAPON_MP9 = 34,
|
||||
WEAPON_NOVA = 35,
|
||||
WEAPON_P250 = 36,
|
||||
WEAPON_SCAR20 = 38,
|
||||
WEAPON_SG553 = 39,
|
||||
WEAPON_SSG08 = 40,
|
||||
WEAPON_KNIFE_GOLD = 41,
|
||||
WEAPON_KNIFE = 42,
|
||||
WEAPON_FLASHBANG = 43,
|
||||
WEAPON_HEGRENADE = 44,
|
||||
WEAPON_SMOKEGRENADE = 45,
|
||||
WEAPON_MOLOTOV = 46,
|
||||
WEAPON_DECOY = 47,
|
||||
WEAPON_INCGRENADE = 48,
|
||||
WEAPON_C4 = 49,
|
||||
WEAPON_KNIFE_T = 59,
|
||||
WEAPON_M4A1_SILENCER = 60,
|
||||
WEAPON_USP_SILENCER = 61,
|
||||
WEAPON_CZ75A = 63,
|
||||
WEAPON_REVOLVER = 64,
|
||||
WEAPON_KNIFE_BAYONET = 500,
|
||||
WEAPON_KNIFE_FLIP = 505,
|
||||
WEAPON_KNIFE_GUT = 506,
|
||||
WEAPON_KNIFE_KARAMBIT = 507,
|
||||
WEAPON_KNIFE_M9_BAYONET = 508,
|
||||
WEAPON_KNIFE_TACTICAL = 509,
|
||||
WEAPON_KNIFE_FALCHION = 512,
|
||||
WEAPON_KNIFE_SURVIVAL_BOWIE = 514,
|
||||
WEAPON_KNIFE_BUTTERFLY = 515,
|
||||
WEAPON_KNIFE_PUSH = 516,
|
||||
GLOVE_STUDDED_BLOODHOUND = 5027,
|
||||
GLOVE_T_SIDE = 5028,
|
||||
GLOVE_CT_SIDE = 5029,
|
||||
GLOVE_SPORTY = 5030,
|
||||
GLOVE_SLICK = 5031,
|
||||
GLOVE_LEATHER_WRAP = 5032,
|
||||
GLOVE_MOTORCYCLE = 5033,
|
||||
GLOVE_SPECIALIST = 5034,
|
||||
MAX_ITEMDEFINITIONINDEX
|
||||
};
|
||||
|
||||
|
||||
static int random(int min, int max) noexcept
|
||||
{
|
||||
return rand() % (max - min + 1) + min;
|
||||
}
|
||||
|
||||
|
||||
enum Sequence
|
||||
{
|
||||
SEQUENCE_DEFAULT_DRAW = 0,
|
||||
SEQUENCE_DEFAULT_IDLE1 = 1,
|
||||
SEQUENCE_DEFAULT_IDLE2 = 2,
|
||||
SEQUENCE_DEFAULT_LIGHT_MISS1 = 3,
|
||||
SEQUENCE_DEFAULT_LIGHT_MISS2 = 4,
|
||||
SEQUENCE_DEFAULT_HEAVY_MISS1 = 9,
|
||||
SEQUENCE_DEFAULT_HEAVY_HIT1 = 10,
|
||||
SEQUENCE_DEFAULT_HEAVY_BACKSTAB = 11,
|
||||
SEQUENCE_DEFAULT_LOOKAT01 = 12,
|
||||
|
||||
SEQUENCE_BUTTERFLY_DRAW = 0,
|
||||
SEQUENCE_BUTTERFLY_DRAW2 = 1,
|
||||
SEQUENCE_BUTTERFLY_LOOKAT01 = 13,
|
||||
SEQUENCE_BUTTERFLY_LOOKAT03 = 15,
|
||||
|
||||
SEQUENCE_FALCHION_IDLE1 = 1,
|
||||
SEQUENCE_FALCHION_HEAVY_MISS1 = 8,
|
||||
SEQUENCE_FALCHION_HEAVY_MISS1_NOFLIP = 9,
|
||||
SEQUENCE_FALCHION_LOOKAT01 = 12,
|
||||
SEQUENCE_FALCHION_LOOKAT02 = 13,
|
||||
|
||||
SEQUENCE_DAGGERS_IDLE1 = 1,
|
||||
SEQUENCE_DAGGERS_LIGHT_MISS1 = 2,
|
||||
SEQUENCE_DAGGERS_LIGHT_MISS5 = 6,
|
||||
SEQUENCE_DAGGERS_HEAVY_MISS2 = 11,
|
||||
SEQUENCE_DAGGERS_HEAVY_MISS1 = 12,
|
||||
|
||||
SEQUENCE_BOWIE_IDLE1 = 1,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
+1949
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
#include "NetVarManager.hpp"
|
||||
#include <cctype>
|
||||
|
||||
#ifdef DUMP_NETVARS
|
||||
#define IF_DUMPING(...) __VA_ARGS__
|
||||
#else
|
||||
#define IF_DUMPING(...)
|
||||
#endif
|
||||
|
||||
IF_DUMPING(static FILE* s_fp;)
|
||||
|
||||
netvar_manager::netvar_manager()
|
||||
{
|
||||
IF_DUMPING(fopen_s(&s_fp, "netvar_dump.txt", "w");)
|
||||
for (auto clazz = iff.g_pClient->GetAllClasses(); clazz; clazz = clazz->m_pNext)
|
||||
if (clazz->m_pRecvTable)
|
||||
dump_recursive(clazz->m_pNetworkName, clazz->m_pRecvTable, 0);
|
||||
IF_DUMPING(fclose(s_fp);)
|
||||
}
|
||||
|
||||
auto netvar_manager::dump_recursive(const char* base_class, RecvTable* table, const std::uint16_t offset) -> void
|
||||
{
|
||||
for (auto i = 0; i < table->m_nProps; ++i)
|
||||
{
|
||||
const auto prop_ptr = &table->m_pProps[i];
|
||||
|
||||
if (!prop_ptr || isdigit(prop_ptr->m_pVarName[0]))
|
||||
continue;
|
||||
|
||||
if (fnv::hash_runtime(prop_ptr->m_pVarName) == FNV("baseclass"))
|
||||
continue;
|
||||
|
||||
if (prop_ptr->m_RecvType == DPT_DataTable &&
|
||||
prop_ptr->m_pDataTable != nullptr &&
|
||||
prop_ptr->m_pDataTable->m_pNetTableName[0] == 'D')
|
||||
{
|
||||
dump_recursive(base_class, prop_ptr->m_pDataTable, std::uint16_t(offset + prop_ptr->m_Offset));
|
||||
}
|
||||
|
||||
char hash_name[256];
|
||||
|
||||
strcpy_s(hash_name, base_class);
|
||||
strcat_s(hash_name, "->");
|
||||
strcat_s(hash_name, prop_ptr->m_pVarName);
|
||||
|
||||
const auto hash = fnv::hash_runtime(hash_name);
|
||||
const auto total_offset = std::uint16_t(offset + prop_ptr->m_Offset);
|
||||
|
||||
IF_DUMPING(fprintf(s_fp, "%s\t0x%04X\t%s\n", base_class, total_offset, prop_ptr->m_pVarName);)
|
||||
|
||||
m_props[hash] =
|
||||
{
|
||||
prop_ptr,
|
||||
total_offset
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
#ifndef NETVARMGR
|
||||
#define NETVARMGR
|
||||
#pragma once
|
||||
|
||||
#include "sdk/cdll_int.h"
|
||||
#include "sdk/dt_recv.h"
|
||||
#include "sdk/client_class.h"
|
||||
#include <vector>
|
||||
|
||||
#include "Interfaces.hpp"
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Type, Type OffsetBasis, Type Prime>
|
||||
struct size_dependant_data
|
||||
{
|
||||
using type = Type;
|
||||
constexpr static auto k_offset_basis = OffsetBasis;
|
||||
constexpr static auto k_prime = Prime;
|
||||
};
|
||||
|
||||
template <size_t Bits>
|
||||
struct size_selector;
|
||||
|
||||
template <>
|
||||
struct size_selector<32>
|
||||
{
|
||||
using type = size_dependant_data<std::uint32_t, 0x811c9dc5ul, 16777619ul>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct size_selector<64>
|
||||
{
|
||||
using type = size_dependant_data<std::uint64_t, 0xcbf29ce484222325ull, 1099511628211ull>;
|
||||
};
|
||||
|
||||
template <std::size_t Size>
|
||||
class fnv_hash
|
||||
{
|
||||
private:
|
||||
using data_t = typename size_selector<Size>::type;
|
||||
|
||||
public:
|
||||
using hash = typename data_t::type;
|
||||
|
||||
private:
|
||||
constexpr static auto k_offset_basis = data_t::k_offset_basis;
|
||||
constexpr static auto k_prime = data_t::k_prime;
|
||||
|
||||
public:
|
||||
template <std::size_t N>
|
||||
static __forceinline constexpr auto hash_constexpr(const char(&str)[N], const std::size_t size = N) -> hash
|
||||
{
|
||||
return static_cast<hash>(1ull * (size == 1
|
||||
? (k_offset_basis ^ str[0])
|
||||
: (hash_constexpr(str, size - 1) ^ str[size - 1])) * k_prime);
|
||||
}
|
||||
|
||||
static auto __forceinline hash_runtime(const char* str) -> hash
|
||||
{
|
||||
auto result = k_offset_basis;
|
||||
do
|
||||
{
|
||||
result ^= *str++;
|
||||
result *= k_prime;
|
||||
} while (*(str - 1) != '\0');
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace fnv2 {
|
||||
constexpr uint32_t offsetBasis = 0x811c9dc5;
|
||||
constexpr uint32_t prime = 0x1000193;
|
||||
|
||||
constexpr uint32_t hash(const char* str, const uint32_t value = offsetBasis) noexcept
|
||||
{
|
||||
return *str ? hash(str + 1, (value ^ *str) * static_cast<unsigned long long>(prime)) : value;
|
||||
}
|
||||
|
||||
constexpr uint32_t hashRuntime(const char* str) noexcept
|
||||
{
|
||||
auto value = offsetBasis;
|
||||
|
||||
while (*str) {
|
||||
value ^= *str++;
|
||||
value *= prime;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
using fnv = ::detail::fnv_hash<sizeof(void*) * 8>;
|
||||
|
||||
#define FNV(str) (std::integral_constant<fnv::hash, fnv::hash_constexpr(str)>::value)
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
|
||||
class netvar_manager
|
||||
{
|
||||
private:
|
||||
struct stored_data
|
||||
{
|
||||
RecvProp* prop_ptr;
|
||||
std::uint16_t class_relative_offset;
|
||||
};
|
||||
|
||||
public:
|
||||
static auto get() -> const netvar_manager&
|
||||
{
|
||||
static netvar_manager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto get_offset(const fnv::hash hash) const -> std::uint16_t
|
||||
{
|
||||
return m_props.at(hash).class_relative_offset;
|
||||
}
|
||||
|
||||
auto get_prop(const fnv::hash hash) const -> RecvProp*
|
||||
{
|
||||
return m_props.at(hash).prop_ptr;
|
||||
}
|
||||
|
||||
__declspec(noinline) static auto get_offset_by_hash(const fnv::hash hash) -> std::uint16_t
|
||||
{
|
||||
return get().get_offset(hash);
|
||||
}
|
||||
|
||||
template<fnv::hash Hash>
|
||||
static auto get_offset_by_hash_cached() -> std::uint16_t
|
||||
{
|
||||
static auto offset = std::uint16_t(0);
|
||||
if (!offset)
|
||||
offset = get_offset_by_hash(Hash);
|
||||
return offset;
|
||||
}
|
||||
|
||||
private:
|
||||
netvar_manager();
|
||||
auto dump_recursive(const char* base_class, RecvTable* table, std::uint16_t offset) -> void;
|
||||
|
||||
private:
|
||||
std::map<fnv::hash, stored_data> m_props;
|
||||
};
|
||||
|
||||
|
||||
#define PNETVAR_OFFSET(funcname, class_name, var_name, offset, ...) \
|
||||
auto funcname() -> std::add_pointer_t<__VA_ARGS__> \
|
||||
{ \
|
||||
constexpr auto hash = fnv::hash_constexpr(class_name "->" var_name); \
|
||||
const auto addr = std::uintptr_t(this) + offset + netvar_manager::get_offset_by_hash_cached<hash>(); \
|
||||
return reinterpret_cast<std::add_pointer_t<__VA_ARGS__>>(addr); \
|
||||
}
|
||||
|
||||
#define PNETVAR(funcname, class_name, var_name, ...) \
|
||||
PNETVAR_OFFSET(funcname, class_name, var_name, 0, __VA_ARGS__)
|
||||
|
||||
#define NETVAR_OFFSET(funcname, class_name, var_name, offset, ...) \
|
||||
auto funcname() -> std::add_lvalue_reference_t<__VA_ARGS__> \
|
||||
{ \
|
||||
constexpr auto hash = fnv::hash_constexpr(class_name "->" var_name); \
|
||||
const auto addr = std::uintptr_t(this) + offset + netvar_manager::get_offset_by_hash_cached<hash>(); \
|
||||
return *reinterpret_cast<std::add_pointer_t<__VA_ARGS__>>(addr); \
|
||||
}
|
||||
|
||||
#define NETVAR(funcname, class_name, var_name, ...) \
|
||||
NETVAR_OFFSET(funcname, class_name, var_name, 0, __VA_ARGS__)
|
||||
|
||||
#define NETPROP(funcname, class_name, var_name) \
|
||||
static auto funcname() -> RecvProp* \
|
||||
{ \
|
||||
constexpr auto hash = fnv::hash_constexpr(class_name "->" var_name); \
|
||||
static RecvProp* prop_ptr; \
|
||||
if(!prop_ptr) prop_ptr = netvar_manager::get().get_prop(hash); \
|
||||
return prop_ptr; \
|
||||
}
|
||||
|
||||
class recv_prop_hook
|
||||
{
|
||||
public:
|
||||
recv_prop_hook(RecvProp* prop, const RecvVarProxyFn proxy_fn) :
|
||||
m_property(prop),
|
||||
m_original_proxy_fn(prop->m_ProxyFn)
|
||||
{
|
||||
set_proxy_function(proxy_fn);
|
||||
}
|
||||
|
||||
~recv_prop_hook()
|
||||
{
|
||||
m_property->m_ProxyFn = m_original_proxy_fn;
|
||||
}
|
||||
|
||||
auto get_original_function() const -> RecvVarProxyFn
|
||||
{
|
||||
return m_original_proxy_fn;
|
||||
}
|
||||
|
||||
auto set_proxy_function(const RecvVarProxyFn proxy_fn) const -> void
|
||||
{
|
||||
m_property->m_ProxyFn = proxy_fn;
|
||||
}
|
||||
|
||||
private:
|
||||
RecvProp* m_property;
|
||||
RecvVarProxyFn m_original_proxy_fn;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,265 @@
|
||||
#include "Other.hpp"
|
||||
#include "PatternScan.hpp"
|
||||
|
||||
|
||||
|
||||
void UpdateFlashLight(CFlashlightEffect* pFlashLight, const Vector& vecPos, const Vector& vecForward, const Vector& vecRight, const Vector& vecUp)
|
||||
{
|
||||
typedef void(__thiscall* UpdateLight_t)(void*, int, const Vector&, const Vector&, const Vector&, const Vector&, float, float, float, bool, const char*);
|
||||
|
||||
static UpdateLight_t oUpdateLight = NULL;
|
||||
|
||||
if (!oUpdateLight)
|
||||
{
|
||||
DWORD callInstruction = FindPatternV2("client.dll", "E8 ? ?? ? ? 8B 06 F3 0F 10 46");
|
||||
DWORD relativeAddress = *(DWORD*)(callInstruction + 1);
|
||||
DWORD nextInstruction = callInstruction + 5;
|
||||
oUpdateLight = (UpdateLight_t)(nextInstruction + relativeAddress);
|
||||
}
|
||||
|
||||
oUpdateLight(pFlashLight, pFlashLight->m_nEntIndex, vecPos, vecForward, vecRight, vecUp,
|
||||
pFlashLight->m_flFov, pFlashLight->m_flFarZ, pFlashLight->m_flLinearAtten, pFlashLight->m_bCastsShadows,
|
||||
pFlashLight->m_textureName);
|
||||
}
|
||||
|
||||
|
||||
CFlashlightEffect* CreateFlashLight(int nEntIndex, const char* pszTextureName, float flFov, float flFarZ, float flLinearAtten)
|
||||
{
|
||||
|
||||
CFlashlightEffect* pFlashLight = reinterpret_cast<CFlashlightEffect*>(iff.g_pMemAlloc->Alloc(sizeof(CFlashlightEffect)));
|
||||
|
||||
if (!pFlashLight)
|
||||
return NULL;
|
||||
|
||||
static DWORD oConstructor = FindPatternV2("client.dll", "55 8B EC F3 0F 10 45 ? B8");
|
||||
|
||||
__asm
|
||||
{
|
||||
movss xmm3, flFov
|
||||
mov ecx, pFlashLight
|
||||
push flLinearAtten
|
||||
push flFarZ
|
||||
push pszTextureName
|
||||
push nEntIndex
|
||||
call oConstructor
|
||||
}
|
||||
pFlashLight->m_bIsOn = true;
|
||||
|
||||
|
||||
return pFlashLight;
|
||||
}
|
||||
|
||||
void DestroyFlashLight(CFlashlightEffect* pFlashLight)
|
||||
{
|
||||
static DWORD oDestructor = FindPatternV2("client.dll", "56 8B F1 E8 ? ? ? ? 8B 4E 28");
|
||||
|
||||
__asm
|
||||
{
|
||||
mov ecx, pFlashLight
|
||||
push ecx
|
||||
call oDestructor
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AngleVectors(const Vector& angles, Vector* forward, Vector* right, Vector* up)
|
||||
{
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
SinCos(DEG2RAD(angles[1]), &sy, &cy);
|
||||
SinCos(DEG2RAD(angles[0]), &sp, &cp);
|
||||
SinCos(DEG2RAD(angles[2]), &sr, &cr);
|
||||
|
||||
if (forward)
|
||||
{
|
||||
forward->x = cp * cy;
|
||||
forward->y = cp * sy;
|
||||
forward->z = -sp;
|
||||
}
|
||||
|
||||
if (right)
|
||||
{
|
||||
right->x = (-1 * sr * sp * cy + -1 * cr * -sy);
|
||||
right->y = (-1 * sr * sp * sy + -1 * cr * cy);
|
||||
right->z = -1 * sr * cp;
|
||||
}
|
||||
|
||||
if (up)
|
||||
{
|
||||
up->x = (cr * sp * cy + -sr * -sy);
|
||||
up->y = (cr * sp * sy + -sr * cy);
|
||||
up->z = cr * cp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool ToggleButton(ButtonCode_t code)
|
||||
{
|
||||
static int buttonPressedTick = 0;
|
||||
if (iff.g_pInputSystem->IsButtonDown(code) && (GetTickCount64() - buttonPressedTick) > 300)
|
||||
{
|
||||
buttonPressedTick = GetTickCount64();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FlashlightRun(C_BasePlayer* local)
|
||||
{
|
||||
static CFlashlightEffect* pFlashLight = NULL;
|
||||
|
||||
if (opt.disconnected)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("nullify pFlashlight bc disconnected\n");
|
||||
#endif
|
||||
pFlashLight = NULL;
|
||||
opt.disconnected = 0;
|
||||
}
|
||||
|
||||
if (ToggleButton(KEY_L))
|
||||
{
|
||||
if (!pFlashLight)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("creating fl\n");
|
||||
#endif
|
||||
pFlashLight = CreateFlashLight(local->GetIndex(), g_Options.flashlightTexture.value->mystring, *g_Options.flashlightFOV, *g_Options.flashlightFarZ, *g_Options.flashlightLinearAtten);
|
||||
iff.g_pEngineClient->ExecuteClientCmd("play items/flashlight1.wav");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("destroying fl\n");
|
||||
#endif
|
||||
DestroyFlashLight(pFlashLight);
|
||||
pFlashLight = NULL;
|
||||
iff.g_pEngineClient->ExecuteClientCmd("play items/flashlight1.wav");
|
||||
}
|
||||
}
|
||||
|
||||
if (pFlashLight)
|
||||
{
|
||||
Vector f, r, u;
|
||||
Vector viewAngles;
|
||||
|
||||
iff.g_pEngineClient->GetViewAngles(viewAngles);
|
||||
AngleVectors(viewAngles, &f, &r, &u);
|
||||
|
||||
pFlashLight->m_bIsOn = true;
|
||||
pFlashLight->m_bCastsShadows = *g_Options.flashlightShadows;
|
||||
pFlashLight->m_flFov = *g_Options.flashlightFOV;
|
||||
|
||||
UpdateFlashLight(pFlashLight, local->GetOrigin() + local->GetViewOffset(), f, r, u);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define DRAW_SCREEN_EFFECT(material) \
|
||||
{ \
|
||||
const auto drawFunction = relativeToAbsolute<uintptr_t>(FindPatternV2("client.dll", "E8 ? ? ? ? 83 C4 0C 8D 4D F8") + 1); \
|
||||
int w, h; \
|
||||
iff.g_pVGuiSurface->GetScreenSize(w, h); \
|
||||
__asm { \
|
||||
__asm push h \
|
||||
__asm push w \
|
||||
__asm push 0 \
|
||||
__asm xor edx, edx \
|
||||
__asm mov ecx, material \
|
||||
__asm call drawFunction \
|
||||
__asm add esp, 12 \
|
||||
} \
|
||||
}
|
||||
|
||||
void NightvisionRun(C_BasePlayer* local) {
|
||||
|
||||
static int m_flNightVisionAlpha = NetvarSys::Get().GetOffset("DT_CSPlayer", "m_flFlashDuration") - 0x1C;
|
||||
|
||||
if (ToggleButton(KEY_N) )
|
||||
{
|
||||
if (!local->GetNightvision())
|
||||
{
|
||||
local->GetNightvision() = true;
|
||||
*(float*)(uintptr_t(local) + m_flNightVisionAlpha) = 1.0f;
|
||||
iff.g_pEngineClient->ExecuteClientCmd("play items/nvg_on.wav");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
local->GetNightvision() = false;
|
||||
*(float*)(uintptr_t(local) + m_flNightVisionAlpha) = 0;
|
||||
iff.g_pEngineClient->ExecuteClientCmd("play items/nvg_off.wav");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void do_precipitation() {
|
||||
static void* rain_networkable = nullptr;
|
||||
C_Precipitation* rain_ent = (C_Precipitation*)iff.g_pEntityList->GetClientEntity(MAX_EDICTS - 1);
|
||||
static ClientClass* precipitation_client_class = nullptr;
|
||||
|
||||
|
||||
|
||||
|
||||
if (!iff.g_pEngineClient->IsInGame() || !iff.g_pEngineClient->IsConnected()) {
|
||||
rain_networkable = rain_ent = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
int localplayer_index = iff.g_pEngineClient->GetLocalPlayer();
|
||||
C_BasePlayer* localplayer = static_cast<C_BasePlayer*>(iff.g_pEntityList->GetClientEntity(localplayer_index));
|
||||
if (!localplayer) return;
|
||||
|
||||
if (!(localplayer->GetLifeState() == LIFE_ALIVE && localplayer->GetHealth() > 0))
|
||||
return;
|
||||
|
||||
|
||||
|
||||
if (!precipitation_client_class) {
|
||||
for (auto pclass = iff.g_pClient->GetAllClasses(); pclass && !precipitation_client_class; pclass = pclass->m_pNext)
|
||||
if (strstr(pclass->GetName(), "CPrecipitation"))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("class found %x\n", pclass);
|
||||
#endif
|
||||
precipitation_client_class = pclass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
if (!rain_ent && precipitation_client_class && precipitation_client_class->m_pCreateFn) {
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Creating precipitation\n");
|
||||
#endif
|
||||
|
||||
rain_networkable = ((void* (*)(int, int))precipitation_client_class->m_pCreateFn)(MAX_EDICTS - 1, 0);
|
||||
|
||||
if (rain_networkable) {
|
||||
rain_ent = (C_Precipitation*)iff.g_pEntityList->GetClientEntity(MAX_EDICTS - 1);
|
||||
|
||||
rain_ent->GetPrecipitationType() = (PrecipitationType_t)*g_Options.weathertype;
|
||||
|
||||
rain_ent->PreDataUpdate(DataUpdateType_t::DATA_UPDATE_CREATED);
|
||||
rain_ent->OnPreDataChanged(DataUpdateType_t::DATA_UPDATE_CREATED);
|
||||
|
||||
rain_ent->GetMins() = Vector(-32767.0f, -32767.0f, -32767.0f);
|
||||
rain_ent->GetMaxs() = Vector(32767.0f, 32767.0f, 32767.0f);
|
||||
|
||||
rain_ent->OnDataChanged(DataUpdateType_t::DATA_UPDATE_CREATED);
|
||||
rain_ent->PostDataUpdate(DataUpdateType_t::DATA_UPDATE_CREATED);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Created precipitation %x\n", rain_ent);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef OTHER
|
||||
#define OTHER
|
||||
#pragma once
|
||||
|
||||
#include "Interfaces.hpp"
|
||||
#include "Options.hpp"
|
||||
|
||||
#include "sdk/c_baseentity.h"
|
||||
|
||||
void FlashlightRun(C_BasePlayer* local);
|
||||
void NightvisionRun(C_BasePlayer* local);
|
||||
|
||||
void do_precipitation();
|
||||
|
||||
#endif OTHER
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "PatternScan.hpp"
|
||||
|
||||
|
||||
DWORD WaitOnModuleHandle(std::string moduleName)
|
||||
{
|
||||
DWORD ModuleHandle = NULL;
|
||||
while (!ModuleHandle)
|
||||
{
|
||||
ModuleHandle = (DWORD)GetModuleHandle(moduleName.c_str());
|
||||
if (!ModuleHandle)
|
||||
Sleep(50);
|
||||
}
|
||||
return ModuleHandle;
|
||||
}
|
||||
|
||||
DWORD FindPatternV2(std::string moduleName, std::string pattern)
|
||||
{
|
||||
const char* pat = pattern.c_str();
|
||||
DWORD firstMatch = 0;
|
||||
DWORD rangeStart = (DWORD)GetModuleHandleA(moduleName.c_str());
|
||||
MODULEINFO miModInfo; GetModuleInformation(GetCurrentProcess(), (HMODULE)rangeStart, &miModInfo, sizeof(MODULEINFO));
|
||||
DWORD rangeEnd = rangeStart + miModInfo.SizeOfImage;
|
||||
for (DWORD pCur = rangeStart; pCur < rangeEnd; pCur++)
|
||||
{
|
||||
if (!*pat)
|
||||
return firstMatch;
|
||||
|
||||
if (*(PBYTE)pat == '\?' || *(BYTE*)pCur == getByte(pat))
|
||||
{
|
||||
if (!firstMatch)
|
||||
firstMatch = pCur;
|
||||
|
||||
if (!pat[2])
|
||||
return firstMatch;
|
||||
|
||||
if (*(PWORD)pat == '\?\?' || *(PBYTE)pat != '\?')
|
||||
pat += 3;
|
||||
|
||||
else
|
||||
pat += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pat = pattern.c_str();
|
||||
firstMatch = 0;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool bCompare(const BYTE* Data, const BYTE* Mask, const char* szMask)
|
||||
{
|
||||
for (; *szMask; ++szMask, ++Mask, ++Data)
|
||||
{
|
||||
if (*szMask == 'x' && *Mask != *Data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (*szMask) == 0;
|
||||
}
|
||||
|
||||
DWORD FindPattern(std::string moduleName, BYTE* Mask, char* szMask)
|
||||
{
|
||||
DWORD Address = WaitOnModuleHandle(moduleName.c_str());
|
||||
MODULEINFO ModInfo; GetModuleInformation(GetCurrentProcess(), (HMODULE)Address, &ModInfo, sizeof(MODULEINFO));
|
||||
DWORD Length = ModInfo.SizeOfImage;
|
||||
for (DWORD c = 0; c < Length; c += 1)
|
||||
{
|
||||
if (bCompare((BYTE*)(Address + c), Mask, szMask))
|
||||
{
|
||||
return (DWORD)(Address + c);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef PATTERNSCAN
|
||||
#define PATTERNSCAN
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Psapi.h>
|
||||
#include <string>
|
||||
#define INRANGE(x,a,b) (x >= a && x <= b)
|
||||
#define getBits( x ) (INRANGE((x&(~0x20)),'A','F') ? ((x&(~0x20)) - 'A' + 0xa) : (INRANGE(x,'0','9') ? x - '0' : 0))
|
||||
#define getByte( x ) (getBits(x[0]) << 4 | getBits(x[1]))
|
||||
|
||||
DWORD WaitOnModuleHandle(std::string moduleName);
|
||||
DWORD FindPatternV2(std::string moduleName, std::string pattern);
|
||||
bool bCompare(const BYTE* Data, const BYTE* Mask, const char* szMask);
|
||||
DWORD FindPattern(std::string moduleName, BYTE* Mask, char* szMask);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
#include "PlayerInventory.hpp"
|
||||
|
||||
|
||||
void CSharedObjectTypeCache::AddObject(void* obj)
|
||||
{
|
||||
typedef void(__thiscall* tOriginal)(void*, void*);
|
||||
getvfunc<tOriginal>(this, 1)(this, obj);
|
||||
}
|
||||
|
||||
void CSharedObjectTypeCache::RemoveObject(void* obj)
|
||||
{
|
||||
typedef void(__thiscall* tOriginal)(void*, void*);
|
||||
getvfunc<tOriginal>(this, 3)(this, obj);
|
||||
}
|
||||
|
||||
std::vector<CEconItem*> CSharedObjectTypeCache::GetEconItems()
|
||||
{
|
||||
std::vector<CEconItem*> ret;
|
||||
|
||||
auto size = *reinterpret_cast<size_t*>(this + 0x18);
|
||||
|
||||
auto data = *reinterpret_cast<uintptr_t**>(this + 0x4);
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
ret.push_back(reinterpret_cast<CEconItem*>(data[i]));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPE>
|
||||
void CEconItem::SetAttributeValue(int index, TYPE val)
|
||||
{
|
||||
auto v15 = (DWORD*)GetItemSchema();
|
||||
auto v16 = *(DWORD*)(v15[72] + 4 * index);
|
||||
|
||||
static auto fnSetDynamicAttributeValue
|
||||
= reinterpret_cast<int(__thiscall*)(CEconItem*, DWORD, void*)>(
|
||||
FindPatternV2("client.dll", "55 8B EC 83 E4 F8 83 EC 3C 53 8B 5D 08 56 57 6A 00")
|
||||
);
|
||||
|
||||
fnSetDynamicAttributeValue(this, v16, &val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int C_EconItemDefinition::get_equipped_position()
|
||||
{
|
||||
return *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this) + 0x24C);
|
||||
}
|
||||
|
||||
const char* C_EconItemDefinition::get_world_model_name()
|
||||
{
|
||||
return *reinterpret_cast<const char**>(uintptr_t(this) + 0x9C);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t* CEconItem::GetAccountID()
|
||||
{
|
||||
return reinterpret_cast<uint32_t*>(this + 0x1C);
|
||||
}
|
||||
uint64_t* CEconItem::GetItemID()
|
||||
{
|
||||
return reinterpret_cast<uint64_t*>(this + 0x8);
|
||||
}
|
||||
|
||||
uint64_t* CEconItem::GetOriginalID()
|
||||
{
|
||||
return reinterpret_cast<uint64_t*>(this + 0x10);
|
||||
}
|
||||
|
||||
uint16_t* CEconItem::GetDefIndex()
|
||||
{
|
||||
return reinterpret_cast<uint16_t*>(this + 0x24);
|
||||
}
|
||||
|
||||
uint32_t* CEconItem::GetInventory()
|
||||
{
|
||||
return reinterpret_cast<uint32_t*>(this + 0x20);
|
||||
}
|
||||
|
||||
unsigned char* CEconItem::GetFlags()
|
||||
{
|
||||
return reinterpret_cast<unsigned char*>(this + 0x30);
|
||||
}
|
||||
|
||||
unsigned short* CEconItem::GetEconItemData()
|
||||
{
|
||||
return reinterpret_cast<unsigned short*>(this + 0x26);
|
||||
}
|
||||
|
||||
|
||||
|
||||
C_EconItemDefinition* C_EconItemView::get_static_data()
|
||||
{
|
||||
static auto fn = reinterpret_cast<C_EconItemDefinition * (__thiscall*)(void*)>(FindPatternV2("client.dll", "55 8B EC 51 53 8B D9 8B ? ? ? ? ? 56 57 8B ? ? ? ? ? 85 FF 74 16"));
|
||||
|
||||
return fn(this);
|
||||
}
|
||||
|
||||
|
||||
CEconItem* C_EconItemView::get_soc_data()
|
||||
{
|
||||
static auto fn = reinterpret_cast<CEconItem * (__thiscall*)(C_EconItemView*)>(FindPatternV2("client.dll", "55 8B EC 83 E4 F0 83 EC 18 56 8B F1 57 8B 86"));
|
||||
|
||||
return fn(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPlayerInventory::RemoveItem(uint64_t ID)
|
||||
{
|
||||
static auto fnRemoveItem
|
||||
= reinterpret_cast<int(__thiscall*)(void*, int64_t)>(
|
||||
FindPatternV2("client.dll", "55 8B EC 83 E4 F8 56 57 FF 75 0C 8B F1")
|
||||
);
|
||||
|
||||
fnRemoveItem(this, ID);
|
||||
}
|
||||
|
||||
CSharedObjectTypeCache* CPlayerInventory::GetBaseTypeCache()
|
||||
{
|
||||
static auto fnGCSDK_CGCClient_FindSOCache
|
||||
= reinterpret_cast<uintptr_t(__thiscall*)(uintptr_t, uint64_t, uint64_t, bool)>(
|
||||
FindPatternV2("client.dll", "55 8B EC 83 E4 F8 83 EC 1C 0F 10 45 08")
|
||||
);
|
||||
|
||||
static auto fnGCSDK_CSharedObjectCache_CreateBaseTypeCache
|
||||
= reinterpret_cast<CSharedObjectTypeCache * (__thiscall*)(uintptr_t, int)>(
|
||||
FindPatternV2("client.dll", "55 8B EC 51 53 56 8B D9 8D 45 08")
|
||||
);
|
||||
|
||||
static auto g_GCClientSystem = **reinterpret_cast<uintptr_t**>(FindPatternV2("client.dll", "8B 0D ? ? ? ? 6A 00 83 EC 10") + 0x2);
|
||||
auto SOCahce = fnGCSDK_CGCClient_FindSOCache(g_GCClientSystem + 0x60, *reinterpret_cast<uint64_t*>(this + 0x8), *reinterpret_cast<uint64_t*>(this + 0x10), 0);
|
||||
|
||||
return fnGCSDK_CSharedObjectCache_CreateBaseTypeCache(SOCahce, 1);
|
||||
}
|
||||
|
||||
void CPlayerInventory::RemoveItem(CEconItem* item)
|
||||
{
|
||||
RemoveItem(*item->GetItemID());
|
||||
GetBaseTypeCache()->RemoveObject(item);
|
||||
}
|
||||
|
||||
void CPlayerInventory::ClearInventory()
|
||||
{
|
||||
auto BaseTypeCache = this->GetBaseTypeCache();
|
||||
auto items = BaseTypeCache->GetEconItems();
|
||||
for (auto item : items)
|
||||
{
|
||||
RemoveItem(*item->GetItemID());
|
||||
BaseTypeCache->RemoveObject(item);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CPlayerInventory::GetSteamID()
|
||||
{
|
||||
return *reinterpret_cast<uint32_t*>(this + 0x8);
|
||||
}
|
||||
|
||||
CUtlVector< C_EconItemView* >* CPlayerInventory::GetInventoryItems()
|
||||
{
|
||||
return reinterpret_cast<CUtlVector<C_EconItemView*>*>(this + 0x2C);
|
||||
}
|
||||
|
||||
bool CPlayerInventory::AddEconItem(CEconItem* item, int a3, int a4, char a5)
|
||||
{
|
||||
static auto fnAddEconItem
|
||||
= reinterpret_cast<C_EconItemView * (__thiscall*)(void*, CEconItem*, int, int, char)>(
|
||||
FindPatternV2("client.dll", "55 8B EC 83 E4 F8 A1 ? ? ? ? 83 EC 14 53 56 57 8B F9 8B 08")
|
||||
);
|
||||
|
||||
GetBaseTypeCache()->AddObject(item);
|
||||
|
||||
|
||||
auto ret = fnAddEconItem(this, item, a3, a4, a5);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
CPlayerInventory* CSInventoryManager::GetLocalPlayerInventory()
|
||||
{
|
||||
static auto local_inventory_offset = *reinterpret_cast<uintptr_t*>(FindPatternV2("client.dll", "8B 8B ? ? ? ? E8 ? ? ? ? 89 44 24 18") + 0x2);
|
||||
return *reinterpret_cast<CPlayerInventory**>(this + local_inventory_offset);
|
||||
}
|
||||
|
||||
CEconItem* CreateEconItem()
|
||||
{
|
||||
static auto fnCreateSharedObjectSubclass_EconItem_
|
||||
= reinterpret_cast<CEconItem * (__stdcall*)()>(
|
||||
*reinterpret_cast<uintptr_t*>(FindPatternV2("client.dll", "C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? E8 ? ? ? ? 83 F8 FF 75 09 8D 45 E4 50 E8 ? ? ? ? 8D 45 E4 C7 45 ? ? ? ? ? 50 C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? E8 ? ? ? ? 83 F8 FF 75 09 8D 45 E4 50 E8 ? ? ? ? 8D 45 E4 C7 45 ? ? ? ? ? 50 C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? E8 ? ? ? ? 83 F8 FF 75 09 8D 45 E4 50 E8 ? ? ? ? 8D 45 E4 C7 45 ? ? ? ? ? 50 C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? C7 45 ? ? ? ? ? E8 ? ? ? ? 83 F8 FF 75 09 8D 45 E4 50 E8 ? ? ? ? 8D 45 E4") + 3)
|
||||
);
|
||||
return fnCreateSharedObjectSubclass_EconItem_();
|
||||
}
|
||||
uintptr_t GetItemSchema()
|
||||
{
|
||||
static auto fnGetItemSchema
|
||||
= reinterpret_cast<uintptr_t(__stdcall*)()>(
|
||||
FindPatternV2("client.dll", "A1 ? ? ? ? 85 C0 75 53")
|
||||
);
|
||||
return fnGetItemSchema();
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
#ifndef PLAYERINV
|
||||
#define PLAYERINV
|
||||
#pragma once
|
||||
|
||||
#include "PatternScan.hpp"
|
||||
#include "Interfaces.hpp"
|
||||
|
||||
#include "sdk/utlvector.h"
|
||||
#include "stdint.h"
|
||||
#include <vector>
|
||||
|
||||
#include "sdk/icliententity.h"
|
||||
|
||||
|
||||
|
||||
enum ItemQuality
|
||||
{
|
||||
ITEM_QUALITY_DEFAULT,
|
||||
ITEM_QUALITY_GENUINE,
|
||||
ITEM_QUALITY_VINTAGE,
|
||||
ITEM_QUALITY_UNUSUAL,
|
||||
ITEM_QUALITY_SKIN,
|
||||
ITEM_QUALITY_COMMUNITY,
|
||||
ITEM_QUALITY_DEVELOPER,
|
||||
ITEM_QUALITY_SELFMADE,
|
||||
ITEM_QUALITY_CUSTOMIZED,
|
||||
ITEM_QUALITY_STRANGE,
|
||||
ITEM_QUALITY_COMPLETED,
|
||||
ITEM_QUALITY_UNK2,
|
||||
ITEM_QUALITY_TOURNAMENT
|
||||
};
|
||||
|
||||
enum ItemRarity
|
||||
{
|
||||
ITEM_RARITY_DEFAULT,
|
||||
ITEM_RARITY_COMMON,
|
||||
ITEM_RARITY_UNCOMMON,
|
||||
ITEM_RARITY_RARE,
|
||||
ITEM_RARITY_MYTHICAL,
|
||||
ITEM_RARITY_LEGENDARY,
|
||||
ITEM_RARITY_ANCIENT,
|
||||
ITEM_RARITY_IMMORTAL
|
||||
};
|
||||
|
||||
class CEconItem
|
||||
{
|
||||
unsigned short* GetEconItemData();
|
||||
void UpdateEquippedState(unsigned int state);
|
||||
public:
|
||||
uint32_t* GetInventory();
|
||||
uint32_t* GetAccountID();
|
||||
uint16_t* GetDefIndex();
|
||||
uint64_t* GetItemID();
|
||||
uint64_t* GetOriginalID();
|
||||
unsigned char* GetFlags();
|
||||
void SetQuality(ItemQuality quality);
|
||||
void SetRarity(ItemRarity rarity);
|
||||
void SetOrigin(int origin);
|
||||
void SetLevel(int level);
|
||||
void SetInUse(bool in_use);
|
||||
void SetCustomName(const char* name);
|
||||
void SetCustomDesc(const char* name);
|
||||
void SetPaintSeed(float seed);
|
||||
void SetPaintKit(float kit);
|
||||
void SetPaintWear(float wear);
|
||||
void SetStatTrak(int val);
|
||||
void AddSticker(int index, int kit, float wear, float scale, float rotation);
|
||||
|
||||
template<typename TYPE>
|
||||
void SetAttributeValue(int index, TYPE val);
|
||||
|
||||
};
|
||||
|
||||
class C_EconItemDefinition
|
||||
{
|
||||
public:
|
||||
int get_equipped_position();
|
||||
const char* get_world_model_name();
|
||||
};
|
||||
|
||||
class C_EconItemView
|
||||
{
|
||||
private:
|
||||
using str_32 = char[32];
|
||||
public:
|
||||
int32_t m_bInitialized;
|
||||
int16_t m_iItemDefinitionIndex;
|
||||
int32_t m_iEntityLevel;
|
||||
int32_t m_iAccountID;
|
||||
int32_t m_iItemIDLow;
|
||||
int32_t m_iItemIDHigh;
|
||||
int32_t m_iEntityQuality;
|
||||
str_32 m_iCustomName;
|
||||
|
||||
CUtlVector<IRefCounted*>& m_CustomMaterials();
|
||||
CUtlVector<IRefCounted*>& m_VisualsDataProcessors();
|
||||
|
||||
C_EconItemDefinition* get_static_data();
|
||||
CEconItem* get_soc_data();
|
||||
};
|
||||
|
||||
|
||||
class CSharedObjectTypeCache
|
||||
{
|
||||
public:
|
||||
void AddObject(void* obj);
|
||||
void RemoveObject(void* obj);
|
||||
std::vector<CEconItem*> GetEconItems();
|
||||
};
|
||||
|
||||
|
||||
class CPlayerInventory
|
||||
{
|
||||
public:
|
||||
void RemoveItem(uint64_t ID);
|
||||
void RemoveItem(CEconItem* item);
|
||||
void ClearInventory();
|
||||
CSharedObjectTypeCache* GetBaseTypeCache();
|
||||
uint32_t GetSteamID();
|
||||
CUtlVector<C_EconItemView*>* GetInventoryItems();
|
||||
bool AddEconItem(CEconItem* item, int a3, int a4, char a5);
|
||||
};
|
||||
|
||||
|
||||
class CSInventoryManager
|
||||
{
|
||||
public:
|
||||
CPlayerInventory* GetLocalPlayerInventory();
|
||||
};
|
||||
|
||||
|
||||
uintptr_t GetItemSchema();
|
||||
CEconItem* CreateEconItem();
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,581 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define MAKE_TAG(FIELD_NUMBER, TYPE) static_cast<uint32_t>(((FIELD_NUMBER) << kTagTypeBits) | (TYPE))
|
||||
|
||||
#define make_struct(_name_, _size_) \
|
||||
struct _name_ : ProtoWriter { \
|
||||
constexpr static size_t MAX_FIELD = _size_; \
|
||||
_name_() : ProtoWriter(MAX_FIELD) {} \
|
||||
_name_(void* data, size_t size) : ProtoWriter(data, size, MAX_FIELD) {} \
|
||||
_name_(std::string data) : ProtoWriter(data, MAX_FIELD) {}
|
||||
|
||||
#define make_field(_name_, _id_, _type_) \
|
||||
constexpr static Tag _name_ = { _id_, _type_ }; \
|
||||
void clear_##_name_() { this->clear(_name_); } \
|
||||
bool has_##_name_() { return this->has(_name_); } \
|
||||
Field get_##_name_() { return this->get(_name_); } \
|
||||
std::vector<Field> getAll_##_name_() { return this->getAll(_name_); } \
|
||||
\
|
||||
void add_##_name_(std::string v) { this->add(_name_, v); } \
|
||||
template<typename T> void add_##_name_(T v) { this->add(_name_, v); } \
|
||||
void replace_##_name_(std::string v) { this->replace(_name_, v); } \
|
||||
void replace_##_name_(std::string v, uint32_t index) { this->replace(_name_, v, index); } \
|
||||
template<typename T> void replace_##_name_(T v) { this->replace(_name_, v); } \
|
||||
template<typename T> void replace_##_name_(T v, uint32_t index) { this->replace(_name_, v, index); } \
|
||||
template<class T> T get_##_name_() { return std::move( T(this->get(_name_).String()) ); }
|
||||
|
||||
|
||||
struct Tag
|
||||
{
|
||||
unsigned field;
|
||||
unsigned type;
|
||||
};
|
||||
|
||||
enum FieldType {
|
||||
TYPE_DOUBLE = 1,
|
||||
TYPE_FLOAT = 2,
|
||||
TYPE_INT64 = 3,
|
||||
TYPE_UINT64 = 4,
|
||||
TYPE_INT32 = 5,
|
||||
TYPE_FIXED64 = 6,
|
||||
TYPE_FIXED32 = 7,
|
||||
TYPE_BOOL = 8,
|
||||
TYPE_STRING = 9,
|
||||
TYPE_GROUP = 10,
|
||||
TYPE_MESSAGE = 11,
|
||||
TYPE_BYTES = 12,
|
||||
TYPE_UINT32 = 13,
|
||||
TYPE_ENUM = 14,
|
||||
TYPE_SFIXED32 = 15,
|
||||
TYPE_SFIXED64 = 16,
|
||||
TYPE_SINT32 = 17,
|
||||
TYPE_SINT64 = 18,
|
||||
MAX_FIELD_TYPE = 18,
|
||||
};
|
||||
|
||||
struct Field
|
||||
{
|
||||
friend class ProtoWriter;
|
||||
public:
|
||||
inline Field& operator=(const Field& f);
|
||||
|
||||
Field() : tag({ 0,0 }), value(""), full("") { }
|
||||
Field(unsigned field, unsigned type, std::string value, std::string full);
|
||||
|
||||
Field(Tag tag, std::string value);
|
||||
Field(unsigned field, unsigned type, std::string value);
|
||||
|
||||
template<typename T>
|
||||
Field(Tag tag, T value);
|
||||
|
||||
template<typename T>
|
||||
Field(unsigned field, unsigned type, T value);
|
||||
|
||||
public:
|
||||
static Field ReadField(void* data, size_t& bytesRead);
|
||||
|
||||
public:
|
||||
inline float Float();
|
||||
inline double Double();
|
||||
inline int32_t Int32();
|
||||
inline int64_t Int64();
|
||||
inline uint32_t UInt32();
|
||||
inline uint64_t UInt64();
|
||||
inline uint32_t Fixed32();
|
||||
inline uint64_t Fixed64();
|
||||
inline int32_t SFixed32();
|
||||
inline int64_t SFixed64();
|
||||
inline bool Bool();
|
||||
inline std::string String();
|
||||
|
||||
private:
|
||||
Tag tag;
|
||||
std::string value;
|
||||
std::string full;
|
||||
|
||||
static std::string getBytesVarint32(uint32_t value);
|
||||
static std::string getBytesVarint64(uint64_t value);
|
||||
static uint32_t readVarUint32(void* data, size_t& bytesRead);
|
||||
static uint64_t readVarUint64(void* data, size_t& bytesRead);
|
||||
|
||||
enum WireType {
|
||||
WIRETYPE_VARINT = 0,
|
||||
WIRETYPE_FIXED64 = 1,
|
||||
WIRETYPE_LENGTH_DELIMITED = 2,
|
||||
WIRETYPE_START_GROUP = 3,
|
||||
WIRETYPE_END_GROUP = 4,
|
||||
WIRETYPE_FIXED32 = 5,
|
||||
};
|
||||
|
||||
constexpr static WireType kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
|
||||
static_cast<WireType>(-1),
|
||||
WIRETYPE_FIXED64,
|
||||
WIRETYPE_FIXED32,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_FIXED64,
|
||||
WIRETYPE_FIXED32,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_LENGTH_DELIMITED,
|
||||
WIRETYPE_START_GROUP,
|
||||
WIRETYPE_LENGTH_DELIMITED,
|
||||
WIRETYPE_LENGTH_DELIMITED,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_FIXED32,
|
||||
WIRETYPE_FIXED64,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
};
|
||||
|
||||
constexpr static int kTagTypeBits = 3;
|
||||
constexpr static uint32_t kTagTypeMask = (1 << kTagTypeBits) - 1;
|
||||
constexpr static int kMaxVarintBytes = 10;
|
||||
constexpr static int kMaxVarint32Bytes = 5;
|
||||
};
|
||||
|
||||
class ProtoWriter
|
||||
{
|
||||
public:
|
||||
inline ProtoWriter();
|
||||
inline ProtoWriter(size_t maxFields);
|
||||
inline ProtoWriter(void* data, size_t size, size_t maxFields);
|
||||
inline ProtoWriter(std::string dataStr, size_t maxFields);
|
||||
|
||||
public:
|
||||
inline void add(Field field);
|
||||
inline void replace(Field field);
|
||||
inline void replace(Field field, uint32_t index);
|
||||
inline void clear(unsigned fieldId);
|
||||
inline bool has(unsigned fieldId);
|
||||
inline Field get(unsigned fieldId);
|
||||
inline std::vector<Field> getAll(unsigned fieldId);
|
||||
|
||||
public:
|
||||
inline void add(Tag tag, std::string value);
|
||||
inline void replace(Tag tag, std::string value);
|
||||
inline void replace(Tag tag, std::string value, uint32_t index);
|
||||
inline void clear(Tag tag);
|
||||
inline bool has(Tag tag);
|
||||
inline Field get(Tag tag);
|
||||
inline std::vector<Field> getAll(Tag tag);
|
||||
|
||||
template<typename T>
|
||||
inline void add(Tag tag, T value);
|
||||
|
||||
template<typename T>
|
||||
inline void replace(Tag tag, T value);
|
||||
|
||||
template<typename T>
|
||||
inline void replace(Tag tag, T value, uint32_t index);
|
||||
|
||||
|
||||
std::string serialize();
|
||||
void print();
|
||||
|
||||
private:
|
||||
std::vector<std::vector<Field>> fields;
|
||||
};
|
||||
|
||||
#pragma region Helper Functions
|
||||
std::string Field::getBytesVarint32(uint32_t value)
|
||||
{
|
||||
uint8_t bytes[kMaxVarint32Bytes];
|
||||
int size = 0;
|
||||
while (value > 0x7F) {
|
||||
bytes[size++] = (static_cast<uint8_t>(value) & 0x7F) | 0x80;
|
||||
value >>= 7;
|
||||
}
|
||||
bytes[size++] = static_cast<uint8_t>(value) & 0x7F;
|
||||
return std::string{ reinterpret_cast<const char*>(&bytes[0]), (size_t)size };
|
||||
}
|
||||
|
||||
std::string Field::getBytesVarint64(uint64_t value)
|
||||
{
|
||||
uint8_t bytes[kMaxVarintBytes];
|
||||
int size = 0;
|
||||
while (value > 0x7F) {
|
||||
bytes[size++] = (static_cast<uint8_t>(value) & 0x7F) | 0x80;
|
||||
value >>= 7;
|
||||
}
|
||||
bytes[size++] = static_cast<uint8_t>(value) & 0x7F;
|
||||
return std::string{ reinterpret_cast<const char*>(&bytes[0]), (size_t)size };
|
||||
}
|
||||
|
||||
uint32_t Field::readVarUint32(void* data, size_t& bytesRead)
|
||||
{
|
||||
auto ptr = reinterpret_cast<const uint8_t*>(data);
|
||||
auto value = 0u;
|
||||
auto bytes = 0u;
|
||||
|
||||
do {
|
||||
value |= static_cast<uint32_t>(*ptr & 0x7f) << (7 * bytes);
|
||||
bytes++;
|
||||
} while (*(ptr++) & 0x80 && bytes <= 5);
|
||||
|
||||
bytesRead = bytes;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t Field::readVarUint64(void* data, size_t& bytesRead)
|
||||
{
|
||||
auto ptr = reinterpret_cast<const uint8_t*>(data);
|
||||
auto value = 0ull;
|
||||
auto bytes = 0u;
|
||||
|
||||
do
|
||||
{
|
||||
value |= static_cast<uint64_t>(*ptr & 0x7f) << (7 * bytes);
|
||||
bytes++;
|
||||
} while (*(ptr++) & 0x80 && bytes <= 10);
|
||||
|
||||
bytesRead = bytes;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Field Field::ReadField(void* data, size_t& bytesRead)
|
||||
{
|
||||
unsigned field = *reinterpret_cast<uint16_t*>(data);
|
||||
unsigned type = field & kTagTypeMask;
|
||||
|
||||
if (field == 0xffff) {
|
||||
bytesRead = 0;
|
||||
return Field();
|
||||
}
|
||||
|
||||
if (field & 0x80) {
|
||||
field = ((field & 0x7f) | ((field & 0xff00) >> 1)) >> kTagTypeBits;
|
||||
bytesRead = 2;
|
||||
}
|
||||
else {
|
||||
field = (field & 0xff) >> kTagTypeBits;
|
||||
bytesRead = 1;
|
||||
}
|
||||
|
||||
size_t length, sizeDelimited;
|
||||
std::string value, full;
|
||||
switch (type)
|
||||
{
|
||||
case WIRETYPE_VARINT:
|
||||
readVarUint64((void*)((ptrdiff_t)data + bytesRead), length);
|
||||
value = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytesRead)), length };
|
||||
full = std::string{ reinterpret_cast<const char*>(data), bytesRead + length };
|
||||
bytesRead += length;
|
||||
break;
|
||||
case WIRETYPE_FIXED64:
|
||||
value = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytesRead)), 8 };
|
||||
full = std::string{ reinterpret_cast<const char*>(data), bytesRead + 8 };
|
||||
bytesRead += 8;
|
||||
break;
|
||||
case WIRETYPE_LENGTH_DELIMITED:
|
||||
sizeDelimited = readVarUint32((void*)((ptrdiff_t)data + bytesRead), length);
|
||||
value = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytesRead)), length + sizeDelimited };
|
||||
full = std::string{ reinterpret_cast<const char*>(data), bytesRead + length + sizeDelimited };
|
||||
bytesRead += length + sizeDelimited;
|
||||
break;
|
||||
case WIRETYPE_START_GROUP:
|
||||
throw("WIRETYPE_START_GROUP unrealised");
|
||||
break;
|
||||
case WIRETYPE_END_GROUP:
|
||||
throw("WIRETYPE_END_GROUP unrealised");
|
||||
break;
|
||||
case WIRETYPE_FIXED32:
|
||||
value = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytesRead)), 4 };
|
||||
full = std::string{ reinterpret_cast<const char*>(data), bytesRead + 4 };
|
||||
bytesRead += 4;
|
||||
break;
|
||||
default:
|
||||
throw("Unknown type %i", type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return Field(field, type, value, full);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Field Definition
|
||||
Field& Field::operator=(const Field& f) {
|
||||
this->tag = f.tag;
|
||||
this->value = f.value;
|
||||
this->full = f.full;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Field::Field(unsigned field, unsigned type, std::string value, std::string full) {
|
||||
this->tag = { field, type };
|
||||
this->value = value;
|
||||
this->full = full;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Field::Field(Tag tag, T value) {
|
||||
auto wireType = kWireTypeForFieldType[tag.type];
|
||||
full = getBytesVarint32(MAKE_TAG(tag.field, wireType));
|
||||
|
||||
switch (wireType) {
|
||||
case WIRETYPE_VARINT:
|
||||
full += getBytesVarint64(static_cast<uint64_t>(value));
|
||||
break;
|
||||
case WIRETYPE_FIXED32:
|
||||
full += std::string{ reinterpret_cast<const char*>(&value), 4 };
|
||||
break;
|
||||
case WIRETYPE_FIXED64:
|
||||
full += std::string{ reinterpret_cast<const char*>(&value), 8 };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Field::Field(unsigned field, unsigned type, T value) {
|
||||
auto wireType = kWireTypeForFieldType[type];
|
||||
tag = { field, (unsigned)wireType };
|
||||
full = getBytesVarint32(MAKE_TAG(field, wireType));
|
||||
|
||||
switch (wireType) {
|
||||
case WIRETYPE_VARINT:
|
||||
full += getBytesVarint64(static_cast<uint64_t>(value));
|
||||
break;
|
||||
case WIRETYPE_FIXED32:
|
||||
full += std::string{ reinterpret_cast<const char*>(&value), 4 };
|
||||
break;
|
||||
case WIRETYPE_FIXED64:
|
||||
full += std::string{ reinterpret_cast<const char*>(&value), 8 };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Field::Field(Tag tag, std::string value) {
|
||||
auto wireType = kWireTypeForFieldType[tag.type];
|
||||
full = getBytesVarint32(MAKE_TAG(tag.field, wireType));
|
||||
full += getBytesVarint32(value.size());
|
||||
full += value;
|
||||
}
|
||||
|
||||
Field::Field(unsigned field, unsigned type, std::string value) {
|
||||
auto wireType = kWireTypeForFieldType[type];
|
||||
tag = { field, (unsigned)wireType };
|
||||
full = getBytesVarint32(MAKE_TAG(field, wireType));
|
||||
full += getBytesVarint32(value.size());
|
||||
full += value;
|
||||
}
|
||||
|
||||
|
||||
float Field::Float() {
|
||||
return *reinterpret_cast<float*>((void*)value.data());
|
||||
}
|
||||
double Field::Double() {
|
||||
return *reinterpret_cast<double*>((void*)value.data());
|
||||
}
|
||||
int32_t Field::Int32() {
|
||||
size_t bytesRead;
|
||||
return static_cast<int32_t>(readVarUint64((void*)value.data(), bytesRead));
|
||||
}
|
||||
int64_t Field::Int64() {
|
||||
size_t bytesRead;
|
||||
return readVarUint64((void*)value.data(), bytesRead);
|
||||
}
|
||||
uint32_t Field::UInt32() {
|
||||
size_t bytesRead;
|
||||
return readVarUint32((void*)value.data(), bytesRead);
|
||||
}
|
||||
uint64_t Field::UInt64() {
|
||||
size_t bytesRead;
|
||||
return readVarUint64((void*)value.data(), bytesRead);
|
||||
}
|
||||
uint32_t Field::Fixed32() {
|
||||
return *reinterpret_cast<uint32_t*>((void*)value.data());
|
||||
}
|
||||
uint64_t Field::Fixed64() {
|
||||
return *reinterpret_cast<uint64_t*>((void*)value.data());
|
||||
}
|
||||
int32_t Field::SFixed32() {
|
||||
return *reinterpret_cast<int32_t*>((void*)value.data());
|
||||
}
|
||||
int64_t Field::SFixed64() {
|
||||
return *reinterpret_cast<int64_t*>((void*)value.data());
|
||||
}
|
||||
bool Field::Bool() {
|
||||
size_t bytesRead;
|
||||
return !!readVarUint32((void*)value.data(), bytesRead);
|
||||
}
|
||||
|
||||
std::string Field::String()
|
||||
{
|
||||
size_t bytesRead;
|
||||
void* data = (void*)value.data();
|
||||
auto length = readVarUint32((void*)value.data(), bytesRead);
|
||||
auto value = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytesRead)), length };
|
||||
return value;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ProtoWriter Definition
|
||||
ProtoWriter::ProtoWriter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ProtoWriter::ProtoWriter(size_t maxFields)
|
||||
{
|
||||
size_t vector_size = maxFields + 1;
|
||||
fields.resize(vector_size);
|
||||
fields.reserve(vector_size);
|
||||
}
|
||||
|
||||
ProtoWriter::ProtoWriter(void* data, size_t size, size_t maxFields) : ProtoWriter(maxFields)
|
||||
{
|
||||
size_t vector_size = maxFields + 1,
|
||||
pos = 0,
|
||||
bytesRead;
|
||||
|
||||
if (data == nullptr)
|
||||
return;
|
||||
while (pos < size) {
|
||||
auto field = Field::ReadField((void*)((ptrdiff_t)data + pos), bytesRead);
|
||||
if (!bytesRead) break;
|
||||
|
||||
auto index = field.tag.field;
|
||||
if (index >= vector_size) throw("fields range error: field[%i]", index);
|
||||
fields[index].push_back(field);
|
||||
pos += bytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
ProtoWriter::ProtoWriter(std::string dataStr, size_t maxFields) : ProtoWriter((void*)dataStr.data(), dataStr.size(), maxFields)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string ProtoWriter::serialize()
|
||||
{
|
||||
std::string result;
|
||||
for (auto& f0 : fields) {
|
||||
for (auto& f1 : f0) {
|
||||
result += f1.full;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ProtoWriter::print()
|
||||
{
|
||||
auto data = serialize();
|
||||
void* mem = (void*)data.data();
|
||||
size_t size = data.size();
|
||||
int j = 0;
|
||||
for (size_t i = 0; i <= size; ++i) {
|
||||
printf("%.2X ", *(unsigned char*)((uintptr_t)mem + i));
|
||||
j++;
|
||||
if (j == 16)
|
||||
{
|
||||
j = 0;
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void ProtoWriter::add(Field field)
|
||||
{
|
||||
fields[field.tag.field].push_back(field);
|
||||
}
|
||||
|
||||
void ProtoWriter::replace(Field field)
|
||||
{
|
||||
fields[field.tag.field].clear();
|
||||
fields[field.tag.field].push_back(field);
|
||||
}
|
||||
|
||||
void ProtoWriter::replace(Field field, uint32_t index)
|
||||
{
|
||||
fields[field.tag.field][index] = field;
|
||||
}
|
||||
|
||||
void ProtoWriter::clear(unsigned fieldId)
|
||||
{
|
||||
return fields[fieldId].clear();
|
||||
}
|
||||
|
||||
bool ProtoWriter::has(unsigned fieldId)
|
||||
{
|
||||
return fields[fieldId].size() > 0;
|
||||
}
|
||||
|
||||
Field ProtoWriter::get(unsigned fieldId)
|
||||
{
|
||||
if (fields[fieldId].empty())
|
||||
return Field();
|
||||
return fields[fieldId][0];
|
||||
}
|
||||
|
||||
std::vector<Field> ProtoWriter::getAll(unsigned fieldId)
|
||||
{
|
||||
return fields[fieldId];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ProtoWriter::add(Tag tag, T value)
|
||||
{
|
||||
fields[tag.field].push_back(Field(tag, value));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ProtoWriter::replace(Tag tag, T value)
|
||||
{
|
||||
fields[tag.field].clear();
|
||||
fields[tag.field].push_back(Field(tag, value));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ProtoWriter::replace(Tag tag, T value, uint32_t index)
|
||||
{
|
||||
fields[tag.field][index] = Field(tag, value);
|
||||
}
|
||||
|
||||
void ProtoWriter::add(Tag tag, std::string value)
|
||||
{
|
||||
fields[tag.field].push_back(Field(tag, value));
|
||||
}
|
||||
|
||||
void ProtoWriter::replace(Tag tag, std::string value)
|
||||
{
|
||||
fields[tag.field].clear();
|
||||
fields[tag.field].push_back(Field(tag, value));
|
||||
}
|
||||
|
||||
void ProtoWriter::replace(Tag tag, std::string value, uint32_t index)
|
||||
{
|
||||
fields[tag.field][index] = Field(tag, value);
|
||||
}
|
||||
|
||||
void ProtoWriter::clear(Tag tag)
|
||||
{
|
||||
return fields[tag.field].clear();
|
||||
}
|
||||
|
||||
bool ProtoWriter::has(Tag tag)
|
||||
{
|
||||
return fields[tag.field].size() > 0;
|
||||
}
|
||||
|
||||
Field ProtoWriter::get(Tag tag)
|
||||
{
|
||||
if (fields[tag.field].empty())
|
||||
return Field();
|
||||
return fields[tag.field][0];
|
||||
}
|
||||
|
||||
std::vector<Field> ProtoWriter::getAll(Tag tag)
|
||||
{
|
||||
return fields[tag.field];
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
#include "pbwrap.hpp"
|
||||
|
||||
#define k_EMsgGCCStrike15_v2_MatchmakingGC2ClientReserve 9107
|
||||
#define k_EMsgGCClientWelcome 4004
|
||||
#define k_EMsgGCClientHello 4006
|
||||
#define k_EMsgGCAdjustItemEquippedState 1059
|
||||
#define k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello 9109
|
||||
#define k_EMsgGCCStrike15_v2_MatchmakingGC2ClientHello 9110
|
||||
#define k_EMsgGCCStrike15_v2_ClientGCRankUpdate 9194
|
||||
|
||||
using namespace pbwrap;
|
||||
|
||||
struct CMsgClientHello : pbmsg<8> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(3, types::Uint32, client_session_need);
|
||||
};
|
||||
|
||||
struct MatchmakingGC2ClientHello : pbmsg<20> {
|
||||
struct PlayerRankingInfo : pbmsg<6> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, types::Uint32, account_id);
|
||||
PBFIELD(2, types::Uint32, rank_id);
|
||||
PBFIELD(3, types::Uint32, wins);
|
||||
PBFIELD(6, types::Uint32, rank_type_id);
|
||||
};
|
||||
struct PlayerCommendationInfo : pbmsg<4> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, types::Uint32, cmd_friendly);
|
||||
PBFIELD(2, types::Uint32, cmd_teaching);
|
||||
PBFIELD(4, types::Uint32, cmd_leader);
|
||||
};
|
||||
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(7, PlayerRankingInfo, ranking);
|
||||
PBFIELD(8, PlayerCommendationInfo, commendation);
|
||||
PBFIELD(17, types::Int32, player_level);
|
||||
PBFIELD(18, types::Int32, player_cur_xp);
|
||||
PBFIELD(4, types::Uint32, penalty_seconds);
|
||||
PBFIELD(5, types::Uint32, penalty_reason);
|
||||
PBFIELD(6, types::Int32, vac_banned);
|
||||
};
|
||||
|
||||
struct CMsgGCCStrike15_v2_ClientGCRankUpdate : pbmsg<1> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, MatchmakingGC2ClientHello::PlayerRankingInfo, ranking);
|
||||
};
|
||||
|
||||
struct CSOEconItemEquipped : pbmsg<2> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, types::Int32, new_class);
|
||||
PBFIELD(2, types::Int32, new_slot);
|
||||
};
|
||||
|
||||
struct CSOEconItemAttribute : pbmsg<3> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, types::Uint32, def_index);
|
||||
PBFIELD(2, types::Uint32, value);
|
||||
PBFIELD(3, types::Bytes, value_bytes);
|
||||
};
|
||||
|
||||
struct CSOEconItem : pbmsg<19> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, types::Uint64, id);
|
||||
PBFIELD(2, types::Uint32, account_id);
|
||||
PBFIELD(3, types::Uint32, inventory);
|
||||
PBFIELD(4, types::Int32, def_index);
|
||||
PBFIELD(5, types::Uint32, quantity);
|
||||
PBFIELD(6, types::Uint32, level);
|
||||
PBFIELD(7, types::Uint32, quality);
|
||||
PBFIELD(8, types::Uint32, flags);
|
||||
PBFIELD(9, types::Uint32, origin);
|
||||
PBFIELD(10, types::String, custom_name);
|
||||
PBFIELD(11, types::String, custom_desc);
|
||||
PBFIELD(12, CSOEconItemAttribute, attribute);
|
||||
PBFIELD(14, types::Bool, in_use);
|
||||
PBFIELD(15, types::Uint32, style);
|
||||
PBFIELD(16, types::Uint64, original_id);
|
||||
PBFIELD(18, CSOEconItemEquipped, equipped_state);
|
||||
PBFIELD(19, types::Uint32, rarity);
|
||||
};
|
||||
|
||||
struct CMsgClientWelcome : pbmsg<11> {
|
||||
struct SubscribedType : pbmsg<2> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, types::Int32, type_id);
|
||||
PBFIELD(2, CSOEconItem, object_data);
|
||||
};
|
||||
|
||||
struct CMsgSOCacheSubscribed : pbmsg<4> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(2, SubscribedType, objects);
|
||||
};
|
||||
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(3, CMsgSOCacheSubscribed, outofdate_subscribed_caches);
|
||||
};
|
||||
|
||||
struct CMsgAdjustItemEquippedState : pbmsg<4> {
|
||||
PBMSG_CTOR;
|
||||
PBFIELD(1, types::Uint64, item_id);
|
||||
PBFIELD(2, types::Uint32, new_class);
|
||||
PBFIELD(3, types::Uint32, new_slot);
|
||||
PBFIELD(4, types::Bool, swap);
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef SINGLETON
|
||||
#define SINGLETON
|
||||
#pragma once
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Singleton
|
||||
{
|
||||
protected:
|
||||
Singleton() {}
|
||||
~Singleton() {}
|
||||
|
||||
Singleton(const Singleton&) = delete;
|
||||
Singleton& operator=(const Singleton&) = delete;
|
||||
|
||||
Singleton(Singleton&&) = delete;
|
||||
Singleton& operator=(Singleton&&) = delete;
|
||||
|
||||
public:
|
||||
static T& Get()
|
||||
{
|
||||
static T inst{};
|
||||
return inst;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,427 @@
|
||||
#ifndef SKINCHANGER
|
||||
#define SKINCHANGER
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "sdk/GameEventManager.h"
|
||||
#include "VMT.hpp"
|
||||
#include "Interfaces.hpp"
|
||||
#include "Options.hpp"
|
||||
#include "sdk/c_baseentity.h"
|
||||
#include "PatternScan.hpp"
|
||||
|
||||
extern VMTHook* GameEventManagerHook;
|
||||
extern VMTHook* ClientHook;
|
||||
|
||||
#include "NetVarManager.hpp"
|
||||
|
||||
extern bool needupdate;
|
||||
|
||||
#include "vmt_smart_hook.hpp"
|
||||
|
||||
|
||||
struct iitem
|
||||
{
|
||||
iitem(int defindex1, std::string name1, std::string viewmodel1, std::string worldmodel1)
|
||||
{
|
||||
defindex = defindex1;
|
||||
name = name1;
|
||||
viewmodel = viewmodel1;
|
||||
worldmodel = worldmodel1;
|
||||
Preview = std::to_string(defindex1).append(": ").append(name1);
|
||||
}
|
||||
int defindex;
|
||||
std::string name;
|
||||
std::string viewmodel;
|
||||
std::string worldmodel;
|
||||
std::string Preview;
|
||||
bool isSelected;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct hud_weapons_t
|
||||
{
|
||||
std::int32_t* get_weapon_count()
|
||||
{
|
||||
return reinterpret_cast<std::int32_t*>(std::uintptr_t(this) + 0x80);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct String_t
|
||||
{
|
||||
char* szBuffer;
|
||||
int nCapacity;
|
||||
int _unknown;
|
||||
int nLength;
|
||||
};
|
||||
|
||||
class CEconItemRarityDefinition
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
int color;
|
||||
String_t name;
|
||||
String_t loc_key;
|
||||
String_t loc_key_weapon;
|
||||
String_t loot_list;
|
||||
String_t recycle_list;
|
||||
String_t drop_sound;
|
||||
String_t endmatchitemrevealrarity;
|
||||
String_t pointertosomething3;
|
||||
void* pointertosomething4;
|
||||
void* pointertosomething5;
|
||||
char dumb10[8];
|
||||
};
|
||||
|
||||
class CStickerKit
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
int item_rarity;
|
||||
String_t name;
|
||||
String_t description;
|
||||
String_t item_name;
|
||||
String_t material_name;
|
||||
String_t image_inventory;
|
||||
int tournament_event_id;
|
||||
int tournament_team_id;
|
||||
int tournament_player_id;
|
||||
bool is_custom_sticker_material;
|
||||
float rotate_end;
|
||||
float rotate_start;
|
||||
float scale_min;
|
||||
float scale_max;
|
||||
float wear_min;
|
||||
float wear_max;
|
||||
String_t image_inventory2;
|
||||
String_t image_inventory_large;
|
||||
std::uint32_t pad0[4];
|
||||
};
|
||||
|
||||
|
||||
class CPaintKit
|
||||
{
|
||||
public:
|
||||
int nID;
|
||||
String_t sName;
|
||||
String_t sDescriptionString;
|
||||
String_t sDescriptionTag;
|
||||
String_t pad;
|
||||
String_t pattern;
|
||||
String_t pad1;
|
||||
String_t sLogoMaterial;
|
||||
int bBaseDiffuseOverride;
|
||||
int rarity;
|
||||
int nStyle;
|
||||
int color1;
|
||||
int color2;
|
||||
int color3;
|
||||
int color4;
|
||||
int logoColor1;
|
||||
int logoColor2;
|
||||
int logoColor3;
|
||||
int logoColor4;
|
||||
float flWearDefault;
|
||||
float flWearRemapMin;
|
||||
float flWearRemapMax;
|
||||
char nFixedSeed;
|
||||
char uchPhongExponent;
|
||||
char uchPhongAlbedoBoost;
|
||||
char uchPhongIntensity;
|
||||
float flPatternScale;
|
||||
float flPatternOffsetXStart;
|
||||
float flPatternOffsetXEnd;
|
||||
float flPatternOffsetYStart;
|
||||
float flPatternOffsetYEnd;
|
||||
float flPatternRotateStart;
|
||||
float flPatternRotateEnd;
|
||||
float flLogoScale;
|
||||
float flLogoOffsetX;
|
||||
float flLogoOffsetY;
|
||||
float flLogoRotation;
|
||||
int bIgnoreWeaponSizeScale;
|
||||
int nViewModelExponentOverrideSize;
|
||||
int bOnlyFirstMaterial;
|
||||
float pearlescent;
|
||||
int sVmtPath[4];
|
||||
int kvVmtOverrides;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct EconItemQualityDefinition {
|
||||
int id;
|
||||
const char* name;
|
||||
unsigned weight;
|
||||
bool explicitMatchesOnly;
|
||||
bool canSupportSet;
|
||||
const char* hexColor;
|
||||
};
|
||||
|
||||
extern std::vector<iitem> rarities;
|
||||
extern std::vector<iitem> knives;
|
||||
extern std::vector<iitem> gloves;
|
||||
extern std::vector<iitem> agents;
|
||||
extern std::vector<iitem> medals;
|
||||
extern std::vector<iitem> musickits;
|
||||
extern std::vector <iitem> qualities;
|
||||
|
||||
static inline auto is_knife(const int di) -> bool
|
||||
{
|
||||
for (short i = 0; i < knives.size(); i++)
|
||||
if (knives[i].defindex == di) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall hkFireEventClientSide(void* thisptr, void* edx, IGameEvent* event);
|
||||
void __fastcall hkFrameStageNotify(IBaseClientDLL* thisptr, void* edx, ClientFrameStage_t stage);
|
||||
|
||||
|
||||
|
||||
|
||||
class CCStrike15ItemSchema;
|
||||
class CCStrike15ItemSystem
|
||||
{
|
||||
public:
|
||||
virtual CCStrike15ItemSchema* GetItemSchemaInterface() = 0;
|
||||
};
|
||||
|
||||
|
||||
template <typename Key, typename Value>
|
||||
struct Node_t
|
||||
{
|
||||
int nPreviousId;
|
||||
int nNextId;
|
||||
void* parent;
|
||||
int type;
|
||||
Key iPaintKitId;
|
||||
Value value;
|
||||
};
|
||||
|
||||
template <typename Key, typename Value>
|
||||
struct Head_t
|
||||
{
|
||||
Node_t<Key, Value>* pMemory;
|
||||
int nAllocationCount;
|
||||
int nGrowSize;
|
||||
int nStartElement;
|
||||
int nNextAvailable;
|
||||
int _unknown;
|
||||
int nLastElement;
|
||||
};
|
||||
|
||||
|
||||
class CEconItemDefinition
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
VIRTUAL_METHOD(int, getWeaponId, 0, (), (this))
|
||||
VIRTUAL_METHOD(const char*, getItemBaseName, 2, (), (this))
|
||||
VIRTUAL_METHOD(const char*, getItemTypeName, 3, (), (this))
|
||||
VIRTUAL_METHOD(const char*, getPlayerDisplayModel, 6, (), (this))
|
||||
VIRTUAL_METHOD(const char*, getWorldDisplayModel, 7, (), (this))
|
||||
VIRTUAL_METHOD(std::uint8_t, getRarity, 12, (), (this))
|
||||
|
||||
char pad_0x0000[0x8];
|
||||
int32_t m_iItemDefinitionIndex;
|
||||
char pad_0x000C[0x40];
|
||||
char* m_szHudName;
|
||||
char pad_0x0050[0x4];
|
||||
char* m_szWeaponType;
|
||||
char pad_0x0058[0x4];
|
||||
char* m_szWeaponDescription;
|
||||
char pad_0x0060[0x34];
|
||||
char* m_szViewModel;
|
||||
char pad_0x0098[0x4];
|
||||
char* m_szWorldModel;
|
||||
char* m_szWorldModelDropped;
|
||||
char pad_0x001[0x58];
|
||||
char* stickersdecalmdl;
|
||||
char pad_0x002[0x0C];
|
||||
char* stickersdecalmdl1;
|
||||
char* inventoryicon;
|
||||
char pad_0x003[0xA4];
|
||||
char* m_szWeaponName1;
|
||||
char pad_0x004[0x14];
|
||||
char* m_szWeaponName;
|
||||
char pad_0x005[0x8];
|
||||
char* m_szWeaponName3;
|
||||
char pad_0x01C4[0x27C];
|
||||
};
|
||||
|
||||
|
||||
void InitSkinChanger();
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct UtlMemory {
|
||||
T& operator[](int i) const noexcept { return memory[i]; };
|
||||
|
||||
T* memory;
|
||||
int allocationCount;
|
||||
int growSize;
|
||||
};
|
||||
|
||||
template <typename Key, typename Value>
|
||||
struct UtlMap {
|
||||
auto begin() const noexcept { return memory.memory; }
|
||||
auto end() const noexcept { return memory.memory + numElements; }
|
||||
|
||||
int find(Key key) const noexcept
|
||||
{
|
||||
auto curr = root;
|
||||
|
||||
while (curr != -1) {
|
||||
const auto el = memory[curr];
|
||||
|
||||
if (el.iPaintKitId < key)
|
||||
curr = el.nNextId;
|
||||
else if (el.iPaintKitId > key)
|
||||
curr = el.nPreviousId;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return curr;
|
||||
}
|
||||
void* lessFunc;
|
||||
UtlMemory<Node_t<Key, Value>> memory;
|
||||
int root;
|
||||
int numElements;
|
||||
int firstFree;
|
||||
int lastAlloc;
|
||||
Node_t<Key, Value>* elements;
|
||||
};
|
||||
|
||||
struct AlternateIconData {
|
||||
String_t simpleName;
|
||||
String_t largeSimpleName;
|
||||
String_t iconURLSmall;
|
||||
String_t iconURLLarge;
|
||||
PAD(28)
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
class UtlVector {
|
||||
public:
|
||||
constexpr T& operator[](int i) noexcept { return memory[i]; };
|
||||
constexpr const T& operator[](int i) const noexcept { return memory[i]; };
|
||||
|
||||
T* memory;
|
||||
int allocationCount;
|
||||
int growSize;
|
||||
int size;
|
||||
T* elements;
|
||||
};
|
||||
|
||||
|
||||
struct ItemListEntry {
|
||||
int itemDef;
|
||||
int paintKit;
|
||||
PAD(20)
|
||||
|
||||
auto weaponId() const noexcept
|
||||
{
|
||||
return itemDef;
|
||||
}
|
||||
};
|
||||
|
||||
class EconLootListDefinition {
|
||||
public:
|
||||
VIRTUAL_METHOD(const char*, getName, 0, (), (this))
|
||||
VIRTUAL_METHOD(const UtlVector<ItemListEntry>&, getLootListContents, 1, (), (this))
|
||||
};
|
||||
|
||||
class EconItemSetDefinition {
|
||||
public:
|
||||
VIRTUAL_METHOD(const char*, getLocKey, 1, (), (this))
|
||||
VIRTUAL_METHOD(int, getItemCount, 4, (), (this))
|
||||
VIRTUAL_METHOD(int, getItemDef, 5, (int index), (this, index))
|
||||
VIRTUAL_METHOD(int, getItemPaintKit, 6, (int index), (this, index))
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class CEconColorDefinition
|
||||
{
|
||||
public:
|
||||
int xz;
|
||||
int xz2;
|
||||
};
|
||||
|
||||
class CEconGraffitiTintDefinition
|
||||
{
|
||||
public:
|
||||
int xz;
|
||||
int xz2;
|
||||
};
|
||||
|
||||
class CEconMusicDefinition
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
char* name;
|
||||
char* desc;
|
||||
char* model;
|
||||
char* music;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MusicVector {
|
||||
public:
|
||||
constexpr T& operator[](int i) noexcept { return memory[i]; };
|
||||
constexpr const T& operator[](int i) const noexcept { return memory[i]; };
|
||||
|
||||
T* memory;
|
||||
PAD(0xC)
|
||||
int itemcount;
|
||||
};
|
||||
|
||||
class ItemSchema {
|
||||
public:
|
||||
PAD(0x64)
|
||||
UtlMap<int, CEconItemRarityDefinition> rars;
|
||||
UtlMap<int, EconItemQualityDefinition> qualities;
|
||||
PAD(0x48)
|
||||
UtlMap<int, CEconItemDefinition*> itemsSorted;
|
||||
PAD(0x104)
|
||||
UtlMap<std::uint64_t, AlternateIconData> alternateIcons;
|
||||
PAD(0x48)
|
||||
UtlMap<int, CPaintKit*> paintKits;
|
||||
UtlMap<int, CStickerKit*> stickerKits;
|
||||
UtlMap<const char*, CStickerKit*> sticker_kits_namekey;
|
||||
int32_t pad6[24];
|
||||
UtlMap<const char*, KeyValues*> prefabs;
|
||||
UtlVector<CEconColorDefinition*> colors;
|
||||
UtlVector<CEconGraffitiTintDefinition*> graffiti_tints;
|
||||
int32_t pad7[20];
|
||||
MusicVector<CEconMusicDefinition*> music_definitions;
|
||||
|
||||
VIRTUAL_METHOD(CEconItemDefinition*, getItemDefinitionInterface, 4, (int id), (this, id))
|
||||
VIRTUAL_METHOD(int, getItemSetCount, 28, (), (this))
|
||||
VIRTUAL_METHOD(EconItemSetDefinition*, getItemSet, 29, (int index), (this, index))
|
||||
VIRTUAL_METHOD(EconLootListDefinition*, getLootList, 32, (int index), (this, index))
|
||||
VIRTUAL_METHOD(int, getLootListCount, 34, (), (this))
|
||||
VIRTUAL_METHOD(CEconItemDefinition*, getItemDefinitionByName, 42, (const char* name), (this, name))
|
||||
};
|
||||
|
||||
|
||||
class ItemSystem {
|
||||
public:
|
||||
VIRTUAL_METHOD(ItemSchema*, getItemSchema, 0, (), (this))
|
||||
};
|
||||
|
||||
extern std::add_pointer_t<ItemSystem* __cdecl()> itemSystem;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,678 @@
|
||||
#include "SkinChanger.hpp"
|
||||
#include "Other.hpp"
|
||||
|
||||
VMTHook* GameEventManagerHook = nullptr;
|
||||
VMTHook* ClientHook = nullptr;
|
||||
std::vector<iitem> rarities;
|
||||
std::vector<iitem> knives;
|
||||
std::vector<iitem> gloves;
|
||||
std::vector<iitem> agents;
|
||||
std::vector<iitem> medals;
|
||||
std::vector<iitem> musickits;
|
||||
std::vector <iitem> qualities;
|
||||
|
||||
std::add_pointer_t<ItemSystem* __cdecl()> itemSystem;
|
||||
|
||||
|
||||
|
||||
|
||||
enum class EStickerAttributeType
|
||||
{
|
||||
Index,
|
||||
Wear,
|
||||
Scale,
|
||||
Rotation
|
||||
};
|
||||
|
||||
static auto s_econ_item_interface_wrapper_offset = std::uint16_t(0);
|
||||
|
||||
struct GetStickerAttributeBySlotIndexFloat
|
||||
{
|
||||
static auto __fastcall hooked(void* thisptr, void*, const int slot,
|
||||
const EStickerAttributeType attribute, const float unknown) -> float
|
||||
{
|
||||
auto item = reinterpret_cast<C_BaseAttributableItem*>(std::uintptr_t(thisptr) - s_econ_item_interface_wrapper_offset);
|
||||
|
||||
const auto defindex = item->GetItemDefinitionIndex();
|
||||
|
||||
int config = GetCfgIndex(defindex);
|
||||
|
||||
if (config != -1)
|
||||
{
|
||||
switch (attribute)
|
||||
{
|
||||
case EStickerAttributeType::Wear:
|
||||
return g_Options.weapons.value->arr[config].stickers[slot].wear;
|
||||
case EStickerAttributeType::Scale:
|
||||
return g_Options.weapons.value->arr[config].stickers[slot].scale;
|
||||
case EStickerAttributeType::Rotation:
|
||||
return g_Options.weapons.value->arr[config].stickers[slot].rotation;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_original(thisptr, nullptr, slot, attribute, unknown);
|
||||
}
|
||||
|
||||
static decltype(&hooked) m_original;
|
||||
};
|
||||
|
||||
decltype(GetStickerAttributeBySlotIndexFloat::m_original) GetStickerAttributeBySlotIndexFloat::m_original;
|
||||
|
||||
struct GetStickerAttributeBySlotIndexInt
|
||||
{
|
||||
static auto __fastcall hooked(void* thisptr, void*, const int slot,
|
||||
const EStickerAttributeType attribute, const int unknown) -> int
|
||||
{
|
||||
auto item = reinterpret_cast<C_BaseAttributableItem*>(std::uintptr_t(thisptr) - s_econ_item_interface_wrapper_offset);
|
||||
|
||||
if (attribute == EStickerAttributeType::Index)
|
||||
{
|
||||
const auto defindex = item->GetItemDefinitionIndex();
|
||||
|
||||
int config = GetCfgIndex(defindex);
|
||||
|
||||
if (config != -1)
|
||||
return g_Options.weapons.value->arr[config].stickers[slot].stickerid;
|
||||
}
|
||||
|
||||
return m_original(thisptr, nullptr, slot, attribute, unknown);
|
||||
}
|
||||
|
||||
static decltype(&hooked) m_original;
|
||||
};
|
||||
|
||||
decltype(GetStickerAttributeBySlotIndexInt::m_original) GetStickerAttributeBySlotIndexInt::m_original;
|
||||
|
||||
|
||||
void ApplyStickers(C_BaseAttributableItem* item)
|
||||
{
|
||||
if (!s_econ_item_interface_wrapper_offset)
|
||||
s_econ_item_interface_wrapper_offset = netvar_manager::get().get_offset(FNV("CBaseAttributableItem->m_Item")) + 0xC;
|
||||
|
||||
static vmt_multi_hook hook;
|
||||
|
||||
const auto econ_item_interface_wrapper = std::uintptr_t(item) + s_econ_item_interface_wrapper_offset;
|
||||
|
||||
if (hook.initialize_and_hook_instance(reinterpret_cast<void*>(econ_item_interface_wrapper)))
|
||||
{
|
||||
hook.apply_hook<GetStickerAttributeBySlotIndexFloat>(4);
|
||||
hook.apply_hook<GetStickerAttributeBySlotIndexInt>(5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool __fastcall hkFireEventClientSide(void* thisptr, void* edx, IGameEvent* event)
|
||||
{
|
||||
static auto ofunc = GameEventManagerHook->GetOriginal<bool(__fastcall*)(void*, void*, IGameEvent*)>(9);
|
||||
if (event) {
|
||||
if (!strcmp(event->GetName(), "player_death") && iff.g_pEngineClient->GetPlayerForUserID(event->GetInt("attacker")) == iff.g_pEngineClient->GetLocalPlayer())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("BE playerdeath with %s\n", event->GetString("weapon"));
|
||||
#endif
|
||||
for (int i = 0; i < g_Options.weapons.value->weaponzcount; i++)
|
||||
{
|
||||
if (_tcsstr(g_Options.weapons.value->arr[i].killfeedicon, event->GetString("weapon")))
|
||||
{
|
||||
if (g_Options.weapons.value->arr[i].active && g_Options.weapons.value->arr[i].killfeediconactive)
|
||||
event->SetString("weapon", g_Options.weapons.value->arr[i].killfeediconreplace);
|
||||
|
||||
if (!g_Options.weapons.value->arr[i].ownerunk && g_Options.weapons.value->arr[i].stattrak != -1)
|
||||
g_Options.weapons.value->arr[i].stattrak += 1;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ofunc(thisptr, edx, event);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
C_CS_PlayerResource** g_player_resource;
|
||||
|
||||
#include <array>
|
||||
bool Changer()
|
||||
{
|
||||
static bool initinterface = 0;
|
||||
if (!initinterface) {
|
||||
const auto team_arr_prop = C_CS_PlayerResource::GetTeamProp();
|
||||
const auto team_prop = team_arr_prop->m_pDataTable->m_pProps;
|
||||
const auto proxy_addr = std::uintptr_t(team_prop->m_ProxyFn);
|
||||
g_player_resource = *reinterpret_cast<C_CS_PlayerResource***>(proxy_addr + 0x10);
|
||||
#ifdef DEBUG
|
||||
printf("g_player_resource initiated %x\n", g_player_resource);
|
||||
#endif
|
||||
initinterface = 1;
|
||||
}
|
||||
|
||||
if (!iff.g_pEngineClient->IsConnected()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int localplayer_index = iff.g_pEngineClient->GetLocalPlayer();
|
||||
C_BasePlayer* localplayer = static_cast<C_BasePlayer*>(iff.g_pEntityList->GetClientEntity(localplayer_index));
|
||||
|
||||
if (!localplayer)
|
||||
return 0;
|
||||
|
||||
|
||||
auto player_resource = *g_player_resource;
|
||||
|
||||
if (g_Options.weapons.value->arr[4].active)
|
||||
player_resource->GetCoins()[localplayer_index] = g_Options.weapons.value->arr[4].modeldefindex;
|
||||
|
||||
if (g_Options.weapons.value->arr[5].active)
|
||||
player_resource->GetMusicKits()[localplayer_index] = g_Options.weapons.value->arr[5].modeldefindex;
|
||||
|
||||
if (g_Options.profile_active)
|
||||
{
|
||||
int ranktype = player_resource->GetRankType()[localplayer_index];
|
||||
int selectedrank = 0;
|
||||
if (ranktype == 7) selectedrank = 1;
|
||||
if (ranktype == 10) selectedrank = 2;
|
||||
|
||||
player_resource->GetRanks()[localplayer_index] = g_Options.rankz.value->arr[selectedrank].rank;
|
||||
player_resource->GetWins()[localplayer_index] = g_Options.rankz.value->arr[selectedrank].wins;
|
||||
|
||||
player_resource->GetLevel()[localplayer_index] = g_Options.level;
|
||||
player_resource->GetComLeader()[localplayer_index] = g_Options.comleader;
|
||||
player_resource->GetComTeacher()[localplayer_index] = g_Options.comteacher;
|
||||
player_resource->GetComFriendly()[localplayer_index] = g_Options.comfriendly;
|
||||
}
|
||||
|
||||
if (g_Options.fakescore)
|
||||
{
|
||||
player_resource->GetMVPs()[localplayer_index] = g_Options.MVPs;
|
||||
player_resource->GetScore()[localplayer_index] = g_Options.score;
|
||||
player_resource->GetKills()[localplayer_index] = g_Options.kills;
|
||||
player_resource->GetAssists()[localplayer_index] = g_Options.assists;
|
||||
player_resource->GetDeaths()[localplayer_index] = g_Options.deaths;
|
||||
}
|
||||
|
||||
|
||||
int team = localplayer->GetTeam(); char* model = 0;
|
||||
if (team == TEAM_TERRORIST && g_Options.weapons.value->arr[2].active && g_Options.weapons.value->arr[2].modelactive)
|
||||
model = g_Options.weapons.value->arr[2].model;
|
||||
if (team == TEAM_CT && g_Options.weapons.value->arr[3].active && g_Options.weapons.value->arr[3].modelactive)
|
||||
model = g_Options.weapons.value->arr[3].model;
|
||||
|
||||
|
||||
if (model != 0) {
|
||||
localplayer->GetModelIndex() = iff.g_pMdlInfo->GetModelIndex(model);
|
||||
if (const auto modelprecache = iff.g_pNetworkStringTableContainer->FindTable("modelprecache"))
|
||||
{
|
||||
modelprecache->AddString(false, model);
|
||||
const auto viewmodelArmConfig = iff.getPlayerViewmodelArmConfigForPlayerModel(model);
|
||||
modelprecache->AddString(false, viewmodelArmConfig[2]);
|
||||
modelprecache->AddString(false, viewmodelArmConfig[3]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const auto m_hRagdoll = (C_BaseEntity*)iff.g_pEntityList->GetClientEntityFromHandle(localplayer->Ragdoll());
|
||||
if (m_hRagdoll)
|
||||
m_hRagdoll->GetModelIndex() = iff.g_pMdlInfo->GetModelIndex(model);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (localplayer->GetLifeState() != LIFE_ALIVE)
|
||||
{
|
||||
if (g_Options.weapons.value->arr[1].active && g_Options.weapons.value->arr[1].modelactive) {
|
||||
auto destroyglove = iff.g_pEntityList->GetClientEntityFromHandle(localplayer->GetWearables()[0]);
|
||||
if (destroyglove) {
|
||||
destroyglove->GetClientNetworkable()->SetDestroyedOnRecreateEntities();
|
||||
destroyglove->GetClientNetworkable()->Release();
|
||||
#ifdef DEBUG
|
||||
printf("destroyed glove\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
player_info_t localplayer_info;
|
||||
if (!iff.g_pEngineClient->GetPlayerInfo(localplayer_index, &localplayer_info))
|
||||
return 0;
|
||||
|
||||
CBaseHandle viewmodelHandle = localplayer->GetViewModel();
|
||||
C_BaseViewModel* pViewModel = (C_BaseViewModel*)iff.g_pEntityList->GetClientEntityFromHandle(viewmodelHandle);
|
||||
const auto view_model_weapon = (C_BaseAttributableItem*)iff.g_pEntityList->GetClientEntityFromHandle(pViewModel->GetWeapon());
|
||||
|
||||
int idi = view_model_weapon->GetItemDefinitionIndex();
|
||||
if (idi == WEAPON_KNIFE) idi = WEAPON_KNIFE_T;
|
||||
|
||||
int modelcfgindex = GetCfgIndex2(idi);
|
||||
if (modelcfgindex != -1 && g_Options.models.value->arr[modelcfgindex].active)
|
||||
{
|
||||
char* model = g_Options.models.value->arr[modelcfgindex].vmodel_repl;
|
||||
const auto override_model_index = iff.g_pMdlInfo->GetModelIndex(model);
|
||||
view_model_weapon->SetModelIndex(override_model_index) ;
|
||||
pViewModel->SetModelIndex(override_model_index) ;
|
||||
if (const auto modelprecache = iff.g_pNetworkStringTableContainer->FindTable("modelprecache"))
|
||||
{
|
||||
modelprecache->AddString(false, model);
|
||||
}
|
||||
}
|
||||
|
||||
int seqact = opt.needtogetseqact;
|
||||
if (seqact)
|
||||
{
|
||||
int oldmodelindex = pViewModel->GetModelIndex();
|
||||
pViewModel->SetModelIndex(iff.g_pMdlInfo->GetModelIndex(g_Options.models.value->arr[seqact].vmodel_orig));
|
||||
for (int i = 0; i < 20; i++)
|
||||
strcpy(g_Options.models.value->arr[seqact].seqs[i].seq_orig_def, (char*)pViewModel->GetSequenceActivity(i));
|
||||
pViewModel->SetModelIndex(iff.g_pMdlInfo->GetModelIndex(g_Options.models.value->arr[seqact].vmodel_repl));
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
strcpy(g_Options.models.value->arr[seqact].seqs[i].seq_repl_def, (char*)pViewModel->GetSequenceActivity(i));
|
||||
|
||||
char newpreview[32] = "";
|
||||
strcat_s(newpreview, std::to_string(i).c_str());
|
||||
strcat_s(newpreview, ": ");
|
||||
strcat_s(newpreview, g_Options.models.value->arr[seqact].seqs[i].seq_repl_def);
|
||||
strcpy(g_Options.models.value->arr[seqact].seqs[i].seq_repl_def_preview, newpreview);
|
||||
}
|
||||
pViewModel->SetModelIndex(oldmodelindex);
|
||||
opt.needtogetseqact = 0;
|
||||
}
|
||||
|
||||
if (g_Options.weapons.value->arr[1].active && g_Options.weapons.value->arr[1].modelactive)
|
||||
{
|
||||
auto hWearables = localplayer->GetWearables();
|
||||
|
||||
static int glove_handle;
|
||||
C_BaseAttributableItem* glove = (C_BaseAttributableItem*)iff.g_pEntityList->GetClientEntityFromHandle(hWearables[0] );
|
||||
|
||||
if (!glove)
|
||||
{
|
||||
C_BaseAttributableItem* our_glove = (C_BaseAttributableItem*)iff.g_pEntityList->GetClientEntityFromHandle(glove_handle);
|
||||
|
||||
if (our_glove)
|
||||
{
|
||||
hWearables[0] = glove_handle;
|
||||
glove = our_glove;
|
||||
}
|
||||
}
|
||||
|
||||
if (!glove)
|
||||
{
|
||||
static std::add_pointer_t<C_BaseEntity* __cdecl(int, int)> createWearable = nullptr;
|
||||
|
||||
if (!createWearable) {
|
||||
createWearable = []() -> decltype(createWearable)
|
||||
{
|
||||
for (auto clientClass = iff.g_pClient->GetAllClasses(); clientClass; clientClass = clientClass->m_pNext)
|
||||
if (clientClass->m_ClassID == 54)
|
||||
return (std::add_pointer_t<C_BaseEntity* __cdecl(int, int)>)clientClass->m_pCreateFn;
|
||||
return nullptr;
|
||||
}();
|
||||
}
|
||||
|
||||
const auto serial = rand() % 0x1000;
|
||||
auto entry = iff.g_pEntityList->GetHighestEntityIndex() + 1;
|
||||
for (int i = 65; i < iff.g_pEntityList->GetHighestEntityIndex(); i++)
|
||||
{
|
||||
auto pEntity = iff.g_pEntityList->GetClientEntity(i);
|
||||
if (pEntity && pEntity->GetClientClass()->m_ClassID == 70)
|
||||
{
|
||||
entry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
createWearable(entry, serial);
|
||||
glove = (C_BaseAttributableItem*)iff.g_pEntityList->GetClientEntity(entry);
|
||||
glove->initialized() = true;
|
||||
hWearables[0] = entry | serial << 16;
|
||||
|
||||
static int(__thiscall * equipWearable)(void* wearable, void* player) = reinterpret_cast<decltype(equipWearable)>(FindPatternV2("client.dll", "55 8B EC 83 EC 10 53 8B 5D 08 57 8B F9"));
|
||||
equipWearable(glove, localplayer);
|
||||
localplayer->body() = 1;
|
||||
glove->SetModelIndex(iff.g_pMdlInfo->GetModelIndex(g_Options.weapons.value->arr[1].worldmodel));
|
||||
iff.g_pClientState->ForceFullUpdate();
|
||||
}
|
||||
|
||||
if (glove)
|
||||
{
|
||||
glove->GetItemDefinitionIndex() = g_Options.weapons.value->arr[1].modeldefindex;
|
||||
glove->GetItemIDHigh() = -1;
|
||||
glove->GetAccountID() = localplayer_info.xuidlow;
|
||||
glove->GetFallbackPaintKit() = g_Options.weapons.value->arr[1].skinid;
|
||||
glove->GetFallbackSeed() = g_Options.weapons.value->arr[1].seed;
|
||||
glove->GetFallbackWear() = g_Options.weapons.value->arr[1].wear;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (g_Options.weapons.value->arr[0].active && g_Options.weapons.value->arr[0].modelactive)
|
||||
{
|
||||
|
||||
static int lastmdlindex = -1;
|
||||
int curmdlindex = pViewModel->GetModelIndex();
|
||||
if (lastmdlindex != curmdlindex)
|
||||
{
|
||||
lastmdlindex = curmdlindex;
|
||||
int defindex = view_model_weapon->GetItemDefinitionIndex();
|
||||
|
||||
if (!is_knife(defindex)) {
|
||||
for (int i = 0; i < 20; i++)
|
||||
if (_tcsstr(pViewModel->GetSequenceActivity(i), "draw"))
|
||||
{
|
||||
pViewModel->SendViewModelMatchingSequence(i); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (view_model_weapon && is_knife(view_model_weapon->GetItemDefinitionIndex()))
|
||||
{
|
||||
const auto override_model_index = iff.g_pMdlInfo->GetModelIndex(g_Options.weapons.value->arr[0].model);
|
||||
pViewModel->GetModelIndex() = override_model_index;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
auto& weapons = localplayer->GetWeapons();
|
||||
|
||||
for (auto weapon_handle : weapons)
|
||||
{
|
||||
if (weapon_handle == INVALID_EHANDLE_INDEX)
|
||||
break;
|
||||
|
||||
C_BaseAttributableItem* weapon = static_cast<C_BaseAttributableItem*>(iff.g_pEntityList->GetClientEntityFromHandle(weapon_handle));
|
||||
|
||||
if (!weapon)
|
||||
continue;
|
||||
|
||||
short item_definition_index = weapon->GetItemDefinitionIndex();
|
||||
|
||||
if (item_definition_index == WEAPON_C4 && g_Options.weapons.value->arr[GetCfgIndex(item_definition_index)].active)
|
||||
weapon->body() = 2;
|
||||
|
||||
if (item_definition_index == 42) item_definition_index = 59;
|
||||
|
||||
|
||||
|
||||
int configindex = GetCfgIndex(item_definition_index);
|
||||
if (configindex == -1) continue;
|
||||
|
||||
if (g_Options.weapons.value->arr[configindex].active)
|
||||
{
|
||||
if (is_knife(item_definition_index) && g_Options.weapons.value->arr[0].modelactive)
|
||||
{
|
||||
weapon->GetItemDefinitionIndex() = g_Options.weapons.value->arr[0].modeldefindex;
|
||||
short mdlindex = iff.g_pMdlInfo->GetModelIndex(g_Options.weapons.value->arr[0].model);
|
||||
weapon->GetModelIndex() = mdlindex;
|
||||
auto m_pWorld = (C_BaseEntity*)iff.g_pEntityList->GetClientEntityFromHandle(weapon->GetWeaponWorldModel());
|
||||
m_pWorld->GetModelIndex() = mdlindex+1;
|
||||
}
|
||||
weapon->GetItemIDHigh() = -1;
|
||||
|
||||
if (!g_Options.weapons.value->arr[configindex].ownerunk)
|
||||
weapon->GetAccountID() = localplayer_info.xuidlow;
|
||||
weapon->GetEntityQuality() = g_Options.weapons.value->arr[configindex].quality;
|
||||
snprintf(weapon->GetCustomName(), 32, "%s", g_Options.weapons.value->arr[configindex].nametag);
|
||||
|
||||
weapon->GetFallbackPaintKit() = g_Options.weapons.value->arr[configindex].skinid;
|
||||
weapon->GetFallbackSeed() = g_Options.weapons.value->arr[configindex].seed;
|
||||
weapon->GetFallbackWear() = g_Options.weapons.value->arr[configindex].wear;
|
||||
weapon->GetFallbackStatTrak() = g_Options.weapons.value->arr[configindex].stattrak;
|
||||
|
||||
ApplyStickers(weapon);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (*g_Options.nvgsON)
|
||||
NightvisionRun(localplayer);
|
||||
|
||||
if (*g_Options.flashlightON)
|
||||
FlashlightRun(localplayer);
|
||||
|
||||
if (*g_Options.weatheractive)
|
||||
do_precipitation();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void __fastcall hkFrameStageNotify(IBaseClientDLL* thisptr, void* edx, ClientFrameStage_t stage)
|
||||
{
|
||||
static auto oFrameStageNotify = ClientHook->GetOriginal<void(__thiscall*)(IBaseClientDLL*, ClientFrameStage_t stage)>(37);
|
||||
|
||||
if ( (*g_Options.playerloop_count || *g_Options.entityloop_count) && stage == ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END)
|
||||
{
|
||||
for (int i = 1; i < 65; i++)
|
||||
{
|
||||
C_BasePlayer* pEntity = (C_BasePlayer*)iff.g_pEntityList->GetClientEntity(i);
|
||||
|
||||
if (i == iff.g_pEngineClient->GetLocalPlayer()) continue;
|
||||
|
||||
if (!pEntity || pEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
int team = pEntity->GetTeam();
|
||||
if ((team < 2) | (team > 3)) continue;
|
||||
team -= 2;
|
||||
|
||||
if (g_Options.models.value->arr[team].active) {
|
||||
|
||||
char* model = g_Options.models.value->arr[team].vmodel_repl;
|
||||
|
||||
pEntity->GetModelIndex() = iff.g_pMdlInfo->GetModelIndex(model);
|
||||
if (const auto modelprecache = iff.g_pNetworkStringTableContainer->FindTable("modelprecache"))
|
||||
{
|
||||
modelprecache->AddString(false, model);
|
||||
const auto viewmodelArmConfig = iff.getPlayerViewmodelArmConfigForPlayerModel(model);
|
||||
modelprecache->AddString(false, viewmodelArmConfig[2]);
|
||||
modelprecache->AddString(false, viewmodelArmConfig[3]);
|
||||
}
|
||||
|
||||
const auto m_hRagdoll = (C_BaseEntity*)iff.g_pEntityList->GetClientEntityFromHandle(pEntity->Ragdoll());
|
||||
if (m_hRagdoll)
|
||||
m_hRagdoll->SetModelIndex(iff.g_pMdlInfo->GetModelIndex(model));
|
||||
}
|
||||
|
||||
if (g_Options.models.value->arr[team].active_scale)
|
||||
pEntity->GetModelScale() = g_Options.models.value->arr[team].scale;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (stage == ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_START) {
|
||||
|
||||
Changer();
|
||||
|
||||
|
||||
|
||||
|
||||
if (opt.needupdate) {
|
||||
static auto clear_hud_weapon_icon_ptr = FindPatternV2("client.dll", "55 8B EC 51 53 56 8B 75 08 8B D9 57 6B FE 2C");
|
||||
static auto clearHudWeapon = reinterpret_cast<std::int32_t(__thiscall*)(void*, std::int32_t)>(clear_hud_weapon_icon_ptr);
|
||||
auto element = FindHudElement("CCSGO_HudWeaponSelection");
|
||||
auto hud_weapons = reinterpret_cast<hud_weapons_t*>(std::uintptr_t(element) - 0xA0);
|
||||
|
||||
if (hud_weapons && *hud_weapons->get_weapon_count() > 0)
|
||||
for (std::int32_t i = 0; i < *hud_weapons->get_weapon_count(); i++)
|
||||
i = clearHudWeapon(hud_weapons, i);
|
||||
|
||||
opt.needupdate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
oFrameStageNotify(thisptr, stage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void InitSkinChanger()
|
||||
{
|
||||
itemSystem = relativeToAbsolute<decltype(itemSystem)>(FindPatternV2("client.dll", "E8 ? ? ? ? 0F B7 0F") + 1);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("itemschema2 %x\n", itemSystem()->getItemSchema());
|
||||
#endif
|
||||
|
||||
for (const auto& node : itemSystem()->getItemSchema()->itemsSorted) {
|
||||
const auto item = node.value;
|
||||
|
||||
if (std::strcmp(item->m_szWeaponType, "#CSGO_Type_Knife") == 0)
|
||||
if (item->m_szWorldModel)
|
||||
knives.push_back(iitem(item->m_iItemDefinitionIndex, item->m_szWeaponName3, item->m_szViewModel, item->m_szWorldModel));
|
||||
else knives.push_back(iitem(item->m_iItemDefinitionIndex, item->m_szWeaponName3, item->m_szViewModel, ""));
|
||||
|
||||
if (std::strcmp(item->m_szWeaponType, "#CSGO_Type_Collectible") == 0)
|
||||
medals.push_back(iitem(item->m_iItemDefinitionIndex, item->m_szWeaponName3, "", ""));
|
||||
|
||||
if (std::strcmp(item->m_szWeaponType, "#Type_Hands") == 0)
|
||||
if (item->m_szWorldModel)
|
||||
gloves.push_back(iitem(item->m_iItemDefinitionIndex, item->m_szWeaponName3, item->m_szViewModel, item->m_szWorldModel));
|
||||
else gloves.push_back(iitem(item->m_iItemDefinitionIndex, item->m_szWeaponName3, item->m_szViewModel, ""));
|
||||
|
||||
if (std::strcmp(item->m_szWeaponType, "#Type_CustomPlayer") == 0)
|
||||
if (item->m_szWorldModel)
|
||||
agents.push_back(iitem(item->m_iItemDefinitionIndex, item->m_szWeaponName3, item->m_szViewModel, item->m_szWorldModel));
|
||||
else agents.push_back(iitem(item->m_iItemDefinitionIndex, item->m_szWeaponName3, item->m_szViewModel, ""));
|
||||
|
||||
}
|
||||
|
||||
for (const auto& node : itemSystem()->getItemSchema()->qualities) {
|
||||
const auto item = node.value;
|
||||
qualities.push_back(iitem(item.id, item.name, "", ""));
|
||||
}
|
||||
|
||||
for (const auto& node : itemSystem()->getItemSchema()->rars) {
|
||||
const auto item = node.value;
|
||||
rarities.push_back(iitem(item.id, item.name.szBuffer, "", ""));
|
||||
}
|
||||
|
||||
auto musickitsS = itemSystem()->getItemSchema()->music_definitions;
|
||||
#ifdef DEBUG
|
||||
std::cout << musickitsS.memory << " " << musickitsS.itemcount << std::endl;
|
||||
#endif
|
||||
for (int i = (int)musickitsS.memory; i < (int)musickitsS.memory + musickitsS.itemcount * 0x18; i += 0x18)
|
||||
{
|
||||
CEconMusicDefinition* music = *(CEconMusicDefinition**)(i + 0x14);
|
||||
musickits.push_back(iitem(music->id, music->name, "", ""));
|
||||
}
|
||||
|
||||
const auto& paintkitMap = itemSystem()->getItemSchema()->paintKits;
|
||||
int paintkitcount = 0;
|
||||
for (const auto& node : paintkitMap) {
|
||||
const auto pKit = node.value;
|
||||
opt.sc_skins.push_back(Options_my::skinstruct(pKit->nID, pKit->sName.szBuffer, paintkitcount, pKit->rarity, pKit->color1, pKit->color2, pKit->color3, pKit->color4, pKit->pearlescent, (DWORD)&pKit->nID));
|
||||
paintkitcount++;
|
||||
}
|
||||
|
||||
const auto& stickerMap = itemSystem()->getItemSchema()->stickerKits;
|
||||
int stickercount = 0;
|
||||
for (const auto& node : stickerMap) {
|
||||
const auto stickerKit = node.value;
|
||||
opt.sc_stickers.push_back(Options_my::stickerstruct(stickerKit->id, stickerKit->name.szBuffer, stickercount));
|
||||
stickercount++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("counts %d %d %d %d %d %d %d\n",
|
||||
knives.size(), gloves.size(), agents.size(), medals.size(), musickits.size(), opt.sc_skins.size(), opt.sc_stickers.size());
|
||||
#endif
|
||||
|
||||
const auto& prefabMap = itemSystem()->getItemSchema()->prefabs;
|
||||
for (const auto& node : prefabMap) {
|
||||
KeyValues* kv = node.value;
|
||||
int cfgindex = GetCfgIndexByPrefab(fnv2::hash(kv->GetName()));
|
||||
if (cfgindex == -1) continue;
|
||||
int soundcount = 0;
|
||||
const char* vmodel_orig = kv->GetString("model_player");
|
||||
strcpy(g_Options.models.value->arr[cfgindex].vmodel_orig, vmodel_orig);
|
||||
strcpy(g_Options.models.value->arr[cfgindex].vmodel_repl_temp, vmodel_orig);
|
||||
strcpy(g_Options.models.value->arr[cfgindex].vmodel_repl, vmodel_orig);
|
||||
|
||||
g_Options.materials.value->arr[cfgindex + 2].model_hash = fnv2::hash(vmodel_orig);
|
||||
|
||||
|
||||
kv = kv->FindKey("visuals");
|
||||
if (kv) {
|
||||
char* sound_single_shot = (char*)kv->GetString("sound_single_shot");
|
||||
if (sound_single_shot[0] != 0x0) {
|
||||
strcpy(g_Options.models.value->arr[cfgindex].sounds[soundcount].name, sound_single_shot);
|
||||
g_Options.models.value->arr[cfgindex].sounds[soundcount].hash = GenerateSoundEntryHash(sound_single_shot);
|
||||
soundcount++;
|
||||
}
|
||||
|
||||
char* sound_single_shot_accurate = (char*)kv->GetString("sound_single_shot_accurate");
|
||||
if (sound_single_shot_accurate[0] != 0x0) {
|
||||
strcpy(g_Options.models.value->arr[cfgindex].sounds[soundcount].name, sound_single_shot);
|
||||
g_Options.models.value->arr[cfgindex].sounds[soundcount].hash = GenerateSoundEntryHash(sound_single_shot);
|
||||
soundcount++;
|
||||
}
|
||||
|
||||
char* sound_special1 = (char*)kv->GetString("sound_special1");
|
||||
if (sound_special1[0] != 0x0) {
|
||||
strcpy(g_Options.models.value->arr[cfgindex].sounds[soundcount].name, sound_special1);
|
||||
g_Options.models.value->arr[cfgindex].sounds[soundcount].hash = GenerateSoundEntryHash(sound_special1);
|
||||
soundcount++;
|
||||
}
|
||||
}
|
||||
g_Options.models.value->arr[cfgindex].soundcount = soundcount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
c_vpk_archive pak01_archive;
|
||||
if (pak01_archive.load("csgo/pak01_dir.vpk"))
|
||||
for (auto const& pair : pak01_archive.files)
|
||||
if (!pair.first.find("materials/panorama/images/icons/equipment"))
|
||||
opt.killfeedicons.push_back(pair.first.substr(42, pair.first.length() - 46));
|
||||
|
||||
|
||||
g_Options.weapons.value->arr[0].modeldefindex = knives[0].defindex;
|
||||
strcpy(g_Options.weapons.value->arr[0].model, knives[0].viewmodel.c_str());
|
||||
strcpy(g_Options.weapons.value->arr[0].worldmodel, knives[0].worldmodel.c_str());
|
||||
g_Options.weapons.value->arr[0].modelactive = 1;
|
||||
|
||||
g_Options.weapons.value->arr[1].modeldefindex = gloves[0].defindex;
|
||||
strcpy(g_Options.weapons.value->arr[1].model, gloves[0].viewmodel.c_str());
|
||||
strcpy(g_Options.weapons.value->arr[1].worldmodel, gloves[0].worldmodel.c_str());
|
||||
g_Options.weapons.value->arr[1].modelactive = 1;
|
||||
|
||||
g_Options.weapons.value->arr[2].modeldefindex = agents[0].defindex;
|
||||
strcpy(g_Options.weapons.value->arr[2].model, agents[0].viewmodel.c_str());
|
||||
g_Options.weapons.value->arr[2].modelactive = 1;
|
||||
|
||||
g_Options.weapons.value->arr[3].modelcount = 1;
|
||||
g_Options.weapons.value->arr[3].modeldefindex = agents[1].defindex;
|
||||
strcpy(g_Options.weapons.value->arr[3].model, agents[1].viewmodel.c_str());
|
||||
g_Options.weapons.value->arr[3].modelactive = 1;
|
||||
|
||||
g_Options.weapons.value->arr[4].modeldefindex = medals[0].defindex;
|
||||
g_Options.weapons.value->arr[4].modelactive = 1;
|
||||
|
||||
g_Options.weapons.value->arr[5].modeldefindex = musickits[0].defindex;
|
||||
g_Options.weapons.value->arr[5].modelactive = 1;
|
||||
|
||||
g_Options.models.value->arr[2].findMDLmethode = 1;
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,80 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian (Russia) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian (Russia) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WAVE
|
||||
//
|
||||
|
||||
IDR_WAVE1 WAVE "cod.wav"
|
||||
IDR_WAVE2 WAVE "crit.wav"
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,560 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{bde23281-b75d-4fb2-9b8e-08e1ae0a9bbd}</ProjectGuid>
|
||||
<RootNamespace>SpyCustom</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Seaside</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>C:\Program Files (x86)\GnuWin32\include;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files (x86)\GnuWin32\lib;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;SPYCUSTOM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;SPYCUSTOM_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>Winmm.lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;SPYCUSTOM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;SPYCUSTOM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ai_activity.h" />
|
||||
<ClInclude Include="AnalogCode.h" />
|
||||
<ClInclude Include="animationlayer.h" />
|
||||
<ClInclude Include="annotations.h" />
|
||||
<ClInclude Include="baseclientstate.h" />
|
||||
<ClInclude Include="baseentity.h" />
|
||||
<ClInclude Include="baseentity_shared.h" />
|
||||
<ClInclude Include="basehandle.h" />
|
||||
<ClInclude Include="basetypes.h" />
|
||||
<ClInclude Include="beam_flags.h" />
|
||||
<ClInclude Include="bitbuf.h" />
|
||||
<ClInclude Include="bittools.h" />
|
||||
<ClInclude Include="bitvec.h" />
|
||||
<ClInclude Include="bone_accessor.h" />
|
||||
<ClInclude Include="bone_merge_cache.h" />
|
||||
<ClInclude Include="bspfile.h" />
|
||||
<ClInclude Include="bspflags.h" />
|
||||
<ClInclude Include="BuildGroup.h" />
|
||||
<ClInclude Include="bumpvects.h" />
|
||||
<ClInclude Include="Button.h" />
|
||||
<ClInclude Include="ButtonCode.h" />
|
||||
<ClInclude Include="byteswap.h" />
|
||||
<ClInclude Include="cdll_client_int.h" />
|
||||
<ClInclude Include="cdll_int.h" />
|
||||
<ClInclude Include="cdll_util.h" />
|
||||
<ClInclude Include="CGameUI.h" />
|
||||
<ClInclude Include="CheckButton.h" />
|
||||
<ClInclude Include="checksum_crc.h" />
|
||||
<ClInclude Include="checksum_md5.h" />
|
||||
<ClInclude Include="cliententitylist.h" />
|
||||
<ClInclude Include="clientleafsystem.h" />
|
||||
<ClInclude Include="client_class.h" />
|
||||
<ClInclude Include="client_render_handle.h" />
|
||||
<ClInclude Include="client_thinklist.h" />
|
||||
<ClInclude Include="client_virtualreality.h" />
|
||||
<ClInclude Include="cmodel.h" />
|
||||
<ClInclude Include="collisionproperty.h" />
|
||||
<ClInclude Include="Color.h" />
|
||||
<ClInclude Include="commonmacros.h" />
|
||||
<ClInclude Include="compressed_light_cube.h" />
|
||||
<ClInclude Include="compressed_vector.h" />
|
||||
<ClInclude Include="Config.hpp" />
|
||||
<ClInclude Include="const.h" />
|
||||
<ClInclude Include="Controls.h" />
|
||||
<ClInclude Include="convar.h" />
|
||||
<ClInclude Include="csgosdk.h" />
|
||||
<ClInclude Include="cs_achievementdefs.h" />
|
||||
<ClInclude Include="cs_shareddefs.h" />
|
||||
<ClInclude Include="cs_view_scene.h" />
|
||||
<ClInclude Include="Cursor.h" />
|
||||
<ClInclude Include="c_baseanimating.h" />
|
||||
<ClInclude Include="c_baseanimatingoverlay.h" />
|
||||
<ClInclude Include="c_basecombatcharacter.h" />
|
||||
<ClInclude Include="c_baseentity.h" />
|
||||
<ClInclude Include="c_baseflex.h" />
|
||||
<ClInclude Include="c_baseplayer.h" />
|
||||
<ClInclude Include="c_basetempentity.h" />
|
||||
<ClInclude Include="c_input.h" />
|
||||
<ClInclude Include="c_pixel_visibility.h" />
|
||||
<ClInclude Include="c_playerlocaldata.h" />
|
||||
<ClInclude Include="c_recipientfilter.h" />
|
||||
<ClInclude Include="c_te_legacytempents.h" />
|
||||
<ClInclude Include="Dar.h" />
|
||||
<ClInclude Include="datamap.h" />
|
||||
<ClInclude Include="dbg.h" />
|
||||
<ClInclude Include="dbgflag.h" />
|
||||
<ClInclude Include="deformations.h" />
|
||||
<ClInclude Include="detours.h" />
|
||||
<ClInclude Include="dlight.h" />
|
||||
<ClInclude Include="dmattributetypes.h" />
|
||||
<ClInclude Include="dmelementhandle.h" />
|
||||
<ClInclude Include="dmxattribute.h" />
|
||||
<ClInclude Include="dmxelement.h" />
|
||||
<ClInclude Include="dmxloader.h" />
|
||||
<ClInclude Include="dt_common.h" />
|
||||
<ClInclude Include="dt_recv.h" />
|
||||
<ClInclude Include="dt_send.h" />
|
||||
<ClInclude Include="econ_item_constants.h" />
|
||||
<ClInclude Include="econ_item_interface.h" />
|
||||
<ClInclude Include="econ_item_schema.h" />
|
||||
<ClInclude Include="econ_item_view.h" />
|
||||
<ClInclude Include="edict.h" />
|
||||
<ClInclude Include="EditablePanel.h" />
|
||||
<ClInclude Include="ehandle.h" />
|
||||
<ClInclude Include="eiface.h" />
|
||||
<ClInclude Include="enginetrace.h" />
|
||||
<ClInclude Include="entitylist.h" />
|
||||
<ClInclude Include="entitylist_base.h" />
|
||||
<ClInclude Include="EventListener.hpp" />
|
||||
<ClInclude Include="expressioncalculator.h" />
|
||||
<ClInclude Include="exprevaluator.h" />
|
||||
<ClInclude Include="fasttimer.h" />
|
||||
<ClInclude Include="filesystem.h" />
|
||||
<ClInclude Include="filesystem_passthru.h" />
|
||||
<ClInclude Include="flashlighteffect.h" />
|
||||
<ClInclude Include="fltx4.h" />
|
||||
<ClInclude Include="FocusNavGroup.h" />
|
||||
<ClInclude Include="Frame.h" />
|
||||
<ClInclude Include="functors.h" />
|
||||
<ClInclude Include="fx.h" />
|
||||
<ClInclude Include="gameconsole.h" />
|
||||
<ClInclude Include="GameEventListener.h" />
|
||||
<ClInclude Include="GameEventManager.h" />
|
||||
<ClInclude Include="gamestringpool.h" />
|
||||
<ClInclude Include="gametrace.h" />
|
||||
<ClInclude Include="game_item_schema.h" />
|
||||
<ClInclude Include="generichash.h" />
|
||||
<ClInclude Include="GetVfunc.hpp" />
|
||||
<ClInclude Include="globalvars_base.h" />
|
||||
<ClInclude Include="groundlink.h" />
|
||||
<ClInclude Include="Hooks.hpp" />
|
||||
<ClInclude Include="htmlmessages.h" />
|
||||
<ClInclude Include="hud.h" />
|
||||
<ClInclude Include="hudelement.h" />
|
||||
<ClInclude Include="hudtexturehandle.h" />
|
||||
<ClInclude Include="hud_basechat.h" />
|
||||
<ClInclude Include="hud_element_helper.h" />
|
||||
<ClInclude Include="IAppSystem.h" />
|
||||
<ClInclude Include="IBorder.h" />
|
||||
<ClInclude Include="ichromehtmlwrapper.h" />
|
||||
<ClInclude Include="iclassmap.h" />
|
||||
<ClInclude Include="iclient.h" />
|
||||
<ClInclude Include="icliententity.h" />
|
||||
<ClInclude Include="icliententityinternal.h" />
|
||||
<ClInclude Include="icliententitylist.h" />
|
||||
<ClInclude Include="IClientLeafSystem.h" />
|
||||
<ClInclude Include="iclientmode.h" />
|
||||
<ClInclude Include="iclientnetworkable.h" />
|
||||
<ClInclude Include="IClientPanel.h" />
|
||||
<ClInclude Include="iclientrenderable.h" />
|
||||
<ClInclude Include="iclientshadowmgr.h" />
|
||||
<ClInclude Include="iclientthinkable.h" />
|
||||
<ClInclude Include="iclientunknown.h" />
|
||||
<ClInclude Include="iclientvirtualreality.h" />
|
||||
<ClInclude Include="ICollideable.h" />
|
||||
<ClInclude Include="IColorCorrection.h" />
|
||||
<ClInclude Include="icommandline.h" />
|
||||
<ClInclude Include="iconvar.h" />
|
||||
<ClInclude Include="icvar.h" />
|
||||
<ClInclude Include="idatacache.h" />
|
||||
<ClInclude Include="IEffects.h" />
|
||||
<ClInclude Include="iefx.h" />
|
||||
<ClInclude Include="ienginetrace.h" />
|
||||
<ClInclude Include="IEngineVgui.h" />
|
||||
<ClInclude Include="ifilelist.h" />
|
||||
<ClInclude Include="igameconsole.h" />
|
||||
<ClInclude Include="igameevents.h" />
|
||||
<ClInclude Include="IGameSystem.h" />
|
||||
<ClInclude Include="IGameUI.h" />
|
||||
<ClInclude Include="ihandleentity.h" />
|
||||
<ClInclude Include="IHTML.h" />
|
||||
<ClInclude Include="IImage.h" />
|
||||
<ClInclude Include="IInput.h" />
|
||||
<ClInclude Include="iinputsystem.h" />
|
||||
<ClInclude Include="IKeyValuesSystem.h" />
|
||||
<ClInclude Include="ILocalize.h" />
|
||||
<ClInclude Include="Image.h" />
|
||||
<ClInclude Include="imageformat.h" />
|
||||
<ClInclude Include="imaterial.h" />
|
||||
<ClInclude Include="imaterialsystem.h" />
|
||||
<ClInclude Include="imaterialsystemhardwareconfig.h" />
|
||||
<ClInclude Include="imdlcache.h" />
|
||||
<ClInclude Include="IMesh.h" />
|
||||
<ClInclude Include="imgui\imconfig.h" />
|
||||
<ClInclude Include="imgui\imgui.h" />
|
||||
<ClInclude Include="imgui\imgui_impl_dx9.h" />
|
||||
<ClInclude Include="imgui\imgui_impl_win32.h" />
|
||||
<ClInclude Include="imgui\imgui_internal.h" />
|
||||
<ClInclude Include="imgui\imstb_rectpack.h" />
|
||||
<ClInclude Include="imgui\imstb_textedit.h" />
|
||||
<ClInclude Include="imgui\imstb_truetype.h" />
|
||||
<ClInclude Include="imovehelper.h" />
|
||||
<ClInclude Include="inetchannel.h" />
|
||||
<ClInclude Include="inetchannelinfo.h" />
|
||||
<ClInclude Include="inetmessage.h" />
|
||||
<ClInclude Include="inetmsghandler.h" />
|
||||
<ClInclude Include="InputEnums.h" />
|
||||
<ClInclude Include="interface.h" />
|
||||
<ClInclude Include="Interfaces.hpp" />
|
||||
<ClInclude Include="interpolatedvar.h" />
|
||||
<ClInclude Include="inventory_changer.h" />
|
||||
<ClInclude Include="IPanel.h" />
|
||||
<ClInclude Include="ipredictionsystem.h" />
|
||||
<ClInclude Include="iscenetokenprocessor.h" />
|
||||
<ClInclude Include="IScheme.h" />
|
||||
<ClInclude Include="iserverentity.h" />
|
||||
<ClInclude Include="iservernetworkable.h" />
|
||||
<ClInclude Include="iserverplugin.h" />
|
||||
<ClInclude Include="iserverunknown.h" />
|
||||
<ClInclude Include="ishadowmgr.h" />
|
||||
<ClInclude Include="ispatialpartition.h" />
|
||||
<ClInclude Include="istudiorender.h" />
|
||||
<ClInclude Include="ISurface.h" />
|
||||
<ClInclude Include="ISystem.h" />
|
||||
<ClInclude Include="itempents.h" />
|
||||
<ClInclude Include="item_selection_criteria.h" />
|
||||
<ClInclude Include="itexture.h" />
|
||||
<ClInclude Include="itoolentity.h" />
|
||||
<ClInclude Include="ivdebugoverlay.h" />
|
||||
<ClInclude Include="IVGUI.h" />
|
||||
<ClInclude Include="IVguiMatInfo.h" />
|
||||
<ClInclude Include="IVguiMatInfoVar.h" />
|
||||
<ClInclude Include="iviewrender.h" />
|
||||
<ClInclude Include="iviewrender_beams.h" />
|
||||
<ClInclude Include="ivmodelinfo.h" />
|
||||
<ClInclude Include="ivmodelrender.h" />
|
||||
<ClInclude Include="ivrenderview.h" />
|
||||
<ClInclude Include="jobthread.h" />
|
||||
<ClInclude Include="KeyBindingMap.h" />
|
||||
<ClInclude Include="KeyCode.h" />
|
||||
<ClInclude Include="keyvalues.h" />
|
||||
<ClInclude Include="l2cache.h" />
|
||||
<ClInclude Include="Label.h" />
|
||||
<ClInclude Include="lerp_functions.h" />
|
||||
<ClInclude Include="lightdesc.h" />
|
||||
<ClInclude Include="ListPanel.h" />
|
||||
<ClInclude Include="localflexcontroller.h" />
|
||||
<ClInclude Include="logging.h" />
|
||||
<ClInclude Include="MaterialSystemUtil.h" />
|
||||
<ClInclude Include="mathlib.h" />
|
||||
<ClInclude Include="math_pfns.h" />
|
||||
<ClInclude Include="mem.h" />
|
||||
<ClInclude Include="memalloc.h" />
|
||||
<ClInclude Include="memdbgoff.h" />
|
||||
<ClInclude Include="memdbgon.h" />
|
||||
<ClInclude Include="mempool.h" />
|
||||
<ClInclude Include="Menu.h" />
|
||||
<ClInclude Include="Menu.hpp" />
|
||||
<ClInclude Include="MenuItem.h" />
|
||||
<ClInclude Include="meshreader.h" />
|
||||
<ClInclude Include="meshutils.h" />
|
||||
<ClInclude Include="messagebox.h" />
|
||||
<ClInclude Include="MessageMap.h" />
|
||||
<ClInclude Include="minidump.h" />
|
||||
<ClInclude Include="modelloader.h" />
|
||||
<ClInclude Include="modes.h" />
|
||||
<ClInclude Include="MouseCode.h" />
|
||||
<ClInclude Include="mouthinfo.h" />
|
||||
<ClInclude Include="netchannel.hpp" />
|
||||
<ClInclude Include="NetVarManager.hpp" />
|
||||
<ClInclude Include="netvars.hpp" />
|
||||
<ClInclude Include="networkvar.h" />
|
||||
<ClInclude Include="Options.hpp" />
|
||||
<ClInclude Include="Other.hpp" />
|
||||
<ClInclude Include="particledraw.h" />
|
||||
<ClInclude Include="particlemgr.h" />
|
||||
<ClInclude Include="particles.h" />
|
||||
<ClInclude Include="ParticleSphereRenderer.h" />
|
||||
<ClInclude Include="particles_new.h" />
|
||||
<ClInclude Include="particles_simple.h" />
|
||||
<ClInclude Include="particle_iterators.h" />
|
||||
<ClInclude Include="particle_parse.h" />
|
||||
<ClInclude Include="particle_property.h" />
|
||||
<ClInclude Include="particle_property_inlines.h" />
|
||||
<ClInclude Include="particle_util.h" />
|
||||
<ClInclude Include="PatternScan.hpp" />
|
||||
<ClInclude Include="pbwrap.hpp" />
|
||||
<ClInclude Include="PlayerInventory.hpp" />
|
||||
<ClInclude Include="playernet_vars.h" />
|
||||
<ClInclude Include="precipitation_shared.h" />
|
||||
<ClInclude Include="predictableid.h" />
|
||||
<ClInclude Include="predictable_entity.h" />
|
||||
<ClInclude Include="predictioncopy.h" />
|
||||
<ClInclude Include="ProtobuffMessages.h" />
|
||||
<ClInclude Include="protobuffs.hpp" />
|
||||
<ClInclude Include="ProtoParse.h" />
|
||||
<ClInclude Include="proxies.hpp" />
|
||||
<ClInclude Include="ragdoll.h" />
|
||||
<ClInclude Include="ragdoll_shared.h" />
|
||||
<ClInclude Include="rangecheckedvar.h" />
|
||||
<ClInclude Include="recvproxy.h" />
|
||||
<ClInclude Include="refcount.h" />
|
||||
<ClInclude Include="networkstringtabledefs.h" />
|
||||
<ClInclude Include="Panel.h" />
|
||||
<ClInclude Include="PanelAnimationVar.h" />
|
||||
<ClInclude Include="PHandle.h" />
|
||||
<ClInclude Include="platform.h" />
|
||||
<ClInclude Include="random.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="RichText.h" />
|
||||
<ClInclude Include="sceneentity_shared.h" />
|
||||
<ClInclude Include="sdk_hud_chat.h" />
|
||||
<ClInclude Include="seemath.h" />
|
||||
<ClInclude Include="sendproxy.h" />
|
||||
<ClInclude Include="sequence_Transitioner.h" />
|
||||
<ClInclude Include="shake.h" />
|
||||
<ClInclude Include="shareddefs.h" />
|
||||
<ClInclude Include="shared_classnames.h" />
|
||||
<ClInclude Include="shattersurfacetypes.h" />
|
||||
<ClInclude Include="Singleton.hpp" />
|
||||
<ClInclude Include="SkinChanger.hpp" />
|
||||
<ClInclude Include="smartptr.h" />
|
||||
<ClInclude Include="ssemath.h" />
|
||||
<ClInclude Include="steam.h" />
|
||||
<ClInclude Include="SteamCommon.h" />
|
||||
<ClInclude Include="steamtypes.h" />
|
||||
<ClInclude Include="stringpool.h" />
|
||||
<ClInclude Include="string_t.h" />
|
||||
<ClInclude Include="strtools.h" />
|
||||
<ClInclude Include="studio.h" />
|
||||
<ClInclude Include="tempentity.h" />
|
||||
<ClInclude Include="TextEntry.h" />
|
||||
<ClInclude Include="TextImage.h" />
|
||||
<ClInclude Include="texture_group_names.h" />
|
||||
<ClInclude Include="threadtools.h" />
|
||||
<ClInclude Include="tier1.h" />
|
||||
<ClInclude Include="tier2.h" />
|
||||
<ClInclude Include="tier2_logging.h" />
|
||||
<ClInclude Include="tier3.h" />
|
||||
<ClInclude Include="timedevent.h" />
|
||||
<ClInclude Include="timeutils.h" />
|
||||
<ClInclude Include="ToggleButton.h" />
|
||||
<ClInclude Include="Tooltip.h" />
|
||||
<ClInclude Include="touchlink.h" />
|
||||
<ClInclude Include="trace.h" />
|
||||
<ClInclude Include="tslist.h" />
|
||||
<ClInclude Include="uniqueid.h" />
|
||||
<ClInclude Include="usercmd.h" />
|
||||
<ClInclude Include="userid.h" />
|
||||
<ClInclude Include="utlblockmemory.h" />
|
||||
<ClInclude Include="utlbuffer.h" />
|
||||
<ClInclude Include="utldict.h" />
|
||||
<ClInclude Include="utlenvelope.h" />
|
||||
<ClInclude Include="utlfixedmemory.h" />
|
||||
<ClInclude Include="utlflags.h" />
|
||||
<ClInclude Include="utlhandletable.h" />
|
||||
<ClInclude Include="utlhash.h" />
|
||||
<ClInclude Include="utlintrusivelist.h" />
|
||||
<ClInclude Include="utllinkedlist.h" />
|
||||
<ClInclude Include="utlmap.h" />
|
||||
<ClInclude Include="utlmemory.h" />
|
||||
<ClInclude Include="utlobjectreference.h" />
|
||||
<ClInclude Include="utlpriorityqueue.h" />
|
||||
<ClInclude Include="utlqueue.h" />
|
||||
<ClInclude Include="utlrbtree.h" />
|
||||
<ClInclude Include="utlsoacontainer.h" />
|
||||
<ClInclude Include="utlstack.h" />
|
||||
<ClInclude Include="UtlStringMap.h" />
|
||||
<ClInclude Include="utltshash.h" />
|
||||
<ClInclude Include="UtlSortVector.h" />
|
||||
<ClInclude Include="utlstring.h" />
|
||||
<ClInclude Include="utlsymbol.h" />
|
||||
<ClInclude Include="utlsymbollarge.h" />
|
||||
<ClInclude Include="utlvector.h" />
|
||||
<ClInclude Include="valve_minmax_on.h" />
|
||||
<ClInclude Include="valve_off.h" />
|
||||
<ClInclude Include="valve_on.h" />
|
||||
<ClInclude Include="vcollide.h" />
|
||||
<ClInclude Include="vcrmode.h" />
|
||||
<ClInclude Include="vector.h" />
|
||||
<ClInclude Include="vector2d.h" />
|
||||
<ClInclude Include="vector4d.h" />
|
||||
<ClInclude Include="vertexcolor.h" />
|
||||
<ClInclude Include="VGUI.h" />
|
||||
<ClInclude Include="vgui_basepanel.h" />
|
||||
<ClInclude Include="viewrender.h" />
|
||||
<ClInclude Include="view_shared.h" />
|
||||
<ClInclude Include="vmatrix.h" />
|
||||
<ClInclude Include="VMT.hpp" />
|
||||
<ClInclude Include="vmt_smart_hook.hpp" />
|
||||
<ClInclude Include="volumeculler.h" />
|
||||
<ClInclude Include="vphysics_interface.h" />
|
||||
<ClInclude Include="vpkparser.h" />
|
||||
<ClInclude Include="vplane.h" />
|
||||
<ClInclude Include="vprof.h" />
|
||||
<ClInclude Include="vprof_sn.h" />
|
||||
<ClInclude Include="vprof_telemetry.h" />
|
||||
<ClInclude Include="vstdlib.h" />
|
||||
<ClInclude Include="vtf.h" />
|
||||
<ClInclude Include="wchartypes.h" />
|
||||
<ClInclude Include="weapon_parse.h" />
|
||||
<ClInclude Include="win32consoleio.h" />
|
||||
<ClInclude Include="xboxstubs.h" />
|
||||
<ClInclude Include="XorStr.hpp" />
|
||||
<ClInclude Include="zip_uncompressed.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ConVars.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="imgui\imgui.cpp" />
|
||||
<ClCompile Include="imgui\imgui_demo.cpp" />
|
||||
<ClCompile Include="imgui\imgui_draw.cpp" />
|
||||
<ClCompile Include="imgui\imgui_impl_dx9.cpp" />
|
||||
<ClCompile Include="imgui\imgui_impl_win32.cpp" />
|
||||
<ClCompile Include="imgui\imgui_tables.cpp" />
|
||||
<ClCompile Include="imgui\imgui_widgets.cpp" />
|
||||
<ClCompile Include="Interfaces.cpp" />
|
||||
<ClCompile Include="KeyValues.cpp" />
|
||||
<ClCompile Include="NetVarManager.cpp" />
|
||||
<ClCompile Include="netvars.cpp" />
|
||||
<ClCompile Include="Other.cpp" />
|
||||
<ClCompile Include="PatternScan.cpp" />
|
||||
<ClCompile Include="PlayerInventory.cpp" />
|
||||
<ClCompile Include="protobuffs.cpp" />
|
||||
<ClCompile Include="Skinchanger.cpp" />
|
||||
<ClCompile Include="textinputcombobox.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="SpyCustom.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Media Include="cod.wav">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
</Media>
|
||||
<Media Include="crit.wav">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
</Media>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <Windows.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class VMTHook
|
||||
{
|
||||
public:
|
||||
VMTHook(void* classptr)
|
||||
{
|
||||
this->class_pointer = reinterpret_cast<uintptr_t**>(classptr);
|
||||
|
||||
int table_size = 0;
|
||||
while (reinterpret_cast<uintptr_t*>(*this->class_pointer)[table_size])
|
||||
table_size++;
|
||||
|
||||
original_pointer = *this->class_pointer;
|
||||
|
||||
new_table_pointer = new uintptr_t[sizeof(uintptr_t) * table_size];
|
||||
memcpy(new_table_pointer, original_pointer, sizeof(uintptr_t) * table_size);
|
||||
}
|
||||
|
||||
~VMTHook()
|
||||
{
|
||||
RestoreOldTable();
|
||||
delete original_pointer;
|
||||
delete new_table_pointer;
|
||||
}
|
||||
|
||||
void SwapPointer(size_t index, void* new_function)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Swapping pointer 0x%X to 0x%X\n", new_table_pointer[index], reinterpret_cast<uintptr_t>(new_function));
|
||||
#endif
|
||||
new_table_pointer[index] = reinterpret_cast<uintptr_t>(new_function);
|
||||
#ifdef DEBUG
|
||||
printf("Swapped pointer!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void ApplyNewTable()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Applying new table... (0x%X to 0x%X)\n", reinterpret_cast<uintptr_t>(*class_pointer), reinterpret_cast<uintptr_t>(new_table_pointer));
|
||||
#endif
|
||||
*class_pointer = new_table_pointer;
|
||||
#ifdef DEBUG
|
||||
printf("New table applyed!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void RestoreOldTable()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Restoring old table... (0x%X to 0x%X)\n", reinterpret_cast<uintptr_t>(*class_pointer), reinterpret_cast<uintptr_t>(original_pointer));
|
||||
#endif
|
||||
*class_pointer = original_pointer;
|
||||
#ifdef DEBUG
|
||||
printf("Old table restored!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T GetOriginal(size_t index)
|
||||
{
|
||||
return reinterpret_cast<T>(original_pointer[index]);
|
||||
}
|
||||
|
||||
private:
|
||||
uintptr_t** class_pointer = nullptr;
|
||||
uintptr_t* original_pointer = nullptr;
|
||||
uintptr_t* new_table_pointer = nullptr;
|
||||
};
|
||||
@@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <cstdarg>
|
||||
|
||||
#define BEGIN_NAMESPACE( x ) namespace x {
|
||||
#define END_NAMESPACE }
|
||||
|
||||
BEGIN_NAMESPACE(XorCompileTime)
|
||||
|
||||
constexpr auto time = __TIME__;
|
||||
constexpr auto seed = static_cast<int>(time[7]) + static_cast<int>(time[6]) * 10 + static_cast<int>(time[4]) * 60 + static_cast<int>(time[3]) * 600 + static_cast<int>(time[1]) * 3600 + static_cast<int>(time[0]) * 36000;
|
||||
|
||||
template < int N >
|
||||
struct RandomGenerator {
|
||||
private:
|
||||
static constexpr unsigned a = 16807;
|
||||
static constexpr unsigned m = 2147483647;
|
||||
|
||||
static constexpr unsigned s = RandomGenerator< N - 1 >::value;
|
||||
static constexpr unsigned lo = a * (s & 0xFFFF);
|
||||
static constexpr unsigned hi = a * (s >> 16);
|
||||
static constexpr unsigned lo2 = lo + ((hi & 0x7FFF) << 16);
|
||||
static constexpr unsigned hi2 = hi >> 15;
|
||||
static constexpr unsigned lo3 = lo2 + hi;
|
||||
|
||||
public:
|
||||
static constexpr unsigned max = m;
|
||||
static constexpr unsigned value = lo3 > m ? lo3 - m : lo3;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RandomGenerator< 0 > {
|
||||
static constexpr unsigned value = seed;
|
||||
};
|
||||
|
||||
template < int N, int M >
|
||||
struct RandomInt {
|
||||
static constexpr auto value = RandomGenerator< N + 1 >::value % M;
|
||||
};
|
||||
|
||||
template < int N >
|
||||
struct RandomChar {
|
||||
static const char value = static_cast<char>(1 + RandomInt< N, 0x7F - 1 >::value);
|
||||
};
|
||||
|
||||
template < size_t N, int K >
|
||||
struct XorString {
|
||||
private:
|
||||
const char _key;
|
||||
std::array< char, N + 1 > _encrypted;
|
||||
|
||||
constexpr char enc(char c) const {
|
||||
return c ^ _key;
|
||||
}
|
||||
|
||||
char dec(char c) const {
|
||||
return c ^ _key;
|
||||
}
|
||||
|
||||
public:
|
||||
template < size_t... Is >
|
||||
constexpr __forceinline XorString(const char* str, std::index_sequence< Is... >) : _key(RandomChar< K >::value), _encrypted{ enc(str[Is])... } {
|
||||
}
|
||||
|
||||
__forceinline decltype(auto) decrypt(void) {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
_encrypted[i] = dec(_encrypted[i]);
|
||||
}
|
||||
_encrypted[N] = '\0';
|
||||
return _encrypted.data();
|
||||
}
|
||||
};
|
||||
|
||||
static auto w_printf = [](const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf_s(fmt, args);
|
||||
va_end(args);
|
||||
};
|
||||
|
||||
static auto w_printf_s = [](const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf_s(fmt, args);
|
||||
va_end(args);
|
||||
};
|
||||
|
||||
static auto w_sprintf = [](char* buf, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
};
|
||||
|
||||
static auto w_sprintf_s = [](char* buf, size_t buf_size, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf_s(buf, buf_size, fmt, args);
|
||||
va_end(args);
|
||||
};
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define XorStr( s ) ( XorCompileTime::XorString< sizeof( s ) - 1, __COUNTER__ >( s, std::make_index_sequence< sizeof( s ) - 1>() ).decrypt() )
|
||||
#else
|
||||
#define XorStr( s ) ( s )
|
||||
#endif
|
||||
|
||||
END_NAMESPACE
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include "sdk/icliententitylist.h"
|
||||
#include "sdk/CGameUI.h"
|
||||
#include "sdk/GameEventManager.h"
|
||||
#include "sdk/cdll_int.h"
|
||||
#include "sdk/ISurface.h"
|
||||
#include "sdk/IEngineVgui.h"
|
||||
#include "sdk/ivmodelinfo.h"
|
||||
#include "sdk/idatacache.h"
|
||||
#include "sdk/ILocalize.h"
|
||||
|
||||
#include "sdk/Panel.h"
|
||||
#include "sdk/IGameUI.h"
|
||||
|
||||
#include "sdk/dt_recv.h"
|
||||
#include "sdk/client_class.h"
|
||||
|
||||
#include "sdk/enginetrace.h"
|
||||
|
||||
#include "sdk/gameconsole.h"
|
||||
#include "sdk/ivrenderview.h"
|
||||
#include "sdk/ivdebugoverlay.h"
|
||||
#include "sdk/vphysics_interface.h"
|
||||
#include "sdk/iefx.h"
|
||||
|
||||
#include "sdk/iclient.h"
|
||||
#include "sdk/icliententity.h"
|
||||
#include "sdk/globalvars_base.h"
|
||||
#include "sdk/cmodel.h"
|
||||
#include "sdk/IInput.h"
|
||||
#include "sdk/IEffects.h"
|
||||
#include "sdk/iviewrender_beams.h"
|
||||
#include "sdk/sdk_hud_chat.h"
|
||||
#include "sdk/fx.h"
|
||||
#include "sdk/c_input.h"
|
||||
#include "EventListener.hpp"
|
||||
|
||||
#include "VMT.hpp"
|
||||
#include "PatternScan.hpp"
|
||||
|
||||
#include "PlayerInventory.hpp"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,561 @@
|
||||
#pragma once
|
||||
#ifndef _DETOURS_H_
|
||||
#define _DETOURS_H_
|
||||
|
||||
#pragma comment(lib, "detours")
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
DWORD Data1;
|
||||
WORD Data2;
|
||||
WORD Data3;
|
||||
BYTE Data4[ 8 ];
|
||||
} GUID;
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#ifndef _REFGUID_DEFINED
|
||||
#define _REFGUID_DEFINED
|
||||
#define REFGUID const GUID &
|
||||
#endif
|
||||
#else
|
||||
#ifndef _REFGUID_DEFINED
|
||||
#define _REFGUID_DEFINED
|
||||
#define REFGUID const GUID * const
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DETOUR_INSTRUCTION_TARGET_NONE ((PBYTE)0)
|
||||
#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PBYTE)~0ul)
|
||||
|
||||
#define DETOUR_TRAMPOLINE_SIZE 32
|
||||
#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444
|
||||
|
||||
#define DETOUR_TRAMPOLINE(trampoline,target) \
|
||||
static PVOID __fastcall _Detours_GetVA_##target(VOID) \
|
||||
{ \
|
||||
return ⌖ \
|
||||
} \
|
||||
\
|
||||
__declspec(naked) trampoline \
|
||||
{ \
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { call _Detours_GetVA_##target };\
|
||||
__asm { jmp eax };\
|
||||
__asm { ret };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
}
|
||||
|
||||
#define DETOUR_TRAMPOLINE_EMPTY(trampoline) \
|
||||
__declspec(naked) trampoline \
|
||||
{ \
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { xor eax, eax };\
|
||||
__asm { mov eax, [eax] };\
|
||||
__asm { ret };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
__asm { nop };\
|
||||
}
|
||||
|
||||
#pragma pack(push, 8)
|
||||
typedef struct _DETOUR_SECTION_HEADER
|
||||
{
|
||||
DWORD cbHeaderSize;
|
||||
DWORD nSignature;
|
||||
DWORD nDataOffset;
|
||||
DWORD cbDataSize;
|
||||
|
||||
DWORD nOriginalImportVirtualAddress;
|
||||
DWORD nOriginalImportSize;
|
||||
DWORD nOriginalBoundImportVirtualAddress;
|
||||
DWORD nOriginalBoundImportSize;
|
||||
|
||||
DWORD nOriginalIatVirtualAddress;
|
||||
DWORD nOriginalIatSize;
|
||||
DWORD nOriginalSizeOfImage;
|
||||
DWORD nReserve;
|
||||
} DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER;
|
||||
|
||||
typedef struct _DETOUR_SECTION_RECORD
|
||||
{
|
||||
DWORD cbBytes;
|
||||
DWORD nReserved;
|
||||
GUID guid;
|
||||
} DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \
|
||||
{ \
|
||||
sizeof(DETOUR_SECTION_HEADER),\
|
||||
DETOUR_SECTION_HEADER_SIGNATURE,\
|
||||
sizeof(DETOUR_SECTION_HEADER),\
|
||||
(cbSectionSize),\
|
||||
\
|
||||
0,\
|
||||
0,\
|
||||
0,\
|
||||
0,\
|
||||
\
|
||||
0,\
|
||||
0,\
|
||||
0,\
|
||||
0,\
|
||||
}
|
||||
|
||||
typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)(PVOID pContext,
|
||||
PCHAR pszFile,
|
||||
PCHAR *ppszOutFile);
|
||||
typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)(PVOID pContext,
|
||||
PCHAR pszOrigFile,
|
||||
PCHAR pszFile,
|
||||
PCHAR *ppszOutFile);
|
||||
typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)(PVOID pContext,
|
||||
DWORD nOrdinal,
|
||||
PCHAR pszOrigSymbol,
|
||||
PCHAR pszSymbol,
|
||||
PCHAR *ppszOutSymbol);
|
||||
typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FINAL_CALLBACK)(PVOID pContext);
|
||||
typedef BOOL (CALLBACK *PF_DETOUR_BINARY_EXPORT_CALLBACK)(PVOID pContext,
|
||||
DWORD nOrdinal,
|
||||
PCHAR pszName,
|
||||
PBYTE pbCode);
|
||||
|
||||
typedef VOID * PDETOUR_BINARY;
|
||||
typedef VOID * PDETOUR_LOADED_BINARY;
|
||||
|
||||
PBYTE WINAPI DetourFunction(PBYTE pbTargetFunction,
|
||||
PBYTE pbDetourFunction);
|
||||
|
||||
BOOL WINAPI DetourFunctionWithEmptyTrampoline(PBYTE pbTrampoline,
|
||||
PBYTE pbTarget,
|
||||
PBYTE pbDetour);
|
||||
|
||||
BOOL WINAPI DetourFunctionWithEmptyTrampolineEx(PBYTE pbTrampoline,
|
||||
PBYTE pbTarget,
|
||||
PBYTE pbDetour,
|
||||
PBYTE *ppbRealTrampoline,
|
||||
PBYTE *ppbRealTarget,
|
||||
PBYTE *ppbRealDetour);
|
||||
|
||||
BOOL WINAPI DetourFunctionWithTrampoline(PBYTE pbTrampoline,
|
||||
PBYTE pbDetour);
|
||||
|
||||
BOOL WINAPI DetourFunctionWithTrampolineEx(PBYTE pbTrampoline,
|
||||
PBYTE pbDetour,
|
||||
PBYTE *ppbRealTrampoline,
|
||||
PBYTE *ppbRealTarget);
|
||||
|
||||
BOOL WINAPI DetourRemove(PBYTE pbTrampoline, PBYTE pbDetour);
|
||||
|
||||
PBYTE WINAPI DetourFindFunction(PCHAR pszModule, PCHAR pszFunction);
|
||||
PBYTE WINAPI DetourGetFinalCode(PBYTE pbCode, BOOL fSkipJmp);
|
||||
|
||||
PBYTE WINAPI DetourCopyInstruction(PBYTE pbDst, PBYTE pbSrc, PBYTE *ppbTarget);
|
||||
PBYTE WINAPI DetourCopyInstructionEx(PBYTE pbDst,
|
||||
PBYTE pbSrc,
|
||||
PBYTE *ppbTarget,
|
||||
LONG *plExtra);
|
||||
|
||||
HMODULE WINAPI DetourEnumerateModules(HMODULE hModuleLast);
|
||||
PBYTE WINAPI DetourGetEntryPoint(HMODULE hModule);
|
||||
BOOL WINAPI DetourEnumerateExports(HMODULE hModule,
|
||||
PVOID pContext,
|
||||
PF_DETOUR_BINARY_EXPORT_CALLBACK pfExport);
|
||||
|
||||
PBYTE WINAPI DetourFindPayload(HMODULE hModule, REFGUID rguid, DWORD *pcbData);
|
||||
DWORD WINAPI DetourGetSizeOfPayloads(HMODULE hModule);
|
||||
|
||||
BOOL WINAPI DetourBinaryBindA(PCHAR pszFile, PCHAR pszDll, PCHAR pszPath);
|
||||
BOOL WINAPI DetourBinaryBindW(PWCHAR pwzFile, PWCHAR pwzDll, PWCHAR pwzPath);
|
||||
#ifdef UNICODE
|
||||
#define DetourBinaryBind DetourBinaryBindW
|
||||
#else
|
||||
#define DetourBinaryBind DetourBinaryBindA
|
||||
#endif
|
||||
|
||||
PDETOUR_BINARY WINAPI DetourBinaryOpen(HANDLE hFile);
|
||||
PBYTE WINAPI DetourBinaryEnumeratePayloads(PDETOUR_BINARY pBinary,
|
||||
GUID *pGuid,
|
||||
DWORD *pcbData,
|
||||
DWORD *pnIterator);
|
||||
PBYTE WINAPI DetourBinaryFindPayload(PDETOUR_BINARY pBinary,
|
||||
REFGUID rguid,
|
||||
DWORD *pcbData);
|
||||
PBYTE WINAPI DetourBinarySetPayload(PDETOUR_BINARY pBinary,
|
||||
REFGUID rguid,
|
||||
PBYTE pbData,
|
||||
DWORD cbData);
|
||||
BOOL WINAPI DetourBinaryDeletePayload(PDETOUR_BINARY pBinary, REFGUID rguid);
|
||||
BOOL WINAPI DetourBinaryPurgePayloads(PDETOUR_BINARY pBinary);
|
||||
BOOL WINAPI DetourBinaryResetImports(PDETOUR_BINARY pBinary);
|
||||
BOOL WINAPI DetourBinaryEditImports(PDETOUR_BINARY pBinary,
|
||||
PVOID pContext,
|
||||
PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway,
|
||||
PF_DETOUR_BINARY_FILE_CALLBACK pfFile,
|
||||
PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol,
|
||||
PF_DETOUR_BINARY_FINAL_CALLBACK pfFinal);
|
||||
BOOL WINAPI DetourBinaryWrite(PDETOUR_BINARY pBinary, HANDLE hFile);
|
||||
BOOL WINAPI DetourBinaryClose(PDETOUR_BINARY pBinary);
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
|
||||
DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelFilter);
|
||||
|
||||
typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)
|
||||
(LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOA lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation);
|
||||
|
||||
typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)
|
||||
(LPCWSTR lpApplicationName,
|
||||
LPWSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCWSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOW lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation);
|
||||
|
||||
BOOL WINAPI DetourCreateProcessWithDllA(LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOA lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation,
|
||||
LPCSTR lpDllName,
|
||||
PDETOUR_CREATE_PROCESS_ROUTINEA
|
||||
pfCreateProcessA);
|
||||
|
||||
BOOL WINAPI DetourCreateProcessWithDllW(LPCWSTR lpApplicationName,
|
||||
LPWSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCWSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOW lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation,
|
||||
LPCWSTR lpDllName,
|
||||
PDETOUR_CREATE_PROCESS_ROUTINEW
|
||||
pfCreateProcessW);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define DetourCreateProcessWithDll DetourCreateProcessWithDllW
|
||||
#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW
|
||||
#else
|
||||
#define DetourCreateProcessWithDll DetourCreateProcessWithDllA
|
||||
#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA
|
||||
#endif
|
||||
|
||||
BOOL WINAPI DetourContinueProcessWithDllA(HANDLE hProcess, LPCSTR lpDllName);
|
||||
BOOL WINAPI DetourContinueProcessWithDllW(HANDLE hProcess, LPCWSTR lpDllName);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define DetourContinueProcessWithDll DetourContinueProcessWithDllW
|
||||
#else
|
||||
#define DetourContinueProcessWithDll DetourContinueProcessWithDllA
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ContinueProcessWithDll DetourContinueProcessWithDll
|
||||
#define ContinueProcessWithDllA DetourContinueProcessWithDllA
|
||||
#define ContinueProcessWithDllW DetourContinueProcessWithDllW
|
||||
#define CreateProcessWithDll DetourCreateProcessWithDll
|
||||
#define CreateProcessWithDllA DetourCreateProcessWithDllA
|
||||
#define CreateProcessWithDllW DetourCreateProcessWithDllW
|
||||
#define DETOUR_TRAMPOLINE_WO_TARGET DETOUR_TRAMPOLINE_EMPTY
|
||||
#define DetourBinaryPurgePayload DetourBinaryPurgePayloads
|
||||
#define DetourEnumerateExportsForInstance DetourEnumerateExports
|
||||
#define DetourEnumerateInstances DetourEnumerateModules
|
||||
#define DetourFindEntryPointForInstance DetourGetEntryPoint
|
||||
#define DetourFindFinalCode DetourGetFinalCode
|
||||
#define DetourFindPayloadInBinary DetourFindPayload
|
||||
#define DetourGetSizeOfBinary DetourGetSizeOfPayloads
|
||||
#define DetourRemoveWithTrampoline DetourRemove
|
||||
#define PCREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINE
|
||||
#define PCREATE_PROCESS_ROUTINEA PDETOUR_CREATE_PROCESS_ROUTINEA
|
||||
#define PCREATE_PROCESS_ROUTINEW PDETOUR_CREATE_PROCESS_ROUTINEW
|
||||
#ifdef __cplusplus
|
||||
#ifdef DETOURS_INTERNAL
|
||||
|
||||
#ifdef IMAGEAPI
|
||||
typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion);
|
||||
|
||||
typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess,
|
||||
IN LPSTR UserSearchPath,
|
||||
IN BOOL fInvadeProcess);
|
||||
typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions);
|
||||
typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
|
||||
typedef BOOL (NTAPI *PF_SymLoadModule)(IN HANDLE hProcess,
|
||||
IN HANDLE hFile,
|
||||
IN PSTR ImageName,
|
||||
IN PSTR ModuleName,
|
||||
IN DWORD BaseOfDll,
|
||||
IN DWORD SizeOfDll);
|
||||
typedef BOOL (NTAPI *PF_SymGetModuleInfo)(IN HANDLE hProcess,
|
||||
IN DWORD dwAddr,
|
||||
OUT PIMAGEHLP_MODULE ModuleInfo);
|
||||
typedef BOOL (NTAPI *PF_SymGetSymFromName)(IN HANDLE hProcess,
|
||||
IN LPSTR Name,
|
||||
OUT PIMAGEHLP_SYMBOL Symbol);
|
||||
typedef BOOL (NTAPI *PF_BindImage)(IN LPSTR pszImageName,
|
||||
IN LPSTR pszDllPath,
|
||||
IN LPSTR pszSymbolPath);
|
||||
|
||||
typedef struct _DETOUR_SYM_INFO
|
||||
{
|
||||
HANDLE hProcess;
|
||||
HMODULE hImageHlp;
|
||||
PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx;
|
||||
PF_SymInitialize pfSymInitialize;
|
||||
PF_SymSetOptions pfSymSetOptions;
|
||||
PF_SymGetOptions pfSymGetOptions;
|
||||
PF_SymLoadModule pfSymLoadModule;
|
||||
PF_SymGetModuleInfo pfSymGetModuleInfo;
|
||||
PF_SymGetSymFromName pfSymGetSymFromName;
|
||||
PF_BindImage pfBindImage;
|
||||
} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO;
|
||||
|
||||
PDETOUR_SYM_INFO DetourLoadImageHlp(VOID);
|
||||
|
||||
#endif
|
||||
|
||||
class CDetourEnableWriteOnCodePage
|
||||
{
|
||||
public:
|
||||
CDetourEnableWriteOnCodePage(PBYTE pbCode, LONG cbCode = DETOUR_TRAMPOLINE_SIZE)
|
||||
{
|
||||
m_pbCode = pbCode;
|
||||
m_cbCode = cbCode;
|
||||
m_dwOldPerm = 0;
|
||||
m_hProcess = GetCurrentProcess();
|
||||
|
||||
if (m_pbCode && m_cbCode) {
|
||||
if (!FlushInstructionCache(m_hProcess, pbCode, cbCode)) {
|
||||
return;
|
||||
}
|
||||
if (!VirtualProtect(pbCode,
|
||||
cbCode,
|
||||
PAGE_EXECUTE_READWRITE,
|
||||
&m_dwOldPerm)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~CDetourEnableWriteOnCodePage()
|
||||
{
|
||||
if (m_dwOldPerm && m_pbCode && m_cbCode) {
|
||||
DWORD dwTemp = 0;
|
||||
if (!FlushInstructionCache(m_hProcess, m_pbCode, m_cbCode)) {
|
||||
return;
|
||||
}
|
||||
if (!VirtualProtect(m_pbCode, m_cbCode, m_dwOldPerm, &dwTemp)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL SetPermission(DWORD dwPerms)
|
||||
{
|
||||
if (m_dwOldPerm && m_pbCode && m_cbCode) {
|
||||
m_dwOldPerm = dwPerms;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL IsValid(VOID)
|
||||
{
|
||||
return m_pbCode && m_cbCode && m_dwOldPerm;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE m_hProcess;
|
||||
PBYTE m_pbCode;
|
||||
LONG m_cbCode;
|
||||
DWORD m_dwOldPerm;
|
||||
};
|
||||
|
||||
inline PBYTE DetourGenMovEax(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xB8;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenMovEbx(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xBB;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenMovEcx(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xB9;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenMovEdx(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xBA;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenMovEsi(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xBE;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenMovEdi(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xBF;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenMovEbp(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xBD;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenMovEsp(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0xBC;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenPush(PBYTE pbCode, UINT32 nValue)
|
||||
{
|
||||
*pbCode++ = 0x68;
|
||||
*((UINT32*&)pbCode)++ = nValue;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenPushad(PBYTE pbCode)
|
||||
{
|
||||
*pbCode++ = 0x60;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenPopad(PBYTE pbCode)
|
||||
{
|
||||
*pbCode++ = 0x61;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenJmp(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0)
|
||||
{
|
||||
if (pbJmpSrc == 0) {
|
||||
pbJmpSrc = pbCode;
|
||||
}
|
||||
*pbCode++ = 0xE9;
|
||||
*((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5);
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenCall(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0)
|
||||
{
|
||||
if (pbJmpSrc == 0) {
|
||||
pbJmpSrc = pbCode;
|
||||
}
|
||||
*pbCode++ = 0xE8;
|
||||
*((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5);
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenBreak(PBYTE pbCode)
|
||||
{
|
||||
*pbCode++ = 0xcc;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenRet(PBYTE pbCode)
|
||||
{
|
||||
*pbCode++ = 0xc3;
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
inline PBYTE DetourGenNop(PBYTE pbCode)
|
||||
{
|
||||
*pbCode++ = 0x90;
|
||||
return pbCode;
|
||||
}
|
||||
#endif DETOURS_INTERAL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,389 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include "Interfaces.hpp"
|
||||
#include "NetVarManager.hpp"
|
||||
#include "VMT.hpp"
|
||||
#include "EventListener.hpp"
|
||||
#include <string>
|
||||
#include "detours.h"
|
||||
#pragma comment(lib, "detours.lib")
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/imgui_impl_dx9.h"
|
||||
#include "imgui/imgui_impl_win32.h"
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
#pragma comment(lib, "d3d9.lib")
|
||||
#pragma comment(lib, "d3dx9.lib")
|
||||
#include "Other.hpp"
|
||||
#include "sdk/c_baseentity.h"
|
||||
#include "PatternScan.hpp"
|
||||
#include "SkinChanger.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "protobuffs.hpp"
|
||||
using namespace std;
|
||||
#include "proxies.hpp"
|
||||
#include "netchannel.hpp"
|
||||
#include "Hooks.hpp"
|
||||
#include "Menu.hpp"
|
||||
#include "SkinChanger.hpp"
|
||||
|
||||
|
||||
void OnLevelInit()
|
||||
{
|
||||
if (g_Options.skyboxactive)
|
||||
{
|
||||
iff.g_pCVar->FindVar("sv_skyname")->SetValue((char*)g_Options.skyboxtemp.value.get());
|
||||
iff.g_pCVar->FindVar("r_3dsky")->SetValue(false);
|
||||
}
|
||||
|
||||
if (g_Options.fogactive)
|
||||
{
|
||||
iff.g_pCVar->FindVar("fog_override")->SetValue(true);
|
||||
iff.g_pCVar->FindVar("fog_color")->SetValue(
|
||||
std::string("").
|
||||
append(std::to_string(g_Options.fogcolor.value->r * 255)).
|
||||
append(" ").
|
||||
append(std::to_string(g_Options.fogcolor.value->g * 255)).
|
||||
append(" ").
|
||||
append(std::to_string(g_Options.fogcolor.value->b * 255)).
|
||||
append(" ").c_str()
|
||||
);
|
||||
iff.g_pCVar->FindVar("fog_colorskybox")->SetValue(
|
||||
std::string("").
|
||||
append(std::to_string(g_Options.fogcolor.value->r * 255)).
|
||||
append(" ").
|
||||
append(std::to_string(g_Options.fogcolor.value->g * 255)).
|
||||
append(" ").
|
||||
append(std::to_string(g_Options.fogcolor.value->b * 255)).
|
||||
append(" ").c_str()
|
||||
);
|
||||
iff.g_pCVar->FindVar("fog_maxdensity")->SetValue(g_Options.fogdensity);
|
||||
iff.g_pCVar->FindVar("fog_maxdensityskybox")->SetValue(g_Options.fogdensity);
|
||||
iff.g_pCVar->FindVar("fog_start")->SetValue(g_Options.fogstart);
|
||||
iff.g_pCVar->FindVar("fog_startskybox")->SetValue(g_Options.fogstart);
|
||||
iff.g_pCVar->FindVar("fog_end")->SetValue(g_Options.fogend);
|
||||
iff.g_pCVar->FindVar("fog_endskybox")->SetValue(g_Options.fogend);
|
||||
}
|
||||
|
||||
iff.g_pCVar->FindVar("r_rainlength")->SetValue(*g_Options.rainlength);
|
||||
iff.g_pCVar->FindVar("r_rainspeed")->SetValue(*g_Options.rainspeed);
|
||||
iff.g_pCVar->FindVar("r_rainradius")->SetValue(*g_Options.rainradius);
|
||||
iff.g_pCVar->FindVar("cl_windspeed")->SetValue(*g_Options.windspeed);
|
||||
iff.g_pCVar->FindVar("r_rainwidth")->SetValue(*g_Options.rainwidth);
|
||||
iff.g_pCVar->FindVar("r_RainSideVel")->SetValue(*g_Options.rainsidevel);
|
||||
iff.g_pCVar->FindVar("r_rainalpha")->SetValue(*g_Options.rainalpha);
|
||||
|
||||
iff.g_pCVar->FindVar("mat_force_tonemap_scale")->SetValue(g_Options.tonemapscale);
|
||||
|
||||
colorWorld();
|
||||
|
||||
if (g_Options.prime)
|
||||
{
|
||||
DWORD old_protect;
|
||||
VirtualProtect(iff.prime, 5, PAGE_EXECUTE_READWRITE, &old_protect);
|
||||
char patch[] = { 0x31, 0xC0, 0xFE, 0xC0, 0xC3 };
|
||||
memcpy(iff.prime, patch, 5);
|
||||
VirtualProtect(iff.prime, 5, old_protect, nullptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void OnLoadCfg()
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if (g_Options.customtextures.value->arr[i].texturelink) {
|
||||
g_Options.customtextures.value->arr[i].texturelink = CreateMaterial(
|
||||
string(g_Options.customtextures.value->arr[i].Name),
|
||||
string(g_Options.customtextures.value->arr[i].keyvalue));
|
||||
opt.dmeitems.at(i) = g_Options.customtextures.value->arr[i].Preview;
|
||||
}
|
||||
}
|
||||
|
||||
OnLevelInit();
|
||||
|
||||
const auto& paintkitMap = itemSystem()->getItemSchema()->paintKits;
|
||||
|
||||
for (int n = 0; n < g_Options.weapons.value->weaponzcount; n++)
|
||||
{
|
||||
CPaintKit* pk = (CPaintKit*)paintkitMap.memory[g_Options.weapons.value->arr[n].skinidc].value;
|
||||
opt.sc_skins[g_Options.weapons.value->arr[n].skinidc].link = (DWORD)pk;
|
||||
pk->rarity = g_Options.weapons.value->arr[n].rarity;
|
||||
opt.sc_skins[g_Options.weapons.value->arr[n].skinidc].rarity = g_Options.weapons.value->arr[n].rarity;
|
||||
pk->pearlescent = g_Options.weapons.value->arr[n].pearl;
|
||||
opt.sc_skins[g_Options.weapons.value->arr[n].skinidc].pearl = g_Options.weapons.value->arr[n].pearl;
|
||||
pk->color1 = g_Options.weapons.value->arr[n].color1;
|
||||
opt.sc_skins[g_Options.weapons.value->arr[n].skinidc].color1 = g_Options.weapons.value->arr[n].color1;
|
||||
pk->color2 = g_Options.weapons.value->arr[n].color2;
|
||||
opt.sc_skins[g_Options.weapons.value->arr[n].skinidc].color2 = g_Options.weapons.value->arr[n].color2;
|
||||
pk->color3 = g_Options.weapons.value->arr[n].color3;
|
||||
opt.sc_skins[g_Options.weapons.value->arr[n].skinidc].color3 = g_Options.weapons.value->arr[n].color3;
|
||||
pk->color4 = g_Options.weapons.value->arr[n].color4;
|
||||
opt.sc_skins[g_Options.weapons.value->arr[n].skinidc].color4 = g_Options.weapons.value->arr[n].color4;
|
||||
|
||||
}
|
||||
|
||||
iff.g_pClientState->ForceFullUpdate();
|
||||
opt.needupdate = 1;
|
||||
ProtoFeatures.SendClientHello();
|
||||
ProtoFeatures.SendMatchmakingClient2GCHello();
|
||||
|
||||
opt.loading = 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI HackThread(HMODULE hModule)
|
||||
{
|
||||
|
||||
while (!GetModuleHandleA("serverbrowser.dll"))
|
||||
Sleep(1000);
|
||||
|
||||
#ifdef DEBUG
|
||||
AllocConsole();
|
||||
FILE* f;
|
||||
freopen_s(&f, "CONOUT$", "w", stdout);
|
||||
printf("Cheat launched\n");
|
||||
#endif
|
||||
|
||||
iff.Init();
|
||||
|
||||
opt.hModuleGlobal = hModule;
|
||||
|
||||
NetvarSys::Get().Initialize();
|
||||
|
||||
DMEHook = new VMTHook(iff.g_pMdlRender);
|
||||
DMEHook->SwapPointer(21, reinterpret_cast<void*>(DrawModelExecute));
|
||||
DMEHook->ApplyNewTable();
|
||||
|
||||
D3DHook = new VMTHook(iff.g_pD3DDevice9);
|
||||
D3DHook->SwapPointer(42, reinterpret_cast<void*>(hkEndScene));
|
||||
D3DHook->ApplyNewTable();
|
||||
|
||||
GameEventManagerHook = new VMTHook(iff.g_pGameEvents);
|
||||
GameEventManagerHook->SwapPointer(9, reinterpret_cast<void*>(hkFireEventClientSide));
|
||||
GameEventManagerHook->ApplyNewTable();
|
||||
|
||||
ProtoHook = new VMTHook(iff.g_SteamGameCoordinator);
|
||||
ProtoHook->SwapPointer(0, reinterpret_cast<void*>(hkGCSendMessage));
|
||||
ProtoHook->SwapPointer(2, reinterpret_cast<void*>(hkGCRetrieveMessage));
|
||||
ProtoHook->ApplyNewTable();
|
||||
|
||||
CacheHook = new VMTHook(iff.g_pMdlCache);
|
||||
CacheHook->SwapPointer(10, reinterpret_cast<void*>(hkFindMDL));
|
||||
CacheHook->ApplyNewTable();
|
||||
|
||||
SoundHook = new VMTHook(iff.g_pEngineSound);
|
||||
SoundHook->SwapPointer(5, reinterpret_cast<void*>(hkEmitSound1));
|
||||
SoundHook->ApplyNewTable();
|
||||
|
||||
|
||||
VGUISurfHook = new VMTHook(iff.g_pVGuiSurface);
|
||||
VGUISurfHook->SwapPointer(67, reinterpret_cast<void*>(hkLockCursor));
|
||||
VGUISurfHook->ApplyNewTable();
|
||||
|
||||
ClientModeHook = new VMTHook(iff.g_ClientMode);
|
||||
ClientModeHook->SwapPointer(44, reinterpret_cast<void*>(hkdoPostScreenEffects));
|
||||
ClientModeHook->ApplyNewTable();
|
||||
|
||||
FileSystemHook = new VMTHook(iff.g_pFullFileSystem);
|
||||
FileSystemHook->SwapPointer(101, reinterpret_cast<void*>(hkGetUnverifiedFileHashes));
|
||||
FileSystemHook->ApplyNewTable();
|
||||
|
||||
InitSkinChanger();
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
ClientHook = new VMTHook(iff.g_pClient);
|
||||
ClientHook->SwapPointer(37, reinterpret_cast<void*>(hkFrameStageNotify));
|
||||
ClientHook->ApplyNewTable();
|
||||
|
||||
iff.g_pGameConsole->Clear();
|
||||
|
||||
EventListener* eventListener = new EventListener();
|
||||
|
||||
Color color = { 255,255,0,255 };
|
||||
iff.g_pCVar->ConsoleColorPrintf(color, "zdarova\n");
|
||||
|
||||
ConVar* sv_skyname = iff.g_pCVar->FindVar("sv_skyname");
|
||||
|
||||
|
||||
int proxyindex = 0;
|
||||
for (ClientClass* pClass = iff.g_pClient->GetAllClasses(); pClass; pClass = pClass->m_pNext) {
|
||||
if (!strcmp(pClass->m_pNetworkName, "CBaseViewModel")) {
|
||||
RecvTable* pClassTable = pClass->m_pRecvTable;
|
||||
for (int nIndex = 0; nIndex < pClassTable->m_nProps; nIndex++) {
|
||||
RecvProp* pProp = &pClassTable->m_pProps[nIndex];
|
||||
if (!pProp || strcmp(pProp->m_pVarName, "m_nSequence"))
|
||||
continue;
|
||||
proxyindex = nIndex;
|
||||
fnSequenceProxyFn = pProp->m_ProxyFn;
|
||||
pProp->m_ProxyFn = (RecvVarProxyFn)SetViewModelSequence;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ifstream loadcfg("seaside_autoload");
|
||||
if (loadcfg.is_open())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("autoload found\n");
|
||||
#endif
|
||||
opt.autoload = true;
|
||||
Sleep(1000);
|
||||
Config::Get().Load();
|
||||
loadcfg.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("autoload NOT found, creatin mat\n");
|
||||
#endif
|
||||
opt.autoload = false;
|
||||
|
||||
g_Options.customtextures.value->arr[0].texturelink = CreateMaterial(
|
||||
string(g_Options.customtextures.value->arr[0].Name),
|
||||
string(g_Options.customtextures.value->arr[0].keyvalue));
|
||||
}
|
||||
|
||||
|
||||
while (!opt.unhook)
|
||||
{
|
||||
|
||||
if (GetAsyncKeyState(VK_INSERT) & 1)
|
||||
{
|
||||
opt.show = !opt.show;
|
||||
#ifdef DEBUG
|
||||
cout << "Show " << opt.show << endl;
|
||||
#endif
|
||||
if (!opt.show)
|
||||
iff.g_pInputSystem->EnableInput(1);
|
||||
else
|
||||
iff.g_pInputSystem->EnableInput(0);
|
||||
}
|
||||
|
||||
if (!opt.netchannedlhooked && iff.g_pEngineClient->IsConnected())
|
||||
HookNetchannel();
|
||||
|
||||
if (iff.g_pEngineClient->IsInGame()) {
|
||||
if (!*g_Options.dme_gettextures)
|
||||
{
|
||||
IMaterial* mats[1];
|
||||
for (int i = 5; i < g_Options.materials.value->itemcount; i++) {
|
||||
int mdlindex = iff.g_pMdlInfo->GetModelIndex(g_Options.models.value->arr[i - 2].vmodel_orig);
|
||||
if (mdlindex != -1) {
|
||||
model_t* pModel = (model_t*)iff.g_pMdlInfo->GetModel(mdlindex);
|
||||
iff.g_pMdlInfo->GetModelMaterials(pModel, 1, mats);
|
||||
const char* matname = mats[0]->GetName();
|
||||
if (g_Options.materials.value->arr[i].texture[0] == 0x0)
|
||||
strcpy(g_Options.materials.value->arr[i].texture, matname);
|
||||
if (g_Options.materials.value->arr[i].texture_temp[0] == 0x0)
|
||||
strcpy(g_Options.materials.value->arr[i].texture_temp, matname);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("Model materials dumped\n");
|
||||
#endif
|
||||
*g_Options.dme_gettextures = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
opt.disconnected = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Sleep(20);
|
||||
}
|
||||
opt.show = false;
|
||||
|
||||
|
||||
for (ClientClass* pClass = iff.g_pClient->GetAllClasses(); pClass; pClass = pClass->m_pNext) {
|
||||
if (!strcmp(pClass->m_pNetworkName, "CBaseViewModel")) {
|
||||
RecvTable* pClassTable = pClass->m_pRecvTable;
|
||||
RecvProp* pProp = &pClassTable->m_pProps[proxyindex];
|
||||
pProp->m_ProxyFn = fnSequenceProxyFn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (iff.g_pEngineClient->IsConnected()) {
|
||||
iff.g_pClientState->ForceFullUpdate();
|
||||
}
|
||||
|
||||
iff.g_pInputSystem->EnableInput(1);
|
||||
|
||||
iff.g_pCVar->FindVar("r_3dsky")->SetValue(true);
|
||||
|
||||
sv_skyname->m_nFlags &= FCVAR_CHEAT;
|
||||
sv_skyname->SetValue("sky_urb01");
|
||||
|
||||
iff.g_pCVar->FindVar("fog_override")->SetValue(0);
|
||||
iff.g_pCVar->FindVar("mat_force_tonemap_scale")->SetValue(0.0f);
|
||||
|
||||
DMEHook->RestoreOldTable();
|
||||
D3DHook->RestoreOldTable();
|
||||
ClientHook->RestoreOldTable();
|
||||
GameEventManagerHook->RestoreOldTable();
|
||||
ProtoHook->RestoreOldTable();
|
||||
CacheHook->RestoreOldTable();
|
||||
SoundHook->RestoreOldTable();
|
||||
VGUISurfHook->RestoreOldTable();
|
||||
ClientModeHook->RestoreOldTable();
|
||||
FileSystemHook->RestoreOldTable();
|
||||
|
||||
if (opt.netchannedlhooked)
|
||||
DetourRemove(reinterpret_cast<BYTE*>(oShutdown), reinterpret_cast<BYTE*>(hkShutdown));
|
||||
|
||||
|
||||
ImGui_ImplDX9_Shutdown();
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
SetWindowLongPtr(window, GWL_WNDPROC, (LONG_PTR)oWndProc);
|
||||
|
||||
delete eventListener;
|
||||
|
||||
ProtoFeatures.SendClientHello();
|
||||
ProtoFeatures.SendMatchmakingClient2GCHello();
|
||||
ProtoFeatures.SendClientGcRankUpdate();
|
||||
|
||||
if (g_Options.prime)
|
||||
{
|
||||
DWORD old_protect;
|
||||
VirtualProtect(iff.prime, 5, PAGE_EXECUTE_READWRITE, &old_protect);
|
||||
memcpy(iff.prime, iff.oldprime, 5);
|
||||
VirtualProtect(iff.prime, 5, old_protect, nullptr);
|
||||
}
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (f) fclose(f);
|
||||
FreeConsole();
|
||||
#endif
|
||||
FreeLibraryAndExitThread(hModule, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
HANDLE hdl = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)HackThread, hModule, 0, nullptr);
|
||||
if (hdl) CloseHandle(hdl);
|
||||
break;
|
||||
}
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
||||
// #define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
||||
// This adds a small runtime cost which is why it is not enabled by default.
|
||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,232 @@
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_dx9.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
|
||||
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
|
||||
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
|
||||
static LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;
|
||||
static LPDIRECT3DTEXTURE9 g_FontTexture = NULL;
|
||||
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
|
||||
|
||||
struct CUSTOMVERTEX
|
||||
{
|
||||
float pos[3];
|
||||
D3DCOLOR col;
|
||||
float uv[2];
|
||||
};
|
||||
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||
|
||||
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||
{
|
||||
D3DVIEWPORT9 vp;
|
||||
vp.X = vp.Y = 0;
|
||||
vp.Width = (DWORD)draw_data->DisplaySize.x;
|
||||
vp.Height = (DWORD)draw_data->DisplaySize.y;
|
||||
vp.MinZ = 0.0f;
|
||||
vp.MaxZ = 1.0f;
|
||||
g_pd3dDevice->SetViewport(&vp);
|
||||
|
||||
g_pd3dDevice->SetPixelShader(NULL);
|
||||
g_pd3dDevice->SetVertexShader(NULL);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
{
|
||||
float L = draw_data->DisplayPos.x + 0.5f;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f;
|
||||
float T = draw_data->DisplayPos.y + 0.5f;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f;
|
||||
D3DMATRIX mat_identity = { { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||
D3DMATRIX mat_projection =
|
||||
{ { {
|
||||
2.0f/(R-L), 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 2.0f/(T-B), 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.5f, 0.0f,
|
||||
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
||||
} } };
|
||||
g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||
g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
|
||||
g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
if (g_pd3dDevice->CreateVertexBuffer(g_VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
|
||||
return;
|
||||
}
|
||||
if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
|
||||
g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
if (g_pd3dDevice->CreateIndexBuffer(g_IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &g_pIB, NULL) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
IDirect3DStateBlock9* d3d9_state_block = NULL;
|
||||
if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
|
||||
return;
|
||||
|
||||
D3DMATRIX last_world, last_view, last_projection;
|
||||
g_pd3dDevice->GetTransform(D3DTS_WORLD, &last_world);
|
||||
g_pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
|
||||
g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
|
||||
CUSTOMVERTEX* vtx_dst;
|
||||
ImDrawIdx* idx_dst;
|
||||
if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
||||
return;
|
||||
if (g_pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
|
||||
return;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
vtx_dst->pos[0] = vtx_src->pos.x;
|
||||
vtx_dst->pos[1] = vtx_src->pos.y;
|
||||
vtx_dst->pos[2] = 0.0f;
|
||||
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000) >> 16) | ((vtx_src->col & 0xFF) << 16);
|
||||
vtx_dst->uv[0] = vtx_src->uv.x;
|
||||
vtx_dst->uv[1] = vtx_src->uv.y;
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
g_pVB->Unlock();
|
||||
g_pIB->Unlock();
|
||||
g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
|
||||
g_pd3dDevice->SetIndices(g_pIB);
|
||||
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != NULL)
|
||||
{
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
const RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
|
||||
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->TextureId;
|
||||
g_pd3dDevice->SetTexture(0, texture);
|
||||
g_pd3dDevice->SetScissorRect(&r);
|
||||
g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
g_pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
|
||||
g_pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
|
||||
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
|
||||
d3d9_state_block->Apply();
|
||||
d3d9_state_block->Release();
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendRendererName = "imgui_impl_dx9";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
|
||||
g_pd3dDevice = device;
|
||||
g_pd3dDevice->AddRef();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels;
|
||||
int width, height, bytes_per_pixel;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
|
||||
|
||||
g_FontTexture = NULL;
|
||||
if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
|
||||
return false;
|
||||
D3DLOCKED_RECT tex_locked_rect;
|
||||
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
|
||||
return false;
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((unsigned char*)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, pixels + (width * bytes_per_pixel) * y, (width * bytes_per_pixel));
|
||||
g_FontTexture->UnlockRect(0);
|
||||
|
||||
io.Fonts->SetTexID((ImTextureID)g_FontTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX9_CreateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
return false;
|
||||
if (!ImGui_ImplDX9_CreateFontsTexture())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_InvalidateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
return;
|
||||
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
|
||||
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
|
||||
if (g_FontTexture) { g_FontTexture->Release(); g_FontTexture = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); }
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_NewFrame()
|
||||
{
|
||||
if (!g_FontTexture)
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "imgui.h"
|
||||
|
||||
struct IDirect3DDevice9;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
@@ -0,0 +1,396 @@
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_win32.h"
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
#include <XInput.h>
|
||||
typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||
typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
#endif
|
||||
|
||||
static HWND g_hWnd = NULL;
|
||||
static INT64 g_Time = 0;
|
||||
static INT64 g_TicksPerSecond = 0;
|
||||
static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
static bool g_HasGamepad = false;
|
||||
static bool g_WantUpdateHasGamepad = true;
|
||||
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
static HMODULE g_XInputDLL = NULL;
|
||||
static PFN_XInputGetCapabilities g_XInputGetCapabilities = NULL;
|
||||
static PFN_XInputGetState g_XInputGetState = NULL;
|
||||
#endif
|
||||
|
||||
bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
{
|
||||
if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&g_TicksPerSecond))
|
||||
return false;
|
||||
if (!::QueryPerformanceCounter((LARGE_INTEGER*)&g_Time))
|
||||
return false;
|
||||
|
||||
g_hWnd = (HWND)hwnd;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;
|
||||
io.BackendPlatformName = "imgui_impl_win32";
|
||||
io.ImeWindowHandle = hwnd;
|
||||
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
|
||||
io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = VK_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Space] = VK_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
const char* xinput_dll_names[] =
|
||||
{
|
||||
"xinput1_4.dll",
|
||||
"xinput1_3.dll",
|
||||
"xinput9_1_0.dll",
|
||||
"xinput1_2.dll",
|
||||
"xinput1_1.dll"
|
||||
};
|
||||
for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++)
|
||||
if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n]))
|
||||
{
|
||||
g_XInputDLL = dll;
|
||||
g_XInputGetCapabilities = (PFN_XInputGetCapabilities)::GetProcAddress(dll, "XInputGetCapabilities");
|
||||
g_XInputGetState = (PFN_XInputGetState)::GetProcAddress(dll, "XInputGetState");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_Shutdown()
|
||||
{
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
if (g_XInputDLL)
|
||||
::FreeLibrary(g_XInputDLL);
|
||||
g_XInputDLL = NULL;
|
||||
g_XInputGetCapabilities = NULL;
|
||||
g_XInputGetState = NULL;
|
||||
#endif
|
||||
|
||||
g_hWnd = NULL;
|
||||
g_Time = 0;
|
||||
g_TicksPerSecond = 0;
|
||||
g_LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
g_HasGamepad = false;
|
||||
g_WantUpdateHasGamepad = true;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||
return false;
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||
{
|
||||
::SetCursor(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPTSTR win32_cursor = IDC_ARROW;
|
||||
switch (imgui_cursor)
|
||||
{
|
||||
case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break;
|
||||
case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break;
|
||||
case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break;
|
||||
case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break;
|
||||
case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break;
|
||||
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
|
||||
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
|
||||
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
||||
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
||||
}
|
||||
::SetCursor(::LoadCursor(NULL, win32_cursor));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateMousePos()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||
if (::ClientToScreen(g_hWnd, &pos))
|
||||
::SetCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
POINT pos;
|
||||
if (HWND active_window = ::GetForegroundWindow())
|
||||
if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd))
|
||||
if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos))
|
||||
io.MousePos = ImVec2((float)pos.x, (float)pos.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateGamepads()
|
||||
{
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
if (g_WantUpdateHasGamepad)
|
||||
{
|
||||
XINPUT_CAPABILITIES caps;
|
||||
g_HasGamepad = g_XInputGetCapabilities ? (g_XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
|
||||
g_WantUpdateHasGamepad = false;
|
||||
}
|
||||
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
XINPUT_STATE xinput_state;
|
||||
if (g_HasGamepad && g_XInputGetState && g_XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
|
||||
{
|
||||
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
|
||||
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
|
||||
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A);
|
||||
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B);
|
||||
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X);
|
||||
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y);
|
||||
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT);
|
||||
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT);
|
||||
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP);
|
||||
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN);
|
||||
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER);
|
||||
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER);
|
||||
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER);
|
||||
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer backend. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
|
||||
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
::GetClientRect(g_hWnd, &rect);
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
||||
|
||||
INT64 current_time = 0;
|
||||
::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time);
|
||||
io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond;
|
||||
g_Time = current_time;
|
||||
|
||||
io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
|
||||
io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
|
||||
io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
|
||||
io.KeySuper = false;
|
||||
ImGui_ImplWin32_UpdateMousePos();
|
||||
|
||||
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||
if (g_LastMouseCursor != mouse_cursor)
|
||||
{
|
||||
g_LastMouseCursor = mouse_cursor;
|
||||
ImGui_ImplWin32_UpdateMouseCursor();
|
||||
}
|
||||
|
||||
ImGui_ImplWin32_UpdateGamepads();
|
||||
}
|
||||
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
#endif
|
||||
#ifndef DBT_DEVNODES_CHANGED
|
||||
#define DBT_DEVNODES_CHANGED 0x0007
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (ImGui::GetCurrentContext() == NULL)
|
||||
return 0;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||
{
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
|
||||
::SetCapture(hwnd);
|
||||
io.MouseDown[button] = true;
|
||||
return 0;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||
if (msg == WM_MBUTTONUP) { button = 2; }
|
||||
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||
io.MouseDown[button] = false;
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
|
||||
::ReleaseCapture();
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
||||
return 0;
|
||||
case WM_MOUSEHWHEEL:
|
||||
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
||||
return 0;
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
if (wParam < 256)
|
||||
io.KeysDown[wParam] = 1;
|
||||
return 0;
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
if (wParam < 256)
|
||||
io.KeysDown[wParam] = 0;
|
||||
return 0;
|
||||
case WM_CHAR:
|
||||
if (wParam > 0 && wParam < 0x10000)
|
||||
io.AddInputCharacterUTF16((unsigned short)wParam);
|
||||
return 0;
|
||||
case WM_SETCURSOR:
|
||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
||||
return 1;
|
||||
return 0;
|
||||
case WM_DEVICECHANGE:
|
||||
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
|
||||
g_WantUpdateHasGamepad = true;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(_versionhelpers_H_INCLUDED_) && !defined(_INC_VERSIONHELPERS)
|
||||
static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp)
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, { 0 }, sp, 0, 0, 0, 0 };
|
||||
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
||||
ULONGLONG cond = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
cond = ::VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cond = ::VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
return ::VerifyVersionInfoW(&osvi, mask, cond);
|
||||
}
|
||||
#define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0)
|
||||
#endif
|
||||
|
||||
#ifndef DPI_ENUMS_DECLARED
|
||||
typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;
|
||||
typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE;
|
||||
#endif
|
||||
#ifndef _DPI_AWARENESS_CONTEXTS_
|
||||
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3
|
||||
#endif
|
||||
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4
|
||||
#endif
|
||||
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
|
||||
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
|
||||
|
||||
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||
{
|
||||
{
|
||||
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll");
|
||||
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
|
||||
{
|
||||
SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (IsWindows8Point1OrGreater())
|
||||
{
|
||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll");
|
||||
if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
|
||||
{
|
||||
SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if _WIN32_WINNT >= 0x0600
|
||||
::SetProcessDPIAware();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && !defined(NOGDI)
|
||||
#pragma comment(lib, "gdi32")
|
||||
#endif
|
||||
|
||||
float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
||||
{
|
||||
UINT xdpi = 96, ydpi = 96;
|
||||
static BOOL bIsWindows8Point1OrGreater = IsWindows8Point1OrGreater();
|
||||
if (bIsWindows8Point1OrGreater)
|
||||
{
|
||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll");
|
||||
if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor"))
|
||||
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||
}
|
||||
#ifndef NOGDI
|
||||
else
|
||||
{
|
||||
const HDC dc = ::GetDC(NULL);
|
||||
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
|
||||
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
|
||||
::ReleaseDC(NULL, dc);
|
||||
}
|
||||
#endif
|
||||
IM_ASSERT(xdpi == ydpi);
|
||||
return xdpi / 96.0f;
|
||||
}
|
||||
|
||||
float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
|
||||
{
|
||||
HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "imgui.h"
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
|
||||
|
||||
#if 0
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
|
||||
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd);
|
||||
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor);
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,403 @@
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
struct stbrp_rect
|
||||
{
|
||||
int id;
|
||||
|
||||
stbrp_coord w, h;
|
||||
|
||||
stbrp_coord x, y;
|
||||
int was_packed;
|
||||
|
||||
};
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
context->align = 1;
|
||||
else {
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0);
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) {
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
if (y + height <= c->height) {
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
}
|
||||
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0;
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,968 @@
|
||||
|
||||
#ifndef INCLUDE_STB_TEXTEDIT_H
|
||||
#define INCLUDE_STB_TEXTEDIT_H
|
||||
|
||||
#ifndef STB_TEXTEDIT_UNDOSTATECOUNT
|
||||
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_UNDOCHARCOUNT
|
||||
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_CHARTYPE
|
||||
#define STB_TEXTEDIT_CHARTYPE int
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_POSITIONTYPE
|
||||
#define STB_TEXTEDIT_POSITIONTYPE int
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
STB_TEXTEDIT_POSITIONTYPE where;
|
||||
STB_TEXTEDIT_POSITIONTYPE insert_length;
|
||||
STB_TEXTEDIT_POSITIONTYPE delete_length;
|
||||
int char_storage;
|
||||
} StbUndoRecord;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
|
||||
STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
|
||||
short undo_point, redo_point;
|
||||
int undo_char_point, redo_char_point;
|
||||
} StbUndoState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int cursor;
|
||||
int select_start;
|
||||
int select_end;
|
||||
unsigned char insert_mode;
|
||||
int row_count_per_page;
|
||||
unsigned char cursor_at_end_of_line;
|
||||
unsigned char initialized;
|
||||
unsigned char has_preferred_x;
|
||||
unsigned char single_line;
|
||||
unsigned char padding1, padding2, padding3;
|
||||
float preferred_x;
|
||||
StbUndoState undostate;
|
||||
} STB_TexteditState;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x0,x1;
|
||||
float baseline_y_delta;
|
||||
float ymin,ymax;
|
||||
int num_chars;
|
||||
} StbTexteditRow;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef STB_TEXTEDIT_IMPLEMENTATION
|
||||
|
||||
#ifndef STB_TEXTEDIT_memmove
|
||||
#include <string.h>
|
||||
#define STB_TEXTEDIT_memmove memmove
|
||||
#endif
|
||||
|
||||
|
||||
static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
||||
{
|
||||
StbTexteditRow r;
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
float base_y = 0, prev_x;
|
||||
int i=0, k;
|
||||
|
||||
r.x0 = r.x1 = 0;
|
||||
r.ymin = r.ymax = 0;
|
||||
r.num_chars = 0;
|
||||
|
||||
while (i < n) {
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
if (r.num_chars <= 0)
|
||||
return n;
|
||||
|
||||
if (i==0 && y < base_y + r.ymin)
|
||||
return 0;
|
||||
|
||||
if (y < base_y + r.ymax)
|
||||
break;
|
||||
|
||||
i += r.num_chars;
|
||||
base_y += r.baseline_y_delta;
|
||||
}
|
||||
|
||||
if (i >= n)
|
||||
return n;
|
||||
|
||||
if (x < r.x0)
|
||||
return i;
|
||||
|
||||
if (x < r.x1) {
|
||||
prev_x = r.x0;
|
||||
for (k=0; k < r.num_chars; ++k) {
|
||||
float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
|
||||
if (x < prev_x+w) {
|
||||
if (x < prev_x+w/2)
|
||||
return k+i;
|
||||
else
|
||||
return k+i+1;
|
||||
}
|
||||
prev_x += w;
|
||||
}
|
||||
}
|
||||
|
||||
if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE)
|
||||
return i+r.num_chars-1;
|
||||
else
|
||||
return i+r.num_chars;
|
||||
}
|
||||
|
||||
static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
{
|
||||
if( state->single_line )
|
||||
{
|
||||
StbTexteditRow r;
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
y = r.ymin;
|
||||
}
|
||||
|
||||
state->cursor = stb_text_locate_coord(str, x, y);
|
||||
state->select_start = state->cursor;
|
||||
state->select_end = state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
|
||||
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
{
|
||||
int p = 0;
|
||||
|
||||
if( state->single_line )
|
||||
{
|
||||
StbTexteditRow r;
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
y = r.ymin;
|
||||
}
|
||||
|
||||
if (state->select_start == state->select_end)
|
||||
state->select_start = state->cursor;
|
||||
|
||||
p = stb_text_locate_coord(str, x, y);
|
||||
state->cursor = state->select_end = p;
|
||||
}
|
||||
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x,y;
|
||||
float height;
|
||||
int first_char, length;
|
||||
int prev_first;
|
||||
} StbFindState;
|
||||
|
||||
static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
|
||||
{
|
||||
StbTexteditRow r;
|
||||
int prev_start = 0;
|
||||
int z = STB_TEXTEDIT_STRINGLEN(str);
|
||||
int i=0, first;
|
||||
|
||||
if (n == z) {
|
||||
if (single_line) {
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
find->y = 0;
|
||||
find->first_char = 0;
|
||||
find->length = z;
|
||||
find->height = r.ymax - r.ymin;
|
||||
find->x = r.x1;
|
||||
} else {
|
||||
find->y = 0;
|
||||
find->x = 0;
|
||||
find->height = 1;
|
||||
while (i < z) {
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
prev_start = i;
|
||||
i += r.num_chars;
|
||||
}
|
||||
find->first_char = i;
|
||||
find->length = 0;
|
||||
find->prev_first = prev_start;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
find->y = 0;
|
||||
|
||||
for(;;) {
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
if (n < i + r.num_chars)
|
||||
break;
|
||||
prev_start = i;
|
||||
i += r.num_chars;
|
||||
find->y += r.baseline_y_delta;
|
||||
}
|
||||
|
||||
find->first_char = first = i;
|
||||
find->length = r.num_chars;
|
||||
find->height = r.ymax - r.ymin;
|
||||
find->prev_first = prev_start;
|
||||
|
||||
find->x = r.x0;
|
||||
for (i=0; first+i < n; ++i)
|
||||
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
|
||||
}
|
||||
|
||||
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
||||
|
||||
static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
if (state->select_start > n) state->select_start = n;
|
||||
if (state->select_end > n) state->select_end = n;
|
||||
if (state->select_start == state->select_end)
|
||||
state->cursor = state->select_start;
|
||||
}
|
||||
if (state->cursor > n) state->cursor = n;
|
||||
}
|
||||
|
||||
static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
||||
{
|
||||
stb_text_makeundo_delete(str, state, where, len);
|
||||
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
|
||||
static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
stb_textedit_clamp(str, state);
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
if (state->select_start < state->select_end) {
|
||||
stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start);
|
||||
state->select_end = state->cursor = state->select_start;
|
||||
} else {
|
||||
stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end);
|
||||
state->select_start = state->cursor = state->select_end;
|
||||
}
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_textedit_sortselection(STB_TexteditState *state)
|
||||
{
|
||||
if (state->select_end < state->select_start) {
|
||||
int temp = state->select_end;
|
||||
state->select_end = state->select_start;
|
||||
state->select_start = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_textedit_move_to_first(STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_sortselection(state);
|
||||
state->cursor = state->select_start;
|
||||
state->select_end = state->select_start;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_sortselection(state);
|
||||
stb_textedit_clamp(str, state);
|
||||
state->cursor = state->select_end;
|
||||
state->select_start = state->select_end;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef STB_TEXTEDIT_IS_SPACE
|
||||
static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
|
||||
{
|
||||
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
||||
}
|
||||
|
||||
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
||||
static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
||||
{
|
||||
--c;
|
||||
while( c >= 0 && !is_word_boundary( str, c ) )
|
||||
--c;
|
||||
|
||||
if( c < 0 )
|
||||
c = 0;
|
||||
|
||||
return c;
|
||||
}
|
||||
#define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous
|
||||
#endif
|
||||
|
||||
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||
static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
|
||||
{
|
||||
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
||||
++c;
|
||||
while( c < len && !is_word_boundary( str, c ) )
|
||||
++c;
|
||||
|
||||
if( c > len )
|
||||
c = len;
|
||||
|
||||
return c;
|
||||
}
|
||||
#define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
|
||||
{
|
||||
if (!STB_TEXT_HAS_SELECTION(state))
|
||||
state->select_start = state->select_end = state->cursor;
|
||||
else
|
||||
state->cursor = state->select_end;
|
||||
}
|
||||
|
||||
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_delete_selection(str,state);
|
||||
state->has_preferred_x = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
||||
{
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_delete_selection(str,state);
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
|
||||
stb_text_makeundo_insert(state, state->cursor, len);
|
||||
state->cursor += len;
|
||||
state->has_preferred_x = 0;
|
||||
return 1;
|
||||
}
|
||||
if (state->undostate.undo_point)
|
||||
--state->undostate.undo_point;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef STB_TEXTEDIT_KEYTYPE
|
||||
#define STB_TEXTEDIT_KEYTYPE int
|
||||
#endif
|
||||
|
||||
static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||
{
|
||||
retry:
|
||||
switch (key) {
|
||||
default: {
|
||||
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
||||
if (c > 0) {
|
||||
STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
|
||||
|
||||
if (c == '\n' && state->single_line)
|
||||
break;
|
||||
|
||||
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
|
||||
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
|
||||
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
||||
++state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
} else {
|
||||
stb_textedit_delete_selection(str,state);
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
||||
stb_text_makeundo_insert(state, state->cursor, 1);
|
||||
++state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_INSERT
|
||||
case STB_TEXTEDIT_K_INSERT:
|
||||
state->insert_mode = !state->insert_mode;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case STB_TEXTEDIT_K_UNDO:
|
||||
stb_text_undo(str, state);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_REDO:
|
||||
stb_text_redo(str, state);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_LEFT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_first(state);
|
||||
else
|
||||
if (state->cursor > 0)
|
||||
--state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_RIGHT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_last(str, state);
|
||||
else
|
||||
++state->cursor;
|
||||
stb_textedit_clamp(str, state);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT:
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
if (state->select_end > 0)
|
||||
--state->select_end;
|
||||
state->cursor = state->select_end;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
#ifdef STB_TEXTEDIT_MOVEWORDLEFT
|
||||
case STB_TEXTEDIT_K_WORDLEFT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_first(state);
|
||||
else {
|
||||
state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
|
||||
stb_textedit_clamp( str, state );
|
||||
}
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT:
|
||||
if( !STB_TEXT_HAS_SELECTION( state ) )
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
|
||||
state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
|
||||
state->select_end = state->cursor;
|
||||
|
||||
stb_textedit_clamp( str, state );
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||
case STB_TEXTEDIT_K_WORDRIGHT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_last(str, state);
|
||||
else {
|
||||
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
|
||||
stb_textedit_clamp( str, state );
|
||||
}
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT:
|
||||
if( !STB_TEXT_HAS_SELECTION( state ) )
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
|
||||
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
|
||||
state->select_end = state->cursor;
|
||||
|
||||
stb_textedit_clamp( str, state );
|
||||
break;
|
||||
#endif
|
||||
|
||||
case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
++state->select_end;
|
||||
stb_textedit_clamp(str, state);
|
||||
state->cursor = state->select_end;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_DOWN:
|
||||
case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT:
|
||||
case STB_TEXTEDIT_K_PGDOWN:
|
||||
case STB_TEXTEDIT_K_PGDOWN | STB_TEXTEDIT_K_SHIFT: {
|
||||
StbFindState find;
|
||||
StbTexteditRow row;
|
||||
int i, j, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||
int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGDOWN;
|
||||
int row_count = is_page ? state->row_count_per_page : 1;
|
||||
|
||||
if (!is_page && state->single_line) {
|
||||
key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (sel)
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
else if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_last(str, state);
|
||||
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
||||
|
||||
for (j = 0; j < row_count; ++j) {
|
||||
float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||
int start = find.first_char + find.length;
|
||||
|
||||
if (find.length == 0)
|
||||
break;
|
||||
|
||||
if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE)
|
||||
break;
|
||||
|
||||
state->cursor = start;
|
||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||
x = row.x0;
|
||||
for (i=0; i < row.num_chars; ++i) {
|
||||
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
break;
|
||||
#endif
|
||||
x += dx;
|
||||
if (x > goal_x)
|
||||
break;
|
||||
++state->cursor;
|
||||
}
|
||||
stb_textedit_clamp(str, state);
|
||||
|
||||
state->has_preferred_x = 1;
|
||||
state->preferred_x = goal_x;
|
||||
|
||||
if (sel)
|
||||
state->select_end = state->cursor;
|
||||
|
||||
find.first_char = find.first_char + find.length;
|
||||
find.length = row.num_chars;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STB_TEXTEDIT_K_UP:
|
||||
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
|
||||
case STB_TEXTEDIT_K_PGUP:
|
||||
case STB_TEXTEDIT_K_PGUP | STB_TEXTEDIT_K_SHIFT: {
|
||||
StbFindState find;
|
||||
StbTexteditRow row;
|
||||
int i, j, prev_scan, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||
int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGUP;
|
||||
int row_count = is_page ? state->row_count_per_page : 1;
|
||||
|
||||
if (!is_page && state->single_line) {
|
||||
key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (sel)
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
else if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_first(state);
|
||||
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
||||
|
||||
for (j = 0; j < row_count; ++j) {
|
||||
float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||
|
||||
if (find.prev_first == find.first_char)
|
||||
break;
|
||||
|
||||
state->cursor = find.prev_first;
|
||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||
x = row.x0;
|
||||
for (i=0; i < row.num_chars; ++i) {
|
||||
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
break;
|
||||
#endif
|
||||
x += dx;
|
||||
if (x > goal_x)
|
||||
break;
|
||||
++state->cursor;
|
||||
}
|
||||
stb_textedit_clamp(str, state);
|
||||
|
||||
state->has_preferred_x = 1;
|
||||
state->preferred_x = goal_x;
|
||||
|
||||
if (sel)
|
||||
state->select_end = state->cursor;
|
||||
|
||||
prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
|
||||
while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE)
|
||||
--prev_scan;
|
||||
find.first_char = find.prev_first;
|
||||
find.prev_first = prev_scan;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STB_TEXTEDIT_K_DELETE:
|
||||
case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_delete_selection(str, state);
|
||||
else {
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
if (state->cursor < n)
|
||||
stb_textedit_delete(str, state, state->cursor, 1);
|
||||
}
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_BACKSPACE:
|
||||
case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_delete_selection(str, state);
|
||||
else {
|
||||
stb_textedit_clamp(str, state);
|
||||
if (state->cursor > 0) {
|
||||
stb_textedit_delete(str, state, state->cursor-1, 1);
|
||||
--state->cursor;
|
||||
}
|
||||
}
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
||||
case STB_TEXTEDIT_K_TEXTSTART2:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_TEXTSTART:
|
||||
state->cursor = state->select_start = state->select_end = 0;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTEND2
|
||||
case STB_TEXTEDIT_K_TEXTEND2:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_TEXTEND:
|
||||
state->cursor = STB_TEXTEDIT_STRINGLEN(str);
|
||||
state->select_start = state->select_end = 0;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
||||
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT:
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
state->cursor = state->select_end = 0;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTEND2
|
||||
case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT:
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_LINESTART2
|
||||
case STB_TEXTEDIT_K_LINESTART2:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_LINESTART:
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_move_to_first(state);
|
||||
if (state->single_line)
|
||||
state->cursor = 0;
|
||||
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
||||
--state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_LINEEND2
|
||||
case STB_TEXTEDIT_K_LINEEND2:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_LINEEND: {
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_move_to_first(state);
|
||||
if (state->single_line)
|
||||
state->cursor = n;
|
||||
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
||||
++state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_LINESTART2
|
||||
case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT:
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
if (state->single_line)
|
||||
state->cursor = 0;
|
||||
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
||||
--state->cursor;
|
||||
state->select_end = state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_LINEEND2
|
||||
case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
if (state->single_line)
|
||||
state->cursor = n;
|
||||
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
||||
++state->cursor;
|
||||
state->select_end = state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_textedit_flush_redo(StbUndoState *state)
|
||||
{
|
||||
state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
}
|
||||
|
||||
static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
{
|
||||
if (state->undo_point > 0) {
|
||||
if (state->undo_rec[0].char_storage >= 0) {
|
||||
int n = state->undo_rec[0].insert_length, i;
|
||||
state->undo_char_point -= n;
|
||||
STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=0; i < state->undo_point; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage -= n;
|
||||
}
|
||||
--state->undo_point;
|
||||
STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
{
|
||||
int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
|
||||
|
||||
if (state->redo_point <= k) {
|
||||
if (state->undo_rec[k].char_storage >= 0) {
|
||||
int n = state->undo_rec[k].insert_length, i;
|
||||
state->redo_char_point += n;
|
||||
STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=state->redo_point; i < k; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage += n;
|
||||
}
|
||||
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
||||
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||
|
||||
++state->redo_point;
|
||||
}
|
||||
}
|
||||
|
||||
static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars)
|
||||
{
|
||||
stb_textedit_flush_redo(state);
|
||||
|
||||
if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
stb_textedit_discard_undo(state);
|
||||
|
||||
if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
state->undo_point = 0;
|
||||
state->undo_char_point = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
|
||||
stb_textedit_discard_undo(state);
|
||||
|
||||
return &state->undo_rec[state->undo_point++];
|
||||
}
|
||||
|
||||
static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
||||
{
|
||||
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
||||
if (r == NULL)
|
||||
return NULL;
|
||||
|
||||
r->where = pos;
|
||||
r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
|
||||
r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
|
||||
|
||||
if (insert_len == 0) {
|
||||
r->char_storage = -1;
|
||||
return NULL;
|
||||
} else {
|
||||
r->char_storage = state->undo_char_point;
|
||||
state->undo_char_point += insert_len;
|
||||
return &state->undo_char[r->char_storage];
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
StbUndoState *s = &state->undostate;
|
||||
StbUndoRecord u, *r;
|
||||
if (s->undo_point == 0)
|
||||
return;
|
||||
|
||||
u = s->undo_rec[s->undo_point-1];
|
||||
r = &s->undo_rec[s->redo_point-1];
|
||||
r->char_storage = -1;
|
||||
|
||||
r->insert_length = u.delete_length;
|
||||
r->delete_length = u.insert_length;
|
||||
r->where = u.where;
|
||||
|
||||
if (u.delete_length) {
|
||||
if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
r->insert_length = 0;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
return;
|
||||
stb_textedit_discard_redo(s);
|
||||
}
|
||||
r = &s->undo_rec[s->redo_point-1];
|
||||
|
||||
r->char_storage = s->redo_char_point - u.delete_length;
|
||||
s->redo_char_point = s->redo_char_point - u.delete_length;
|
||||
|
||||
for (i=0; i < u.delete_length; ++i)
|
||||
s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i);
|
||||
}
|
||||
|
||||
STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length);
|
||||
}
|
||||
|
||||
if (u.insert_length) {
|
||||
STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length);
|
||||
s->undo_char_point -= u.insert_length;
|
||||
}
|
||||
|
||||
state->cursor = u.where + u.insert_length;
|
||||
|
||||
s->undo_point--;
|
||||
s->redo_point--;
|
||||
}
|
||||
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
StbUndoState *s = &state->undostate;
|
||||
StbUndoRecord *u, r;
|
||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
return;
|
||||
|
||||
u = &s->undo_rec[s->undo_point];
|
||||
r = s->undo_rec[s->redo_point];
|
||||
|
||||
u->delete_length = r.insert_length;
|
||||
u->insert_length = r.delete_length;
|
||||
u->where = r.where;
|
||||
u->char_storage = -1;
|
||||
|
||||
if (r.delete_length) {
|
||||
if (s->undo_char_point + u->insert_length > s->redo_char_point) {
|
||||
u->insert_length = 0;
|
||||
u->delete_length = 0;
|
||||
} else {
|
||||
int i;
|
||||
u->char_storage = s->undo_char_point;
|
||||
s->undo_char_point = s->undo_char_point + u->insert_length;
|
||||
|
||||
for (i=0; i < u->insert_length; ++i)
|
||||
s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i);
|
||||
}
|
||||
|
||||
STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length);
|
||||
}
|
||||
|
||||
if (r.insert_length) {
|
||||
STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
|
||||
s->redo_char_point += r.insert_length;
|
||||
}
|
||||
|
||||
state->cursor = r.where + r.insert_length;
|
||||
|
||||
s->undo_point++;
|
||||
s->redo_point++;
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length)
|
||||
{
|
||||
stb_text_createundo(&state->undostate, where, 0, length);
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||
{
|
||||
int i;
|
||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
||||
if (p) {
|
||||
for (i=0; i < length; ++i)
|
||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
||||
{
|
||||
int i;
|
||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
||||
if (p) {
|
||||
for (i=0; i < old_length; ++i)
|
||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line)
|
||||
{
|
||||
state->undostate.undo_point = 0;
|
||||
state->undostate.undo_char_point = 0;
|
||||
state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
state->select_end = state->select_start = 0;
|
||||
state->cursor = 0;
|
||||
state->has_preferred_x = 0;
|
||||
state->preferred_x = 0;
|
||||
state->cursor_at_end_of_line = 0;
|
||||
state->initialized = 1;
|
||||
state->single_line = (unsigned char) is_single_line;
|
||||
state->insert_mode = 0;
|
||||
state->row_count_per_page = 0;
|
||||
}
|
||||
|
||||
static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line)
|
||||
{
|
||||
stb_textedit_clear_state(state, is_single_line);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
#endif
|
||||
|
||||
static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
||||
{
|
||||
return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,397 @@
|
||||
#pragma once
|
||||
#include "ProtoParse.h"
|
||||
#include "ProtobuffMessages.h"
|
||||
#include <ctime>
|
||||
|
||||
#include "Options.hpp"
|
||||
|
||||
struct wskin
|
||||
{
|
||||
int wId;
|
||||
int paintkit;
|
||||
};
|
||||
|
||||
#define START_MUSICKIT_INDEX 1500000
|
||||
#define START_ITEM_INDEX 2000000
|
||||
|
||||
static void clear_equip_state(CMsgClientWelcome::SubscribedType& object);
|
||||
static void apply_medals(CMsgClientWelcome::SubscribedType& object);
|
||||
static void apply_music_kits(CMsgClientWelcome::SubscribedType& object);
|
||||
|
||||
static void add_item(CMsgClientWelcome::SubscribedType& object, int index, ItemDefinitionIndex itemIndex, int quality, int rarity, int paintKit, int seed, float wear, std::string name, std::string desc, sticker stickers[5], int stattrak, int flag);
|
||||
|
||||
static int GetAvailableClassID(int definition_index);
|
||||
static int GetSlotID(int definition_index);
|
||||
static std::vector<uint32_t> music_kits = { 3, 4, 5, 6, 7, 8 };
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline std::string get_4bytes(T value)
|
||||
{
|
||||
return std::string{ reinterpret_cast<const char*>(reinterpret_cast<void*>(&value)), 4 };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline CSOEconItemAttribute make_econ_item_attribute(int def_index, T value)
|
||||
{
|
||||
CSOEconItemAttribute attribute;
|
||||
attribute.def_index().set(def_index);
|
||||
attribute.value_bytes().set(get_4bytes(value));
|
||||
return attribute;
|
||||
}
|
||||
|
||||
inline CSOEconItemEquipped make_equipped_state(int team, int slot)
|
||||
{
|
||||
CSOEconItemEquipped equipped_state;
|
||||
equipped_state.new_class().set(team);
|
||||
equipped_state.new_slot().set(slot);
|
||||
return equipped_state;
|
||||
}
|
||||
|
||||
static std::string inventory_changer(void* pubDest, uint32_t* pcubMsgSize) {
|
||||
CMsgClientWelcome msg((void*)((DWORD)pubDest + 8), *pcubMsgSize - 8);
|
||||
if (!msg.outofdate_subscribed_caches().has())
|
||||
return msg.serialize();
|
||||
|
||||
auto cache = msg.outofdate_subscribed_caches().get();
|
||||
|
||||
static auto fix_null_inventory = [&cache]()
|
||||
{
|
||||
auto objects = cache.objects().get_all();
|
||||
auto it = std::find_if(objects.begin(), objects.end(), [](decltype(objects.front()) o)
|
||||
{
|
||||
return o.type_id().has() && o.type_id().get() == 1;
|
||||
});
|
||||
|
||||
if (it == objects.end())
|
||||
{
|
||||
CMsgClientWelcome::SubscribedType null_object;
|
||||
null_object.type_id().set(1);
|
||||
cache.objects().add(null_object);
|
||||
}
|
||||
};
|
||||
|
||||
fix_null_inventory();
|
||||
|
||||
auto objects = cache.objects().get_all();
|
||||
for (size_t i = 0; i < objects.size(); i++) {
|
||||
auto object = objects[i];
|
||||
|
||||
if (!object.type_id().has())
|
||||
continue;
|
||||
|
||||
switch (object.type_id().get())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (true)
|
||||
object.object_data().clear();
|
||||
|
||||
int indexcount = 0;
|
||||
|
||||
for (int i = 0; i < g_Options.weapons.value->weaponzcount; i++)
|
||||
if (g_Options.weapons.value->arr[i].active) {
|
||||
indexcount++;
|
||||
add_item(object, indexcount,
|
||||
(ItemDefinitionIndex)g_Options.weapons.value->arr[i].modeldefindex,
|
||||
g_Options.weapons.value->arr[i].quality,
|
||||
g_Options.weapons.value->arr[i].rarity,
|
||||
g_Options.weapons.value->arr[i].skinid,
|
||||
g_Options.weapons.value->arr[i].seed,
|
||||
g_Options.weapons.value->arr[i].wear,
|
||||
g_Options.weapons.value->arr[i].nametag,
|
||||
g_Options.weapons.value->arr[i].desctag,
|
||||
g_Options.weapons.value->arr[i].stickers,
|
||||
g_Options.weapons.value->arr[i].stattrak,
|
||||
i);
|
||||
}
|
||||
|
||||
cache.objects().set(object, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
msg.outofdate_subscribed_caches().set(cache);
|
||||
|
||||
return msg.serialize();
|
||||
}
|
||||
|
||||
static bool inventory_changer_presend(void* pubData, uint32_t& cubData)
|
||||
{
|
||||
CMsgAdjustItemEquippedState msg((void*)((DWORD)pubData + 8), cubData - 8);
|
||||
if (msg.item_id().has() && (msg.new_class().get() == 0 || msg.new_slot().get() == 54))
|
||||
{
|
||||
auto ItemIndex = msg.item_id().get() - START_MUSICKIT_INDEX;
|
||||
|
||||
if (ItemIndex > 38 || ItemIndex < 3)
|
||||
return true;
|
||||
|
||||
msg.new_slot().get() == 0xFFFF ? 0 : ItemIndex - 2;
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!msg.item_id().has() || !msg.new_class().get() || !msg.new_slot().get())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void clear_equip_state(CMsgClientWelcome::SubscribedType& object)
|
||||
{
|
||||
auto object_data = object.object_data().get_all();
|
||||
for (size_t j = 0; j < object_data.size(); j++)
|
||||
{
|
||||
auto item = object_data[j];
|
||||
|
||||
if (!item.equipped_state().has())
|
||||
continue;
|
||||
|
||||
auto null_equipped_state = make_equipped_state(0, 0);
|
||||
|
||||
auto equipped_state = item.equipped_state().get_all();
|
||||
for (size_t k = 0; k < equipped_state.size(); k++)
|
||||
item.equipped_state().set(null_equipped_state, k);
|
||||
|
||||
object.object_data().set(item, j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void add_item(CMsgClientWelcome::SubscribedType& object, int index, ItemDefinitionIndex itemIndex, int quality, int rarity, int paintKit, int seed, float wear, std::string name, std::string desc, sticker stickers[5], int stattrak, int flag)
|
||||
{
|
||||
uint32_t steamid = iff.g_SteamUser->GetSteamID().GetAccountID();
|
||||
|
||||
CSOEconItem item;
|
||||
item.id().set(START_ITEM_INDEX + itemIndex);
|
||||
item.account_id().set(steamid);
|
||||
if (flag == 5)
|
||||
item.def_index().set(1314);
|
||||
else item.def_index().set(itemIndex);
|
||||
item.inventory().set(START_ITEM_INDEX + index);
|
||||
item.origin().set(24);
|
||||
item.quantity().set(1);
|
||||
item.level().set(1);
|
||||
item.style().set(0);
|
||||
item.flags().set(0);
|
||||
item.in_use().set(true);
|
||||
item.original_id().set(0);
|
||||
item.rarity().set(rarity);
|
||||
item.quality().set(quality);
|
||||
|
||||
if (name.size() > 0)
|
||||
item.custom_name().set(name);
|
||||
|
||||
if (desc.size() > 0)
|
||||
item.custom_desc().set(desc);
|
||||
|
||||
if (flag > 5) {
|
||||
int avalTeam = GetAvailableClassID(itemIndex);
|
||||
if (avalTeam == TEAM_SPECTATOR || avalTeam == TEAM_TERRORIST) {
|
||||
item.equipped_state().add(make_equipped_state(TEAM_TERRORIST, GetSlotID(itemIndex)));
|
||||
}
|
||||
if (avalTeam == TEAM_SPECTATOR || avalTeam == TEAM_CT) {
|
||||
item.equipped_state().add(make_equipped_state(TEAM_CT, GetSlotID(itemIndex)));
|
||||
}
|
||||
}
|
||||
|
||||
item.attribute().add(make_econ_item_attribute(6, float(paintKit)));
|
||||
item.attribute().add(make_econ_item_attribute(7, float(seed)));
|
||||
item.attribute().add(make_econ_item_attribute(8, float(wear)));
|
||||
|
||||
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
item.attribute().add(make_econ_item_attribute(113 + 4 * j, stickers[j].stickerid ));
|
||||
item.attribute().add(make_econ_item_attribute(114 + 4 * j, stickers[j].wear));
|
||||
item.attribute().add(make_econ_item_attribute(115 + 4 * j, stickers[j].scale));
|
||||
item.attribute().add(make_econ_item_attribute(116 + 4 * j, stickers[j].rotation));
|
||||
}
|
||||
|
||||
if (stattrak != -1)
|
||||
{
|
||||
item.attribute().add(make_econ_item_attribute(80, stattrak));
|
||||
item.attribute().add(make_econ_item_attribute(81, 0));
|
||||
}
|
||||
|
||||
if (flag == 0)
|
||||
{
|
||||
item.equipped_state().add(make_equipped_state(TEAM_TERRORIST, 0));
|
||||
item.equipped_state().add(make_equipped_state(TEAM_CT, 0));
|
||||
}
|
||||
|
||||
if (flag == 1)
|
||||
{
|
||||
item.equipped_state().add(make_equipped_state(TEAM_TERRORIST, 41));
|
||||
item.equipped_state().add(make_equipped_state(TEAM_CT, 41));
|
||||
}
|
||||
|
||||
if (flag == 2)
|
||||
item.equipped_state().set(make_equipped_state(2, 38));
|
||||
|
||||
if (flag == 3)
|
||||
item.equipped_state().set(make_equipped_state(3, 38));
|
||||
|
||||
|
||||
if (flag == 4)
|
||||
item.equipped_state().set(make_equipped_state(0, 55));
|
||||
|
||||
|
||||
if (flag == 5)
|
||||
{
|
||||
item.attribute().add(make_econ_item_attribute(166, itemIndex));
|
||||
item.inventory().set(START_MUSICKIT_INDEX + itemIndex);
|
||||
item.id().set(START_MUSICKIT_INDEX + itemIndex);
|
||||
item.equipped_state().set(make_equipped_state(0, 54));
|
||||
}
|
||||
|
||||
object.object_data().add(item);
|
||||
}
|
||||
|
||||
static int GetAvailableClassID(int definition_index)
|
||||
{
|
||||
switch (definition_index)
|
||||
{
|
||||
case WEAPON_KNIFE_BAYONET:
|
||||
case WEAPON_KNIFE_FLIP:
|
||||
case WEAPON_KNIFE_GUT:
|
||||
case WEAPON_KNIFE_KARAMBIT:
|
||||
case WEAPON_KNIFE_M9_BAYONET:
|
||||
case WEAPON_KNIFE_TACTICAL:
|
||||
case WEAPON_KNIFE_FALCHION:
|
||||
case WEAPON_KNIFE_SURVIVAL_BOWIE:
|
||||
case WEAPON_KNIFE_BUTTERFLY:
|
||||
case WEAPON_KNIFE_PUSH:
|
||||
case WEAPON_ELITE:
|
||||
case WEAPON_P250:
|
||||
case WEAPON_CZ75A:
|
||||
case WEAPON_DEAGLE:
|
||||
case WEAPON_REVOLVER:
|
||||
case WEAPON_MP7:
|
||||
case WEAPON_UMP45:
|
||||
case WEAPON_P90:
|
||||
case WEAPON_BIZON:
|
||||
case WEAPON_SSG08:
|
||||
case WEAPON_AWP:
|
||||
case WEAPON_NOVA:
|
||||
case WEAPON_XM1014:
|
||||
case WEAPON_M249:
|
||||
case WEAPON_NEGEV:
|
||||
case GLOVE_STUDDED_BLOODHOUND:
|
||||
case GLOVE_SPORTY:
|
||||
case GLOVE_SLICK:
|
||||
case GLOVE_LEATHER_WRAP:
|
||||
case GLOVE_MOTORCYCLE:
|
||||
case GLOVE_SPECIALIST:
|
||||
return TEAM_SPECTATOR;
|
||||
|
||||
case WEAPON_GLOCK:
|
||||
case WEAPON_AK47:
|
||||
case WEAPON_MAC10:
|
||||
case WEAPON_G3SG1:
|
||||
case WEAPON_TEC9:
|
||||
case WEAPON_GALILAR:
|
||||
case WEAPON_SG553:
|
||||
case WEAPON_SAWEDOFF:
|
||||
case WEAPON_C4:
|
||||
return TEAM_TERRORIST;
|
||||
|
||||
case WEAPON_AUG:
|
||||
case WEAPON_FAMAS:
|
||||
case WEAPON_MAG7:
|
||||
case WEAPON_FIVESEVEN:
|
||||
case WEAPON_USP_SILENCER:
|
||||
case WEAPON_HKP2000:
|
||||
case WEAPON_MP9:
|
||||
case WEAPON_M4A1_SILENCER:
|
||||
case WEAPON_M4A1:
|
||||
case WEAPON_SCAR20:
|
||||
return TEAM_CT;
|
||||
|
||||
default:
|
||||
return TEAM_UNASSIGNED;
|
||||
}
|
||||
}
|
||||
|
||||
static int GetSlotID(int definition_index)
|
||||
{
|
||||
switch (definition_index)
|
||||
{
|
||||
case WEAPON_KNIFE_BAYONET:
|
||||
case WEAPON_KNIFE_FLIP:
|
||||
case WEAPON_KNIFE_GUT:
|
||||
case WEAPON_KNIFE_KARAMBIT:
|
||||
case WEAPON_KNIFE_M9_BAYONET:
|
||||
case WEAPON_KNIFE_TACTICAL:
|
||||
case WEAPON_KNIFE_FALCHION:
|
||||
case WEAPON_KNIFE_SURVIVAL_BOWIE:
|
||||
case WEAPON_KNIFE_BUTTERFLY:
|
||||
case WEAPON_KNIFE_PUSH:
|
||||
return 0;
|
||||
case WEAPON_C4:
|
||||
return 1;
|
||||
case WEAPON_USP_SILENCER:
|
||||
case WEAPON_HKP2000:
|
||||
case WEAPON_GLOCK:
|
||||
return 2;
|
||||
case WEAPON_ELITE:
|
||||
return 3;
|
||||
case WEAPON_P250:
|
||||
return 4;
|
||||
case WEAPON_TEC9:
|
||||
case WEAPON_CZ75A:
|
||||
case WEAPON_FIVESEVEN:
|
||||
return 5;
|
||||
case WEAPON_DEAGLE:
|
||||
case WEAPON_REVOLVER:
|
||||
return 6;
|
||||
case WEAPON_MP9:
|
||||
case WEAPON_MAC10:
|
||||
return 8;
|
||||
case WEAPON_MP7:
|
||||
return 9;
|
||||
case WEAPON_UMP45:
|
||||
return 10;
|
||||
case WEAPON_P90:
|
||||
return 11;
|
||||
case WEAPON_BIZON:
|
||||
return 12;
|
||||
case WEAPON_FAMAS:
|
||||
case WEAPON_GALILAR:
|
||||
return 14;
|
||||
case WEAPON_M4A1_SILENCER:
|
||||
case WEAPON_M4A1:
|
||||
case WEAPON_AK47:
|
||||
return 15;
|
||||
case WEAPON_SSG08:
|
||||
return 16;
|
||||
case WEAPON_SG553:
|
||||
case WEAPON_AUG:
|
||||
return 17;
|
||||
case WEAPON_AWP:
|
||||
return 18;
|
||||
case WEAPON_G3SG1:
|
||||
case WEAPON_SCAR20:
|
||||
return 19;
|
||||
case WEAPON_NOVA:
|
||||
return 20;
|
||||
case WEAPON_XM1014:
|
||||
return 21;
|
||||
case WEAPON_SAWEDOFF:
|
||||
case WEAPON_MAG7:
|
||||
return 22;
|
||||
case WEAPON_M249:
|
||||
return 23;
|
||||
case WEAPON_NEGEV:
|
||||
return 24;
|
||||
case GLOVE_STUDDED_BLOODHOUND:
|
||||
case GLOVE_SPORTY:
|
||||
case GLOVE_SLICK:
|
||||
case GLOVE_LEATHER_WRAP:
|
||||
case GLOVE_MOTORCYCLE:
|
||||
case GLOVE_SPECIALIST:
|
||||
return 41;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
+1785
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
typedef const void(__thiscall* pShutdown)(void*, void*, const char*);
|
||||
pShutdown oShutdown;
|
||||
void __fastcall hkShutdown(void* thisptr, void* unk1, void* unk2, const char* reason) noexcept
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("shutdown (%x) HOOKED %s\n", thisptr, reason);
|
||||
#endif
|
||||
|
||||
if (*g_Options.discmsg_active) {
|
||||
#ifdef DEBUG
|
||||
printf("set new reason %s\n", g_Options.discmsg.value->mystring);
|
||||
#endif
|
||||
char customreason[256] = "#";
|
||||
strcat_s( customreason, MakeControlChars(g_Options.discmsg.value->mystring));
|
||||
|
||||
oShutdown(thisptr, nullptr, customreason);
|
||||
}
|
||||
else
|
||||
oShutdown(thisptr, nullptr, reason);
|
||||
}
|
||||
|
||||
inline void HookNetchannel()
|
||||
{
|
||||
DWORD ptrShutdown = *((DWORD*)iff.g_pEngineClient->GetNetChannelInfo()) + 36 * 4;
|
||||
DWORD addrShutdown = *(DWORD*)ptrShutdown;
|
||||
oShutdown = (pShutdown)DetourFunction(
|
||||
(PBYTE)(addrShutdown),
|
||||
(PBYTE)hkShutdown);
|
||||
#ifdef DEBUG
|
||||
printf("Detoured at %x\n", addrShutdown);
|
||||
#endif
|
||||
opt.netchannedlhooked = 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "netvars.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
|
||||
#include "interfaces.hpp"
|
||||
|
||||
void NetvarSys::Initialize()
|
||||
{
|
||||
|
||||
m_tables.clear();
|
||||
|
||||
ClientClass* clientClass = iff.g_pClient->GetAllClasses();
|
||||
if (!clientClass)
|
||||
return;
|
||||
|
||||
while (clientClass)
|
||||
{
|
||||
RecvTable* recvTable = clientClass->m_pRecvTable;
|
||||
m_tables.push_back(recvTable);
|
||||
|
||||
clientClass = clientClass->m_pNext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#undef GetProp
|
||||
|
||||
int NetvarSys::GetOffset(const char* tableName, const char* propName)
|
||||
{
|
||||
int offset = this->GetProp(tableName, propName);
|
||||
if (!offset)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("%s not found!\n", propName);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("%s: 0x%02X\n", propName, offset);
|
||||
#endif
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
int NetvarSys::GetProp(const char* tableName, const char* propName, RecvProp** prop)
|
||||
{
|
||||
RecvTable* recvTable = GetTable(tableName);
|
||||
if (!recvTable)
|
||||
return 0;
|
||||
|
||||
int offset = this->GetProp(recvTable, propName, prop);
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
int NetvarSys::GetProp(RecvTable* recvTable, const char* propName, RecvProp** prop)
|
||||
{
|
||||
int extraOffset = 0;
|
||||
for (int i = 0; i < recvTable->m_nProps; ++i)
|
||||
{
|
||||
RecvProp* recvProp = &recvTable->m_pProps[i];
|
||||
RecvTable* child = recvProp->m_pDataTable;
|
||||
|
||||
if (child && (child->m_nProps > 0))
|
||||
{
|
||||
int tmp = this->GetProp(child, propName, prop);
|
||||
if (tmp)
|
||||
extraOffset += (recvProp->m_Offset + tmp);
|
||||
}
|
||||
|
||||
if (_stricmp(recvProp->m_pVarName, propName))
|
||||
continue;
|
||||
|
||||
if (prop)
|
||||
*prop = recvProp;
|
||||
|
||||
return (recvProp->m_Offset + extraOffset);
|
||||
}
|
||||
|
||||
return extraOffset;
|
||||
}
|
||||
|
||||
RecvTable* NetvarSys::GetTable(const char* tableName)
|
||||
{
|
||||
if (m_tables.empty())
|
||||
return 0;
|
||||
|
||||
for (const auto& table : m_tables)
|
||||
{
|
||||
if (!table)
|
||||
continue;
|
||||
|
||||
if (_stricmp(table->m_pNetTableName, tableName) == 0)
|
||||
return table;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "dt_recv.h"
|
||||
#include "Singleton.hpp"
|
||||
|
||||
class NetvarSys
|
||||
: public Singleton<NetvarSys>
|
||||
{
|
||||
public:
|
||||
void Initialize();
|
||||
|
||||
int GetOffset(const char* tableName, const char* propName);
|
||||
|
||||
RecvTable* GetTable(const char* tableName);
|
||||
std::vector<RecvTable*> m_tables;
|
||||
|
||||
private:
|
||||
int GetProp(const char* tableName, const char* propName, RecvProp** prop = 0);
|
||||
int GetProp(RecvTable* recvTable, const char* propName, RecvProp** prop = 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define NETVAR_OFFSET2(funcname, class_name, var_name, offset, ...) \
|
||||
auto funcname() -> std::add_lvalue_reference_t<__VA_ARGS__> \
|
||||
{ \
|
||||
static int netvar = NetvarSys::Get().GetOffset(class_name, var_name); \
|
||||
auto addr = std::uintptr_t(this) + offset + netvar; \
|
||||
return *reinterpret_cast<std::add_pointer_t<__VA_ARGS__>>(addr); \
|
||||
}
|
||||
|
||||
#define NETVAR2(funcname, class_name, var_name, ...) \
|
||||
NETVAR_OFFSET2(funcname, class_name, var_name, 0, __VA_ARGS__)
|
||||
@@ -0,0 +1,779 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
#define PBFIELD(number, type, name) \
|
||||
pbfield<number, type> name() const { \
|
||||
return std::move(pbfield<number, type>( fv_ )); \
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#define __forceinline __attribute__((always_inline))
|
||||
|
||||
#define PBMSG_CTOR(class_name) \
|
||||
class_name() : pbmsg() {} \
|
||||
class_name(void* buf, size_t bytes) : pbmsg(buf, bytes) {} \
|
||||
class_name(const std::string& buf) : pbmsg(buf) {}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#define PBMSG_CTOR using pbmsg::pbmsg
|
||||
#endif
|
||||
|
||||
namespace pbwrap
|
||||
{
|
||||
static constexpr int32_t k_invalid_id = -1;
|
||||
|
||||
enum e_field_type
|
||||
{
|
||||
TYPE_DOUBLE = 1,
|
||||
TYPE_FLOAT = 2,
|
||||
TYPE_INT64 = 3,
|
||||
TYPE_UINT64 = 4,
|
||||
TYPE_INT32 = 5,
|
||||
TYPE_FIXED64 = 6,
|
||||
TYPE_FIXED32 = 7,
|
||||
TYPE_BOOL = 8,
|
||||
TYPE_STRING = 9,
|
||||
TYPE_GROUP = 10,
|
||||
TYPE_MESSAGE = 11,
|
||||
TYPE_BYTES = 12,
|
||||
TYPE_UINT32 = 13,
|
||||
TYPE_ENUM = 14,
|
||||
TYPE_SFIXED32 = 15,
|
||||
TYPE_SFIXED64 = 16,
|
||||
TYPE_SINT32 = 17,
|
||||
TYPE_SINT64 = 18,
|
||||
MAX_FIELD_TYPE = 18,
|
||||
};
|
||||
|
||||
enum e_wire_type
|
||||
{
|
||||
WIRETYPE_VARINT = 0,
|
||||
WIRETYPE_FIXED64 = 1,
|
||||
WIRETYPE_LENGTH_DELIMITED = 2,
|
||||
WIRETYPE_START_GROUP = 3,
|
||||
WIRETYPE_END_GROUP = 4,
|
||||
WIRETYPE_FIXED32 = 5,
|
||||
};
|
||||
|
||||
static constexpr e_wire_type k_wire_type_for_field_type[MAX_FIELD_TYPE + 1] = {
|
||||
static_cast<e_wire_type>(k_invalid_id),
|
||||
WIRETYPE_FIXED64,
|
||||
WIRETYPE_FIXED32,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_FIXED64,
|
||||
WIRETYPE_FIXED32,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_LENGTH_DELIMITED,
|
||||
WIRETYPE_START_GROUP,
|
||||
WIRETYPE_LENGTH_DELIMITED,
|
||||
WIRETYPE_LENGTH_DELIMITED,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_FIXED32,
|
||||
WIRETYPE_FIXED64,
|
||||
WIRETYPE_VARINT,
|
||||
WIRETYPE_VARINT,
|
||||
};
|
||||
|
||||
namespace utils
|
||||
{
|
||||
static constexpr int k_tag_type_bits = 3;
|
||||
static constexpr uint32_t k_tag_type_mask = (1 << k_tag_type_bits) - 1;
|
||||
static constexpr int k_max_varint_bytes = 10;
|
||||
static constexpr int k_max_varint32_bytes = 5;
|
||||
|
||||
__forceinline auto make_tag(uint32_t field_number, uint32_t wire_type) -> uint32_t
|
||||
{
|
||||
return static_cast<uint32_t>((field_number << k_tag_type_bits) | wire_type);
|
||||
}
|
||||
|
||||
static auto get_bytes_varint32(uint32_t value) -> std::string
|
||||
{
|
||||
uint8_t bytes[k_max_varint32_bytes];
|
||||
int size = 0;
|
||||
while (value > 0x7F)
|
||||
{
|
||||
bytes[size++] = (static_cast<uint8_t>(value) & 0x7F) | 0x80;
|
||||
value >>= 7;
|
||||
}
|
||||
bytes[size++] = static_cast<uint8_t>(value) & 0x7F;
|
||||
return std::string{ reinterpret_cast<const char*>(&bytes[0]), (size_t)size };
|
||||
}
|
||||
|
||||
static auto get_bytes_varint64(uint64_t value) -> std::string
|
||||
{
|
||||
uint8_t bytes[k_max_varint_bytes];
|
||||
int size = 0;
|
||||
while (value > 0x7F)
|
||||
{
|
||||
bytes[size++] = (static_cast<uint8_t>(value) & 0x7F) | 0x80;
|
||||
value >>= 7;
|
||||
}
|
||||
bytes[size++] = static_cast<uint8_t>(value) & 0x7F;
|
||||
return std::string{ reinterpret_cast<const char*>(&bytes[0]), (size_t)size };
|
||||
}
|
||||
|
||||
static auto read_varuint32(const void* data, size_t& bytes_read) -> uint32_t
|
||||
{
|
||||
auto ptr = reinterpret_cast<const uint8_t*>(data);
|
||||
auto value = 0u;
|
||||
auto bytes = 0u;
|
||||
|
||||
do
|
||||
{
|
||||
value |= static_cast<uint32_t>(*ptr & 0x7f) << (7 * bytes);
|
||||
bytes++;
|
||||
} while (*(ptr++) & 0x80 && bytes <= 5);
|
||||
|
||||
bytes_read = bytes;
|
||||
return value;
|
||||
}
|
||||
|
||||
static auto read_varuint64(const void* data, size_t& bytes_read) -> uint64_t
|
||||
{
|
||||
auto ptr = reinterpret_cast<const uint8_t*>(data);
|
||||
auto value = 0ull;
|
||||
auto bytes = 0u;
|
||||
|
||||
do
|
||||
{
|
||||
value |= static_cast<uint64_t>(*ptr & 0x7f) << (7 * bytes);
|
||||
bytes++;
|
||||
} while (*(ptr++) & 0x80 && bytes <= 10);
|
||||
|
||||
bytes_read = bytes;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static auto read_field(const void* data, size_t& bytes_read)
|
||||
-> std::tuple<uint32_t, uint32_t, std::string, std::string>
|
||||
{
|
||||
uint32_t field = *reinterpret_cast<const uint16_t*>(data);
|
||||
uint32_t wire_type = field & k_tag_type_mask;
|
||||
|
||||
if (field == 0xffff)
|
||||
{
|
||||
bytes_read = 0;
|
||||
return std::make_tuple(k_invalid_id, k_invalid_id, "", "");
|
||||
}
|
||||
|
||||
if (field & 0x80)
|
||||
{
|
||||
field = ((field & 0x7f) | ((field & 0xff00) >> 1)) >> k_tag_type_bits;
|
||||
bytes_read = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
field = (field & 0xff) >> k_tag_type_bits;
|
||||
bytes_read = 1;
|
||||
}
|
||||
|
||||
std::string value_bytes, full_bytes;
|
||||
size_t length, size_delimited;
|
||||
|
||||
switch (wire_type)
|
||||
{
|
||||
case WIRETYPE_VARINT:
|
||||
read_varuint64((void*)((ptrdiff_t)data + bytes_read), length);
|
||||
value_bytes = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytes_read)), length };
|
||||
full_bytes = std::string{ reinterpret_cast<const char*>(data), bytes_read + length };
|
||||
bytes_read += length;
|
||||
break;
|
||||
case WIRETYPE_FIXED64:
|
||||
value_bytes = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytes_read)), 8 };
|
||||
full_bytes = std::string{ reinterpret_cast<const char*>(data), bytes_read + 8 };
|
||||
bytes_read += 8;
|
||||
break;
|
||||
case WIRETYPE_LENGTH_DELIMITED:
|
||||
size_delimited = read_varuint32((void*)((ptrdiff_t)data + bytes_read), length);
|
||||
value_bytes = std::string{
|
||||
reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytes_read)), length + size_delimited
|
||||
};
|
||||
full_bytes = std::string{ reinterpret_cast<const char*>(data), bytes_read + length + size_delimited };
|
||||
bytes_read += length + size_delimited;
|
||||
break;
|
||||
case WIRETYPE_START_GROUP:
|
||||
throw std::runtime_error("WIRETYPE_START_GROUP not implemented");
|
||||
break;
|
||||
case WIRETYPE_END_GROUP:
|
||||
throw std::runtime_error("WIRETYPE_END_GROUP not implemented");
|
||||
break;
|
||||
case WIRETYPE_FIXED32:
|
||||
value_bytes = std::string{ reinterpret_cast<const char*>((void*)((ptrdiff_t)data + bytes_read)), 4 };
|
||||
full_bytes = std::string{ reinterpret_cast<const char*>(data), bytes_read + 4 };
|
||||
bytes_read += 4;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown wire type");
|
||||
break;
|
||||
}
|
||||
|
||||
return std::make_tuple(field, wire_type, std::move(value_bytes), std::move(full_bytes));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto get_field_bytes(uint32_t field, uint32_t wire_type, T value)
|
||||
-> std::pair<std::string, std::string>
|
||||
{
|
||||
const auto tag = get_bytes_varint32(make_tag(field, wire_type));
|
||||
|
||||
std::string bytes{};
|
||||
switch (wire_type)
|
||||
{
|
||||
case WIRETYPE_VARINT:
|
||||
bytes += get_bytes_varint64(static_cast<uint64_t>(value));
|
||||
break;
|
||||
case WIRETYPE_FIXED32:
|
||||
bytes += std::string{ reinterpret_cast<const char*>(&value), 4 };
|
||||
break;
|
||||
case WIRETYPE_FIXED64:
|
||||
bytes += std::string{ reinterpret_cast<const char*>(&value), 8 };
|
||||
break;
|
||||
}
|
||||
|
||||
return { bytes, tag + bytes };
|
||||
}
|
||||
|
||||
template <>
|
||||
inline auto get_field_bytes<std::string>(uint32_t field, uint32_t wire_type, std::string value)
|
||||
-> std::pair<std::string, std::string>
|
||||
{
|
||||
const auto tag = get_bytes_varint32(make_tag(field, wire_type));
|
||||
|
||||
std::string bytes{};
|
||||
bytes += get_bytes_varint32(value.size());
|
||||
bytes += value;
|
||||
|
||||
return { bytes, tag + bytes };
|
||||
}
|
||||
|
||||
template <>
|
||||
inline auto get_field_bytes<const char*>(uint32_t field, uint32_t wire_type, const char* value)
|
||||
-> std::pair<std::string, std::string>
|
||||
{
|
||||
const auto tag = get_bytes_varint32(make_tag(field, wire_type));
|
||||
|
||||
std::string bytes{};
|
||||
bytes += get_bytes_varint32(strlen(value));
|
||||
bytes += value;
|
||||
|
||||
return { bytes, tag + bytes };
|
||||
}
|
||||
}
|
||||
|
||||
namespace types
|
||||
{
|
||||
struct Int32
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_INT32;
|
||||
using type = int32_t;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> int32_t
|
||||
{
|
||||
size_t bytes_read;
|
||||
return utils::read_varuint32(value.data(), bytes_read);
|
||||
}
|
||||
};
|
||||
|
||||
struct Uint32
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_UINT32;
|
||||
using type = uint32_t;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> uint32_t
|
||||
{
|
||||
size_t bytes_read;
|
||||
return utils::read_varuint32(value.data(), bytes_read);
|
||||
}
|
||||
};
|
||||
|
||||
struct Int64
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_INT64;
|
||||
using type = int64_t;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> int64_t
|
||||
{
|
||||
size_t bytes_read;
|
||||
return utils::read_varuint64(value.data(), bytes_read);
|
||||
}
|
||||
};
|
||||
|
||||
struct Uint64
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_UINT64;
|
||||
using type = uint64_t;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> uint64_t
|
||||
{
|
||||
size_t bytes_read;
|
||||
return utils::read_varuint64(value.data(), bytes_read);
|
||||
}
|
||||
};
|
||||
|
||||
struct Float
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_FLOAT;
|
||||
using type = float;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> float
|
||||
{
|
||||
return *reinterpret_cast<const float*>(value.data());
|
||||
}
|
||||
};
|
||||
|
||||
struct Double
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_DOUBLE;
|
||||
using type = double;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> double
|
||||
{
|
||||
return *reinterpret_cast<const double*>(value.data());
|
||||
}
|
||||
};
|
||||
|
||||
struct Fixed32
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_FIXED32;
|
||||
using type = int32_t;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> int32_t
|
||||
{
|
||||
return *reinterpret_cast<const int32_t*>(value.data());
|
||||
}
|
||||
};
|
||||
|
||||
struct Fixed64
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_FIXED64;
|
||||
using type = int64_t;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> int64_t
|
||||
{
|
||||
return *reinterpret_cast<const int64_t*>(value.data());
|
||||
}
|
||||
};
|
||||
|
||||
struct Bool
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_BOOL;
|
||||
using type = bool;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> bool
|
||||
{
|
||||
size_t bytes_read;
|
||||
return !!utils::read_varuint32(value.data(), bytes_read);
|
||||
}
|
||||
};
|
||||
|
||||
struct String
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_STRING;
|
||||
using type = std::string;
|
||||
|
||||
static __forceinline auto get(const std::string& value) -> std::string
|
||||
{
|
||||
size_t bytes_read;
|
||||
const auto length = utils::read_varuint32(value.data(), bytes_read);
|
||||
auto result = std::string{ value.data() + bytes_read, length };
|
||||
return std::move(result);
|
||||
}
|
||||
};
|
||||
|
||||
struct Group : String
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_GROUP;
|
||||
};
|
||||
|
||||
struct Message : String
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_MESSAGE;
|
||||
};
|
||||
|
||||
struct Bytes : String
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_BYTES;
|
||||
};
|
||||
|
||||
struct Enum : Int32
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_ENUM;
|
||||
};
|
||||
|
||||
struct Sfixed32 : Fixed32
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_SFIXED32;
|
||||
};
|
||||
|
||||
struct Sfixed64 : Fixed64
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_SFIXED64;
|
||||
};
|
||||
|
||||
struct Sint32
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_SINT32;
|
||||
using type = int32_t;
|
||||
};
|
||||
|
||||
struct Sint64
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_SINT64;
|
||||
using type = int64_t;
|
||||
};
|
||||
}
|
||||
|
||||
namespace base
|
||||
{
|
||||
struct field_vector
|
||||
{
|
||||
using Entry = std::pair<std::string, std::string>;
|
||||
using Field = std::vector<Entry>;
|
||||
using Fields = std::vector<Field>;
|
||||
|
||||
const std::shared_ptr<Fields> fields;
|
||||
const size_t max_size;
|
||||
|
||||
explicit field_vector(const size_t max_size) : fields{ std::make_shared<Fields>() }, max_size{ max_size + 1 }
|
||||
{
|
||||
fields->resize(this->max_size);
|
||||
}
|
||||
|
||||
auto clear(const uint32_t field) const -> void
|
||||
{
|
||||
if (field >= max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
auto& fld = fields->at(field);
|
||||
|
||||
if (!fld.empty())
|
||||
fld.clear();
|
||||
}
|
||||
|
||||
auto has(const uint32_t field, const size_t index = 0) const -> bool
|
||||
{
|
||||
if (field >= max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
auto& fld = fields->at(field);
|
||||
|
||||
return fld.size() > index;
|
||||
}
|
||||
|
||||
auto count(const uint32_t field) const -> size_t
|
||||
{
|
||||
if (field >= max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
auto& fld = fields->at(field);
|
||||
|
||||
return fld.size();
|
||||
}
|
||||
|
||||
auto add(const uint32_t field, const Entry& entry) const -> void
|
||||
{
|
||||
if (field >= max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
fields->at(field).emplace_back(entry);
|
||||
}
|
||||
|
||||
auto set(const uint32_t field, const Entry& entry, const size_t index = 0) const -> void
|
||||
{
|
||||
if (field >= max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
auto& fld = fields->at(field);
|
||||
|
||||
if (index == 0 && fld.empty())
|
||||
{
|
||||
fld.emplace_back(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index >= fld.size())
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
fld.at(index) = entry;
|
||||
}
|
||||
}
|
||||
|
||||
auto get(const uint32_t field, const size_t index = 0) const -> std::string
|
||||
{
|
||||
if (field >= max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
const auto& fld = fields->at(field);
|
||||
|
||||
if (index >= fld.size())
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
return fld.at(index).first;
|
||||
}
|
||||
|
||||
auto get_all(const uint32_t field) const -> std::vector<std::string>
|
||||
{
|
||||
if (field >= max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
const auto& fld = fields->at(field);
|
||||
|
||||
std::vector<std::string> ret;
|
||||
|
||||
for (const auto& v : fld)
|
||||
ret.emplace_back(v.first);
|
||||
|
||||
return std::move(ret);
|
||||
}
|
||||
};
|
||||
|
||||
template <int Field, typename Type>
|
||||
struct header
|
||||
{
|
||||
static constexpr uint32_t field = Field;
|
||||
static constexpr e_field_type type = Type::field_type;
|
||||
static constexpr e_wire_type wire_type = k_wire_type_for_field_type[type];
|
||||
};
|
||||
|
||||
struct msg
|
||||
{
|
||||
static constexpr e_field_type field_type = TYPE_STRING;
|
||||
using type = std::string;
|
||||
virtual ~msg() = default;
|
||||
msg() = delete;
|
||||
|
||||
explicit msg(const size_t max_size) : fv_{ field_vector(max_size) }
|
||||
{
|
||||
}
|
||||
|
||||
auto serialize() const -> std::string
|
||||
{
|
||||
std::string result;
|
||||
for (const auto& f0 : *fv_.fields)
|
||||
for (const auto& f1 : f0)
|
||||
result.append(f1.second);
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
auto parse(const uint8_t* buf, size_t bytes) -> void
|
||||
{
|
||||
if (buf == nullptr)
|
||||
return;
|
||||
|
||||
size_t pos = 0, bytes_read;
|
||||
uint32_t field, wire_type;
|
||||
std::string field_value_bytes, field_full_bytes;
|
||||
|
||||
while (pos < bytes)
|
||||
{
|
||||
std::tie(field, wire_type, field_value_bytes, field_full_bytes) = utils::read_field(buf + pos, bytes_read);
|
||||
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
|
||||
if (field >= fv_.max_size)
|
||||
throw std::runtime_error("field range error");
|
||||
|
||||
fv_.fields->at(field).emplace_back(field_value_bytes, field_full_bytes);
|
||||
pos += bytes_read;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const field_vector fv_;
|
||||
};
|
||||
|
||||
template <int Field, typename Type>
|
||||
struct field
|
||||
{
|
||||
virtual ~field() = default;
|
||||
|
||||
explicit field(const field_vector& fv) : fv_{ fv }
|
||||
{
|
||||
}
|
||||
|
||||
auto clear() const -> void
|
||||
{
|
||||
fv_.clear(hdr.field);
|
||||
}
|
||||
|
||||
auto has(size_t index = 0) const -> bool
|
||||
{
|
||||
return fv_.has(hdr.field, index);
|
||||
}
|
||||
|
||||
auto count() const -> size_t
|
||||
{
|
||||
return fv_.count(hdr.field);
|
||||
}
|
||||
|
||||
protected:
|
||||
static constexpr header<Field, Type> hdr{};
|
||||
const field_vector fv_;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
template <int Field, typename Type, typename S = void>
|
||||
struct pbfield;
|
||||
|
||||
|
||||
template <int Field, typename Type>
|
||||
struct pbfield<Field, Type, typename std::enable_if<!std::is_base_of<base::msg, Type>::value>::type
|
||||
> : base::field<Field, Type>
|
||||
{
|
||||
virtual ~pbfield() = default;
|
||||
|
||||
explicit pbfield(const base::field_vector& fv) : base::field<Field, Type>{ fv }
|
||||
{
|
||||
}
|
||||
|
||||
using type = typename Type::type;
|
||||
|
||||
auto add(type&& value) const -> void
|
||||
{
|
||||
const auto pair = utils::get_field_bytes(hdr.field, hdr.wire_type, value);
|
||||
fv_.add(hdr.field, pair);
|
||||
}
|
||||
|
||||
auto set(type&& value, size_t index = 0) const -> void
|
||||
{
|
||||
const auto pair = utils::get_field_bytes(hdr.field, hdr.wire_type, value);
|
||||
fv_.set(hdr.field, pair, index);
|
||||
}
|
||||
|
||||
auto set(const type& value, size_t index = 0) const -> void
|
||||
{
|
||||
const auto pair = utils::get_field_bytes(hdr.field, hdr.wire_type, value);
|
||||
fv_.set(hdr.field, pair, index);
|
||||
}
|
||||
|
||||
auto set(std::vector<type>&& values) const -> void
|
||||
{
|
||||
fv_.clear(hdr.field);
|
||||
|
||||
for (auto& v : values)
|
||||
{
|
||||
const auto pair = utils::get_field_bytes(hdr.field, hdr.wire_type, v);
|
||||
fv_.add(hdr.field, pair);
|
||||
}
|
||||
}
|
||||
|
||||
auto set(std::vector<type>& values) const -> void
|
||||
{
|
||||
fv_.clear(hdr.field);
|
||||
|
||||
for (auto& v : values)
|
||||
{
|
||||
const auto pair = utils::get_field_bytes(hdr.field, hdr.wire_type, v);
|
||||
fv_.add(hdr.field, pair);
|
||||
}
|
||||
}
|
||||
|
||||
auto get_all() const -> std::vector<type>
|
||||
{
|
||||
const auto values = fv_.get_all(hdr.field);
|
||||
|
||||
std::vector<type> ret;
|
||||
|
||||
for (const auto& v : values)
|
||||
ret.emplace_back(Type::get(v));
|
||||
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
auto get(size_t index = 0) const -> type
|
||||
{
|
||||
const auto value = fv_.get(hdr.field, index);
|
||||
return Type::get(value);
|
||||
}
|
||||
|
||||
private:
|
||||
using base::field<Field, Type>::hdr;
|
||||
using base::field<Field, Type>::fv_;
|
||||
};
|
||||
|
||||
template <int Field, typename Type>
|
||||
struct pbfield<Field, Type, typename std::enable_if<std::is_base_of<base::msg, Type>::value>::type
|
||||
> : base::field<Field, Type>
|
||||
{
|
||||
virtual ~pbfield() = default;
|
||||
|
||||
explicit pbfield(const base::field_vector& fv) : base::field<Field, Type>{ fv }
|
||||
{
|
||||
}
|
||||
|
||||
using type = typename Type::type;
|
||||
|
||||
auto add(const Type& value) const -> void
|
||||
{
|
||||
const auto v = value.serialize();
|
||||
const auto pair = utils::get_field_bytes(hdr.field, hdr.wire_type, v);
|
||||
fv_.add(hdr.field, pair);
|
||||
}
|
||||
|
||||
auto set(const Type& value, size_t index = 0) const -> void
|
||||
{
|
||||
const auto v = value.serialize();
|
||||
const auto pair = utils::get_field_bytes(hdr.field, hdr.wire_type, v);
|
||||
fv_.set(hdr.field, pair, index);
|
||||
}
|
||||
|
||||
auto get_all() const -> std::vector<Type>
|
||||
{
|
||||
const auto values = fv_.get_all(hdr.field);
|
||||
|
||||
std::vector<Type> ret;
|
||||
|
||||
for (const auto& v : values)
|
||||
{
|
||||
const auto s = types::String::get(v);
|
||||
ret.emplace_back(s);
|
||||
}
|
||||
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
auto get(size_t index = 0) const -> Type
|
||||
{
|
||||
const auto value = fv_.get(hdr.field, index);
|
||||
const auto s = types::String::get(value);
|
||||
return std::move(Type(s));
|
||||
}
|
||||
|
||||
private:
|
||||
using base::field<Field, Type>::hdr;
|
||||
using base::field<Field, Type>::fv_;
|
||||
};
|
||||
|
||||
template <size_t MsgSize>
|
||||
struct pbmsg : base::msg
|
||||
{
|
||||
virtual ~pbmsg() = default;
|
||||
|
||||
explicit pbmsg() : msg(MsgSize)
|
||||
{
|
||||
}
|
||||
|
||||
explicit pbmsg(void* buf, size_t bytes) : msg(MsgSize)
|
||||
{
|
||||
parse(reinterpret_cast<const uint8_t*>(buf), bytes);
|
||||
}
|
||||
|
||||
explicit pbmsg(const std::string& buf) : msg(MsgSize)
|
||||
{
|
||||
parse(reinterpret_cast<const uint8_t*>(buf.data()), buf.size());
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,262 @@
|
||||
#include "Protobuffs.hpp"
|
||||
#include "Interfaces.hpp"
|
||||
#include "inventory_changer.h"
|
||||
|
||||
extern Protobuffs ProtoFeatures;
|
||||
#define CAST(cast, address, add) reinterpret_cast<cast>((uint32_t)address + (uint32_t)add)
|
||||
|
||||
void Protobuffs::WritePacket(std::string packet, void* thisPtr, void* oldEBP, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize)
|
||||
{
|
||||
if ((uint32_t)packet.size() <= cubDest - 8)
|
||||
{
|
||||
memcpy((void*)((DWORD)pubDest + 8), (void*)packet.data(), packet.size());
|
||||
*pcubMsgSize = packet.size() + 8;
|
||||
}
|
||||
else if (iff.g_pMemAlloc)
|
||||
{
|
||||
auto memPtr = *CAST(void**, thisPtr, 0x18);
|
||||
auto memPtrSize = *CAST(uint32_t*, thisPtr, 0x1C);
|
||||
auto newSize = (memPtrSize - cubDest) + packet.size() + 8;
|
||||
|
||||
auto memory = iff.g_pMemAlloc->Realloc(memPtr, newSize + 4);
|
||||
|
||||
*CAST(void**, thisPtr, 0x18) = memory;
|
||||
*CAST(uint32_t*, thisPtr, 0x1C) = newSize;
|
||||
*CAST(void**, oldEBP, -0x14) = memory;
|
||||
|
||||
memcpy(CAST(void*, memory, 0x1C), (void*)packet.data(), packet.size());
|
||||
|
||||
*pcubMsgSize = packet.size() + 8;
|
||||
}
|
||||
}
|
||||
|
||||
static bool onceChanger = false;
|
||||
|
||||
void Protobuffs::ReceiveMessage(void* thisPtr, void* oldEBP, uint32_t messageType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize)
|
||||
{
|
||||
if (messageType == k_EMsgGCCStrike15_v2_MatchmakingGC2ClientHello)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Packet == k_EMsgGCCStrike15_v2_MatchmakingGC2ClientHello\n");
|
||||
#endif
|
||||
if (g_Options.profile_active) {
|
||||
|
||||
MatchmakingGC2ClientHello msg((void*)((DWORD)pubDest + 8), *pcubMsgSize - 8);
|
||||
MatchmakingGC2ClientHello::PlayerCommendationInfo commendations;
|
||||
commendations.cmd_friendly().set(g_Options.comfriendly);
|
||||
commendations.cmd_teaching().set(g_Options.comteacher);
|
||||
commendations.cmd_leader().set(g_Options.comleader);
|
||||
msg.commendation().set(commendations);
|
||||
|
||||
msg.player_level().set(g_Options.level);
|
||||
msg.player_cur_xp().set(g_Options.xp);
|
||||
|
||||
if (g_Options.banduration != 0) {
|
||||
msg.penalty_reason().set(g_Options.banreason);
|
||||
msg.penalty_seconds().set(g_Options.banduration);
|
||||
}
|
||||
|
||||
msg.vac_banned().set(g_Options.vacban);
|
||||
|
||||
MatchmakingGC2ClientHello::PlayerRankingInfo ranking;
|
||||
ranking.account_id().set(iff.g_SteamUser->GetSteamID().GetAccountID());
|
||||
ranking.rank_type_id().set(6);
|
||||
ranking.rank_id().set(g_Options.rankz.value->arr[0].rank);
|
||||
ranking.wins().set(g_Options.rankz.value->arr[0].wins);
|
||||
msg.ranking().set(ranking);
|
||||
|
||||
auto packet = msg.serialize();
|
||||
WritePacket(packet, thisPtr, oldEBP, pubDest, cubDest, pcubMsgSize);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("send packet 0 6 rank %d wins %d\n", g_Options.rankz.value->arr[0].rank, g_Options.rankz.value->arr[0].wins);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if (messageType == k_EMsgGCCStrike15_v2_ClientGCRankUpdate)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Packet == k_EMsgGCCStrike15_v2_ClientGCRankUpdate\n");
|
||||
#endif
|
||||
|
||||
if (g_Options.profile_active) {
|
||||
CMsgGCCStrike15_v2_ClientGCRankUpdate msg((void*)((DWORD)pubDest + 8), *pcubMsgSize - 8);
|
||||
|
||||
auto ranking = msg.ranking().get();
|
||||
|
||||
int ranktype = ranking.rank_type_id().get();
|
||||
#ifdef DEBUG
|
||||
printf("ranktype = %d\n", ranktype);
|
||||
#endif
|
||||
int rankcount = 0;
|
||||
if (ranktype == 7) rankcount = 1;
|
||||
if (ranktype == 10) rankcount = 2;
|
||||
|
||||
ranking.rank_id().set(g_Options.rankz.value->arr[rankcount].rank);
|
||||
ranking.wins().set(g_Options.rankz.value->arr[rankcount].wins);
|
||||
|
||||
msg.ranking().set(ranking);
|
||||
|
||||
auto packet = msg.serialize();
|
||||
WritePacket(packet, thisPtr, oldEBP, pubDest, cubDest, pcubMsgSize);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if (messageType == k_EMsgGCClientWelcome)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Packet == k_EMsgGCClientWelcome\n");
|
||||
#endif
|
||||
auto packet = inventory_changer(pubDest, pcubMsgSize);
|
||||
WritePacket(packet, thisPtr, oldEBP, pubDest, cubDest, pcubMsgSize);
|
||||
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf(".GC Receive: %d\n", messageType);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Protobuffs::PreSendMessage(uint32_t& unMsgType, void* pubData, uint32_t& cubData)
|
||||
{
|
||||
uint32_t MessageType = unMsgType & 0x7FFFFFFF;
|
||||
#ifdef DEBUG
|
||||
printf(".GC Sent: %d\n", MessageType);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Protobuffs::SendClientHello()
|
||||
{
|
||||
CMsgClientHello msg;
|
||||
msg.client_session_need().set(1);
|
||||
auto packet = msg.serialize();
|
||||
|
||||
void* ptr = malloc(packet.size() + 8);
|
||||
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
((uint32_t*)ptr)[0] = k_EMsgGCClientHello | ((DWORD)1 << 31);
|
||||
((uint32_t*)ptr)[1] = 0;
|
||||
|
||||
memcpy((void*)((DWORD)ptr + 8), (void*)packet.data(), packet.size());
|
||||
bool result = iff.g_SteamGameCoordinator->GCSendMessage(k_EMsgGCClientHello | ((DWORD)1 << 31), ptr, packet.size() + 8) == k_EGCResultOK;
|
||||
free(ptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Protobuffs::SendMatchmakingClient2GCHello()
|
||||
{
|
||||
ProtoWriter msg(0);
|
||||
auto packet = msg.serialize();
|
||||
void* ptr = malloc(packet.size() + 8);
|
||||
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
((uint32_t*)ptr)[0] = k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello | ((DWORD)1 << 31);
|
||||
((uint32_t*)ptr)[1] = 0;
|
||||
|
||||
memcpy((void*)((DWORD)ptr + 8), (void*)packet.data(), packet.size());
|
||||
bool result = iff.g_SteamGameCoordinator->GCSendMessage(k_EMsgGCCStrike15_v2_MatchmakingClient2GCHello | ((DWORD)1 << 31), ptr, packet.size() + 8) == k_EGCResultOK;
|
||||
free(ptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Protobuffs::SendClientGcRankUpdate()
|
||||
{
|
||||
MatchmakingGC2ClientHello::PlayerRankingInfo rank_wingman;
|
||||
rank_wingman.rank_type_id().set(7);
|
||||
|
||||
CMsgGCCStrike15_v2_ClientGCRankUpdate msg;
|
||||
msg.ranking().set(rank_wingman);
|
||||
|
||||
auto packet = msg.serialize();
|
||||
|
||||
void* ptr = malloc(packet.size() + 8);
|
||||
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
((uint32_t*)ptr)[0] = k_EMsgGCCStrike15_v2_ClientGCRankUpdate | ((DWORD)1 << 31);
|
||||
((uint32_t*)ptr)[1] = 0;
|
||||
|
||||
memcpy((void*)((DWORD)ptr + 8), (void*)packet.data(), packet.size());
|
||||
bool result = iff.g_SteamGameCoordinator->GCSendMessage(k_EMsgGCCStrike15_v2_ClientGCRankUpdate | ((DWORD)1 << 31), ptr, packet.size() + 8) == k_EGCResultOK;
|
||||
free(ptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Protobuffs::EquipWeapon(int weaponid, int classid, int slotid)
|
||||
{
|
||||
CMsgAdjustItemEquippedState msg;
|
||||
msg.item_id().set(START_ITEM_INDEX + weaponid);
|
||||
msg.new_class().set(classid);
|
||||
msg.new_slot().set(slotid);
|
||||
msg.swap().set(true);
|
||||
auto packet = msg.serialize();
|
||||
|
||||
void* ptr = malloc(packet.size() + 8);
|
||||
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
((uint32_t*)ptr)[0] = k_EMsgGCAdjustItemEquippedState | ((DWORD)1 << 31);
|
||||
((uint32_t*)ptr)[1] = 0;
|
||||
|
||||
memcpy((void*)((DWORD)ptr + 8), (void*)packet.data(), packet.size());
|
||||
bool result = iff.g_SteamGameCoordinator->GCSendMessage(k_EMsgGCAdjustItemEquippedState | ((DWORD)1 << 31), ptr, packet.size() + 8) == k_EGCResultOK;
|
||||
free(ptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
VMTHook* ProtoHook = nullptr;
|
||||
Protobuffs ProtoFeatures;
|
||||
|
||||
|
||||
|
||||
EGCResult __fastcall hkGCRetrieveMessage(void* ecx, void*, uint32_t* punMsgType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize)
|
||||
{
|
||||
static auto oGCRetrieveMessage = ProtoHook->GetOriginal<EGCResult(__thiscall*)(void*, uint32_t* punMsgType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize)>(2);
|
||||
|
||||
auto status = oGCRetrieveMessage(ecx, punMsgType, pubDest, cubDest, pcubMsgSize);
|
||||
|
||||
|
||||
if (status == k_EGCResultOK)
|
||||
{
|
||||
void* thisPtr = nullptr;
|
||||
__asm mov thisPtr, ebx;
|
||||
auto oldEBP = *reinterpret_cast<void**>((uint32_t)_AddressOfReturnAddress() - 4);
|
||||
|
||||
uint32_t messageType = *punMsgType & 0x7FFFFFFF;
|
||||
ProtoFeatures.ReceiveMessage(thisPtr, oldEBP, messageType, pubDest, cubDest, pcubMsgSize);
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
EGCResult __fastcall hkGCSendMessage(void* ecx, void*, uint32_t unMsgType, const void* pubData, uint32_t cubData)
|
||||
{
|
||||
static auto oGCSendMessage = ProtoHook->GetOriginal<EGCResult(__thiscall*)(void*, uint32_t unMsgType, const void* pubData, uint32_t cubData)>(0);
|
||||
|
||||
bool sendMessage = ProtoFeatures.PreSendMessage(unMsgType, const_cast<void*>(pubData), cubData);
|
||||
|
||||
if (!sendMessage)
|
||||
return k_EGCResultOK;
|
||||
|
||||
|
||||
return oGCSendMessage(ecx, unMsgType, const_cast<void*>(pubData), cubData);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
#include "VMT.hpp"
|
||||
|
||||
#include "sdk/steam.h"
|
||||
#include "intrin.h"
|
||||
|
||||
extern VMTHook* ProtoHook;
|
||||
|
||||
class Protobuffs
|
||||
{
|
||||
public:
|
||||
static void WritePacket(std::string packet, void* thisPtr, void* oldEBP, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize);
|
||||
void ReceiveMessage(void* thisPtr, void* oldEBP, uint32_t messageType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize);
|
||||
bool PreSendMessage(uint32_t& unMsgType, void* pubData, uint32_t& cubData);
|
||||
bool SendClientHello();
|
||||
bool SendMatchmakingClient2GCHello();
|
||||
bool SendClientGcRankUpdate();
|
||||
bool EquipWeapon(int weaponid, int classid, int slotid);
|
||||
};
|
||||
|
||||
|
||||
extern Protobuffs ProtoFeatures;
|
||||
|
||||
EGCResult __fastcall hkGCRetrieveMessage(void* ecx, void*, uint32_t* punMsgType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize);
|
||||
EGCResult __fastcall hkGCSendMessage(void* ecx, void*, uint32_t unMsgType, const void* pubData, uint32_t cubData);
|
||||
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
RecvVarProxyFn fnSequenceProxyFn = NULL;
|
||||
|
||||
void SetViewModelSequence(const CRecvProxyData* pDataConst, void* pStruct, void* pOut) {
|
||||
|
||||
CRecvProxyData* pData = const_cast<CRecvProxyData*>(pDataConst);
|
||||
|
||||
C_BaseViewModel* pViewModel = (C_BaseViewModel*)pStruct;
|
||||
|
||||
if (pViewModel) {
|
||||
IClientEntity* pOwner = iff.g_pEntityList->GetClientEntityFromHandle(pViewModel->GetOwner());
|
||||
|
||||
if (pOwner && pOwner->GetIndex() == iff.g_pEngineClient->GetLocalPlayer()) {
|
||||
|
||||
|
||||
|
||||
const model_t* pModel = iff.g_pMdlInfo->GetModel(pViewModel->GetModelIndex());
|
||||
const char* szModel = iff.g_pMdlInfo->GetModelName(pModel);
|
||||
|
||||
int m_nSequence = pData->m_Value.m_Int;
|
||||
|
||||
auto model = fnv2::hashRuntime(szModel);
|
||||
|
||||
static int defknifethash = fnv2::hash("models/weapons/v_knife_default_t.mdl");
|
||||
static int defknifecthash = fnv2::hash("models/weapons/v_knife_default_ct.mdl");
|
||||
if (model == defknifethash || model == defknifecthash) model = fnv2::hash(g_Options.weapons.value->arr[0].model);
|
||||
|
||||
for (int i = 2; i < g_Options.models.value->itemcount; i++) {
|
||||
|
||||
if (model == g_Options.models.value->arr[i].vmodel_hash)
|
||||
{
|
||||
if (g_Options.models.value->arr[i].seq_active)
|
||||
m_nSequence = g_Options.models.value->arr[i].seqs[m_nSequence].seq_repl;
|
||||
break;
|
||||
}
|
||||
if (model == fnv2::hash(g_Options.models.value->arr[i].vmodel_orig))
|
||||
{
|
||||
if (g_Options.models.value->arr[i].seq_active)
|
||||
m_nSequence = g_Options.models.value->arr[i].seqs[m_nSequence].seq_repl;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (model) {
|
||||
case fnv2::hash("models/weapons/v_knife_butterfly.mdl"):
|
||||
{
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_DRAW:
|
||||
m_nSequence = random(SEQUENCE_BUTTERFLY_DRAW, SEQUENCE_BUTTERFLY_DRAW2); break;
|
||||
case SEQUENCE_DEFAULT_LOOKAT01:
|
||||
m_nSequence = random(SEQUENCE_BUTTERFLY_LOOKAT01, SEQUENCE_BUTTERFLY_LOOKAT03); break;
|
||||
default:
|
||||
m_nSequence++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case fnv2::hash("models/weapons/v_knife_falchion_advanced.mdl"):
|
||||
{
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_IDLE2:
|
||||
m_nSequence = SEQUENCE_FALCHION_IDLE1; break;
|
||||
case SEQUENCE_DEFAULT_HEAVY_MISS1:
|
||||
m_nSequence = random(SEQUENCE_FALCHION_HEAVY_MISS1, SEQUENCE_FALCHION_HEAVY_MISS1_NOFLIP); break;
|
||||
case SEQUENCE_DEFAULT_LOOKAT01:
|
||||
m_nSequence = random(SEQUENCE_FALCHION_LOOKAT01, SEQUENCE_FALCHION_LOOKAT02); break;
|
||||
case SEQUENCE_DEFAULT_DRAW:
|
||||
case SEQUENCE_DEFAULT_IDLE1:
|
||||
m_nSequence = m_nSequence; break;
|
||||
default:
|
||||
m_nSequence--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case fnv2::hash("models/weapons/v_knife_push.mdl"):
|
||||
{
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_IDLE2:
|
||||
m_nSequence = SEQUENCE_DAGGERS_IDLE1; break;
|
||||
case SEQUENCE_DEFAULT_LIGHT_MISS1:
|
||||
case SEQUENCE_DEFAULT_LIGHT_MISS2:
|
||||
m_nSequence = random(SEQUENCE_DAGGERS_LIGHT_MISS1, SEQUENCE_DAGGERS_LIGHT_MISS5); break;
|
||||
case SEQUENCE_DEFAULT_HEAVY_MISS1:
|
||||
m_nSequence = random(SEQUENCE_DAGGERS_HEAVY_MISS2, SEQUENCE_DAGGERS_HEAVY_MISS1); break;
|
||||
case SEQUENCE_DEFAULT_HEAVY_HIT1:
|
||||
case SEQUENCE_DEFAULT_HEAVY_BACKSTAB:
|
||||
case SEQUENCE_DEFAULT_LOOKAT01:
|
||||
m_nSequence = m_nSequence + 3; break;
|
||||
case SEQUENCE_DEFAULT_DRAW:
|
||||
case SEQUENCE_DEFAULT_IDLE1:
|
||||
m_nSequence = m_nSequence; break;
|
||||
default:
|
||||
m_nSequence = m_nSequence + 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case fnv2::hash("models/weapons/v_knife_survival_bowie.mdl"):
|
||||
{
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_DRAW:
|
||||
case SEQUENCE_DEFAULT_IDLE1:
|
||||
m_nSequence = m_nSequence; break;
|
||||
case SEQUENCE_DEFAULT_IDLE2:
|
||||
m_nSequence = SEQUENCE_BOWIE_IDLE1; break;
|
||||
default:
|
||||
m_nSequence = m_nSequence - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case fnv2::hash("models/weapons/v_knife_ursus.mdl"):
|
||||
case fnv2::hash("models/weapons/v_knife_skeleton.mdl"):
|
||||
case fnv2::hash("models/weapons/v_knife_outdoor.mdl"):
|
||||
case fnv2::hash("models/weapons/v_knife_cord.mdl"):
|
||||
case fnv2::hash("models/weapons/v_knife_canis.mdl"):
|
||||
{
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_DRAW:
|
||||
m_nSequence = random(SEQUENCE_BUTTERFLY_DRAW, SEQUENCE_BUTTERFLY_DRAW2); break;
|
||||
case SEQUENCE_DEFAULT_LOOKAT01:
|
||||
m_nSequence = random(SEQUENCE_BUTTERFLY_LOOKAT01, 14); break;
|
||||
default:
|
||||
m_nSequence = m_nSequence + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case fnv2::hash("models/weapons/v_knife_stiletto.mdl"):
|
||||
{
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_LOOKAT01:
|
||||
m_nSequence = random(12, 13); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case fnv2::hash("models/weapons/v_knife_widowmaker.mdl"):
|
||||
{
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_LOOKAT01:
|
||||
m_nSequence = random(14, 15); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case fnv2::hash("models/weapons/v_fists.mdl"):
|
||||
case fnv2::hash("models/weapons/v_axe.mdl"):
|
||||
case fnv2::hash("models/weapons/v_hammer.mdl"):
|
||||
case fnv2::hash("models/weapons/v_spanner.mdl"):
|
||||
{
|
||||
static int lastpunch = 3;
|
||||
switch (m_nSequence)
|
||||
{
|
||||
case SEQUENCE_DEFAULT_DRAW:
|
||||
m_nSequence = 1; break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 12:
|
||||
m_nSequence = 0; break;
|
||||
default:
|
||||
if (lastpunch == 3) lastpunch = 2; else lastpunch = 3;
|
||||
m_nSequence = lastpunch;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
cout << "activ " << (char*)pViewModel->GetSequenceActivity(m_nSequence);
|
||||
printf(" new seq %d (%s)\n ", m_nSequence, szModel);
|
||||
#endif
|
||||
|
||||
|
||||
pData->m_Value.m_Int = m_nSequence;
|
||||
}
|
||||
}
|
||||
|
||||
fnSequenceProxyFn(pData, pStruct, pOut);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#define IDR_WAVE1 101
|
||||
#define IDR_WAVE2 102
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef ANALOGCODE_H
|
||||
#define ANALOGCODE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "InputEnums.h"
|
||||
|
||||
|
||||
#define JOYSTICK_AXIS_INTERNAL( _joystick, _axis ) ( JOYSTICK_FIRST_AXIS + ((_joystick) * MAX_JOYSTICK_AXES) + (_axis) )
|
||||
#define JOYSTICK_AXIS( _joystick, _axis ) ( (AnalogCode_t)JOYSTICK_AXIS_INTERNAL( _joystick, _axis ) )
|
||||
|
||||
|
||||
enum AnalogCode_t
|
||||
{
|
||||
ANALOG_CODE_INVALID = -1,
|
||||
MOUSE_X = 0,
|
||||
MOUSE_Y,
|
||||
MOUSE_XY,
|
||||
MOUSE_WHEEL,
|
||||
|
||||
JOYSTICK_FIRST_AXIS,
|
||||
JOYSTICK_LAST_AXIS = JOYSTICK_AXIS_INTERNAL(MAX_JOYSTICKS - 1, MAX_JOYSTICK_AXES - 1),
|
||||
|
||||
ANALOG_CODE_LAST,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/imgui_internal.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern ImFont* ifontmini;
|
||||
extern ImFont* ifont;
|
||||
|
||||
|
||||
|
||||
namespace ImGui {
|
||||
|
||||
bool identical(const char* buf, const char* item) {
|
||||
size_t buf_size = strlen(buf);
|
||||
size_t item_size = strlen(item);
|
||||
if (buf_size >= item_size) return false;
|
||||
for (int i = 0; i < strlen(buf); ++i)
|
||||
if (buf[i] != item[i]) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
int propose(ImGuiInputTextCallbackData* data) {
|
||||
if (strlen(data->Buf) == 0) return 0;
|
||||
|
||||
const char** items = static_cast<std::pair<const char**, size_t>*> (data->UserData)->first;
|
||||
size_t length = static_cast<std::pair<const char**, size_t>*> (data->UserData)->second;
|
||||
|
||||
if (IsKeyPressedMap(ImGuiKey_Backspace)) {
|
||||
if (data->SelectionEnd != data->SelectionStart)
|
||||
if (data->BufTextLen > 0)
|
||||
if (data->CursorPos > 0)
|
||||
data->DeleteChars(data->CursorPos - 1, 1);
|
||||
return 0;
|
||||
}
|
||||
if (IsKeyPressedMap(ImGuiKey_Delete)) return 0;
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (identical(data->Buf, items[i])) {
|
||||
const int cursor = data->CursorPos;
|
||||
data->DeleteChars(0, data->BufTextLen);
|
||||
data->InsertChars(0, items[i]);
|
||||
data->CursorPos = cursor;
|
||||
data->SelectionStart = cursor;
|
||||
data->SelectionEnd = data->BufTextLen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool TextInputComboBox(const char* id, char* buffer, size_t maxInputSize, const char* items[], size_t item_len, short showMaxItems) {
|
||||
if (showMaxItems == 0)
|
||||
showMaxItems = item_len;
|
||||
|
||||
ImGui::PushID(id);
|
||||
std::pair<const char**, size_t> pass(items, item_len);
|
||||
|
||||
bool ret = ImGui::InputText("##in", buffer, maxInputSize, 0, 0, 0);
|
||||
|
||||
ImGui::OpenPopupOnItemClick("combobox");
|
||||
ImVec2 pos = ImGui::GetItemRectMin();
|
||||
ImVec2 size = ImGui::GetItemRectSize();
|
||||
|
||||
ImGui::SameLine(0, 0);
|
||||
if (ImGui::ArrowButton("##openCombo", ImGuiDir_Down)) {
|
||||
ImGui::OpenPopup("combobox");
|
||||
}
|
||||
ImGui::OpenPopupOnItemClick("combobox");
|
||||
|
||||
pos.y += size.y;
|
||||
size.x += ImGui::GetItemRectSize().x;
|
||||
size.y += 5 + (size.y * showMaxItems);
|
||||
ImGui::SetNextWindowPos(pos);
|
||||
ImGui::SetNextWindowSize(size);
|
||||
|
||||
ImGuiStyle* style = &ImGui::GetStyle();
|
||||
ImGui::PushFont(ifontmini);
|
||||
style->ItemSpacing = ImVec2(7.0f, 2.0f);
|
||||
style->WindowPadding = ImVec2(5.0f, 5.0f);
|
||||
|
||||
if (ImGui::BeginPopup("combobox", ImGuiWindowFlags_::ImGuiWindowFlags_NoMove)) {
|
||||
|
||||
|
||||
for (int i = 0; i < item_len; i++)
|
||||
if (ImGui::Selectable(items[i]))
|
||||
strcpy(buffer, items[i]);
|
||||
|
||||
|
||||
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
style->WindowPadding = ImVec2(20.f, 20.0f);
|
||||
style->ItemSpacing = ImVec2(7.0f, 15.0f);
|
||||
ImGui::PushFont(ifont);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool TextInputComboBox(const char* id, char* buffer, size_t maxInputSize, std::vector<std::string> items, short showMaxItems) {
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(id, NULL, true);
|
||||
if (label_size.x > 0) {
|
||||
ImVec2 savecursor = ImGui::GetCursorPos();
|
||||
ImVec2 newcursor = savecursor;
|
||||
savecursor.y += 20.0f;
|
||||
ImGui::SetCursorPos(newcursor);
|
||||
ImGui::TextEx(id);
|
||||
ImGui::SetCursorPos(savecursor);
|
||||
}
|
||||
|
||||
size_t item_len = items.size();
|
||||
|
||||
if (showMaxItems == 0)
|
||||
showMaxItems = item_len;
|
||||
|
||||
ImGui::PushID(id);
|
||||
std::pair<std::vector<std::string>, size_t> pass(items, item_len);
|
||||
|
||||
ImGuiStyle* style = &ImGui::GetStyle();
|
||||
|
||||
const ImVec2 frame_size = CalcItemSize(ImVec2(0, 0), CalcItemWidth(), label_size.y + style->FramePadding.y * 2.0f);
|
||||
|
||||
ImGui::SetNextItemWidth(frame_size.x - 19.0f);
|
||||
|
||||
bool ret = ImGui::InputText("##in", buffer, maxInputSize, 0, 0, 0);
|
||||
|
||||
ImGui::OpenPopupOnItemClick("combobox");
|
||||
ImVec2 pos = ImGui::GetItemRectMin();
|
||||
ImVec2 size = ImGui::GetItemRectSize();
|
||||
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 5.0f);
|
||||
if (ImGui::ArrowButton("##openCombo", ImGuiDir_Down)) {
|
||||
ImGui::OpenPopup("combobox");
|
||||
}
|
||||
ImGui::OpenPopupOnItemClick("combobox");
|
||||
|
||||
pos.y += size.y;
|
||||
|
||||
|
||||
ImGui::SetNextWindowPos(pos);
|
||||
size.x += 15.0f;
|
||||
ImGui::SetNextWindowSizeConstraints(size, ImVec2(400.0f, 200.0f));
|
||||
|
||||
ImGui::PushFont(ifontmini);
|
||||
style->ItemSpacing = ImVec2(7.0f, 2.0f);
|
||||
style->WindowPadding = ImVec2(5.0f, 5.0f);
|
||||
|
||||
if (ImGui::BeginPopup("combobox", ImGuiWindowFlags_::ImGuiWindowFlags_NoMove)) {
|
||||
|
||||
for (int i = 0; i < item_len; i++)
|
||||
if (ImGui::Selectable(items[i].c_str()))
|
||||
strcpy(buffer, items[i].c_str());
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
style->WindowPadding = ImVec2(20.f, 20.0f);
|
||||
style->ItemSpacing = ImVec2(7.0f, 15.0f);
|
||||
ImGui::PushFont(ifont);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "Interfaces.hpp"
|
||||
using proc_t = void(*)();
|
||||
|
||||
class vmt_base_hook
|
||||
{
|
||||
protected:
|
||||
constexpr vmt_base_hook() = default;
|
||||
|
||||
public:
|
||||
~vmt_base_hook()
|
||||
{
|
||||
if (m_new_vmt)
|
||||
delete[](m_new_vmt - 1);
|
||||
}
|
||||
|
||||
vmt_base_hook(const vmt_base_hook&) = delete;
|
||||
vmt_base_hook(vmt_base_hook&&) = delete;
|
||||
|
||||
vmt_base_hook& operator=(const vmt_base_hook&) = delete;
|
||||
vmt_base_hook& operator=(vmt_base_hook&&) = delete;
|
||||
|
||||
protected:
|
||||
auto initialize(proc_t* original_table) -> void
|
||||
{
|
||||
m_old_vmt = original_table;
|
||||
|
||||
size_t size = 0;
|
||||
while (m_old_vmt[size] && is_code_ptr(m_old_vmt[size]))
|
||||
++size;
|
||||
|
||||
m_new_vmt = (new proc_t[size + 1]) + 1;
|
||||
memcpy(m_new_vmt - 1, m_old_vmt - 1, sizeof(void*) * (size + 1));
|
||||
}
|
||||
|
||||
constexpr auto leak_table() -> void
|
||||
{
|
||||
m_new_vmt = nullptr;
|
||||
}
|
||||
|
||||
auto hook_instance(void* inst) const -> void
|
||||
{
|
||||
auto& vtbl = *reinterpret_cast<proc_t**>(inst);
|
||||
assert(vtbl == m_old_vmt || vtbl == m_new_vmt);
|
||||
vtbl = m_new_vmt;
|
||||
}
|
||||
|
||||
auto unhook_instance(void* inst) const -> void
|
||||
{
|
||||
auto& vtbl = *reinterpret_cast<proc_t**>(inst);
|
||||
assert(vtbl == m_old_vmt || vtbl == m_new_vmt);
|
||||
vtbl = m_old_vmt;
|
||||
}
|
||||
|
||||
auto initialize_and_hook_instance(void* inst) -> bool
|
||||
{
|
||||
auto& vtbl = *reinterpret_cast<proc_t**>(inst);
|
||||
auto initialized = false;
|
||||
if (!m_old_vmt)
|
||||
{
|
||||
initialized = true;
|
||||
initialize(vtbl);
|
||||
}
|
||||
hook_instance(inst);
|
||||
return initialized;
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
auto hook_function(Fn hooked_fn, const std::size_t index) -> Fn
|
||||
{
|
||||
m_new_vmt[index] = (proc_t)(hooked_fn);
|
||||
return (Fn)(m_old_vmt[index]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto apply_hook(std::size_t idx) -> void
|
||||
{
|
||||
T::m_original = hook_function(&T::hooked, idx);
|
||||
}
|
||||
|
||||
template <typename Fn = uintptr_t>
|
||||
auto get_original_function(const int index) -> Fn
|
||||
{
|
||||
return (Fn)(m_old_vmt[index]);
|
||||
}
|
||||
|
||||
private:
|
||||
proc_t* m_new_vmt = nullptr;
|
||||
proc_t* m_old_vmt = nullptr;
|
||||
};
|
||||
|
||||
class vmt_smart_hook : vmt_base_hook
|
||||
{
|
||||
public:
|
||||
vmt_smart_hook(void* class_base)
|
||||
: m_class{ class_base }
|
||||
{
|
||||
initialize_and_hook_instance(class_base);
|
||||
}
|
||||
|
||||
~vmt_smart_hook()
|
||||
{
|
||||
unhook_instance(m_class);
|
||||
}
|
||||
|
||||
vmt_smart_hook(const vmt_smart_hook&) = delete;
|
||||
vmt_smart_hook(vmt_smart_hook&&) = delete;
|
||||
|
||||
vmt_smart_hook& operator=(const vmt_smart_hook&) = delete;
|
||||
vmt_smart_hook& operator=(vmt_smart_hook&&) = delete;
|
||||
|
||||
auto rehook() const -> void
|
||||
{
|
||||
hook_instance(m_class);
|
||||
}
|
||||
|
||||
auto unhook() const -> void
|
||||
{
|
||||
unhook_instance(m_class);
|
||||
}
|
||||
|
||||
using vmt_base_hook::apply_hook;
|
||||
using vmt_base_hook::get_original_function;
|
||||
using vmt_base_hook::hook_function;
|
||||
|
||||
private:
|
||||
void* m_class = nullptr;
|
||||
};
|
||||
|
||||
class vmt_multi_hook : vmt_base_hook
|
||||
{
|
||||
public:
|
||||
constexpr vmt_multi_hook() = default;
|
||||
|
||||
~vmt_multi_hook()
|
||||
{
|
||||
leak_table();
|
||||
}
|
||||
|
||||
vmt_multi_hook(const vmt_multi_hook&) = delete;
|
||||
vmt_multi_hook(vmt_multi_hook&&) = delete;
|
||||
|
||||
vmt_multi_hook& operator=(const vmt_multi_hook&) = delete;
|
||||
vmt_multi_hook& operator=(vmt_multi_hook&&) = delete;
|
||||
|
||||
using vmt_base_hook::apply_hook;
|
||||
using vmt_base_hook::get_original_function;
|
||||
using vmt_base_hook::hook_function;
|
||||
using vmt_base_hook::hook_instance;
|
||||
using vmt_base_hook::unhook_instance;
|
||||
using vmt_base_hook::initialize;
|
||||
using vmt_base_hook::initialize_and_hook_instance;
|
||||
};
|
||||
@@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct vpk_header_t
|
||||
{
|
||||
uint32_t signature;
|
||||
uint32_t version;
|
||||
uint32_t tree_size;
|
||||
uint32_t file_data_section_size;
|
||||
uint32_t archive_md5_section_size;
|
||||
uint32_t other_md5_section_size;
|
||||
uint32_t signature_section_size;
|
||||
};
|
||||
|
||||
struct dir_entry_t
|
||||
{
|
||||
uint32_t crc;
|
||||
uint16_t preload_bytes;
|
||||
uint16_t archive_index;
|
||||
uint32_t entry_offset;
|
||||
uint32_t entry_length;
|
||||
uint16_t terminator;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class c_vpk_entry
|
||||
{
|
||||
public:
|
||||
c_vpk_entry() = default;
|
||||
c_vpk_entry(const std::string& base_file, const std::string& path, const dir_entry_t& entry) :_base_file(base_file), _path(path), _entry(entry) {}
|
||||
|
||||
std::optional<std::vector<uint8_t>> get_data()
|
||||
{
|
||||
size_t _dir_pos = _base_file.find("dir");
|
||||
|
||||
std::string old_number_string = std::to_string(_entry.archive_index);
|
||||
std::string vpk_file = _base_file.replace(_base_file.begin() + _dir_pos, _base_file.begin() + _dir_pos + 3, std::string(3 - old_number_string.length(), '0') + old_number_string);
|
||||
std::ifstream stream(vpk_file, std::ios::binary);
|
||||
if (!stream.is_open())
|
||||
return {};
|
||||
|
||||
uint8_t* data = new uint8_t[_entry.entry_length];
|
||||
stream.seekg(_entry.entry_offset, stream.beg);
|
||||
stream.read((char*)data, _entry.entry_length);
|
||||
stream.close();
|
||||
|
||||
std::vector<uint8_t> data_vector(data, data + _entry.entry_length);
|
||||
delete[] data;
|
||||
|
||||
return data_vector;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> preload_bytes = {};
|
||||
std::string _base_file = {};
|
||||
std::string _path = {};
|
||||
dir_entry_t _entry = {};
|
||||
};
|
||||
|
||||
class c_vpk_archive
|
||||
{
|
||||
public:
|
||||
bool load(const std::string& name)
|
||||
{
|
||||
std::ifstream stream(name, std::ios::binary);
|
||||
if (!stream.is_open())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
vpk_header_t file_header = {};
|
||||
stream.read((char*)&file_header, sizeof(file_header));
|
||||
if (file_header.signature != 0x55aa1234)
|
||||
{
|
||||
stream.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file_header.version != 2)
|
||||
{
|
||||
stream.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::string extension;
|
||||
|
||||
std::getline(stream, extension, '\x00');
|
||||
if (extension.empty())
|
||||
break;
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::string directory;
|
||||
std::getline(stream, directory, '\x00');
|
||||
if (directory.empty())
|
||||
break;
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::string file_name;
|
||||
std::getline(stream, file_name, '\x00');
|
||||
if (file_name.empty())
|
||||
break;
|
||||
|
||||
std::string path = directory + '/' + file_name + '.' + extension;
|
||||
|
||||
dir_entry_t dir_entry;
|
||||
stream.read((char*)&dir_entry, sizeof(dir_entry));
|
||||
|
||||
c_vpk_entry vpk_entry(name, path, dir_entry);
|
||||
if (dir_entry.preload_bytes)
|
||||
{
|
||||
uint8_t* bytes = new uint8_t[dir_entry.preload_bytes];
|
||||
stream.read((char*)bytes, dir_entry.preload_bytes);
|
||||
vpk_entry.preload_bytes = std::vector<uint8_t>(bytes, bytes + dir_entry.preload_bytes);
|
||||
delete[] bytes;
|
||||
}
|
||||
|
||||
if (!files.count(path))
|
||||
files[path] = vpk_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) { return false; }
|
||||
stream.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<c_vpk_entry> get_file(const std::string& name)
|
||||
{
|
||||
if (files.count(name))
|
||||
return files[name];
|
||||
|
||||
return {};
|
||||
}
|
||||
std::unordered_map<std::string, c_vpk_entry> files = {};
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
#ifndef ZIP_UNCOMPRESSED_H
|
||||
#define ZIP_UNCOMPRESSED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "datamap.h"
|
||||
|
||||
#define PKID( a, b ) (((b)<<24)|((a)<<16)|('K'<<8)|'P')
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct ZIP_EndOfCentralDirRecord
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
unsigned int signature;
|
||||
unsigned short numberOfThisDisk;
|
||||
unsigned short numberOfTheDiskWithStartOfCentralDirectory;
|
||||
unsigned short nCentralDirectoryEntries_ThisDisk;
|
||||
unsigned short nCentralDirectoryEntries_Total;
|
||||
unsigned int centralDirectorySize;
|
||||
unsigned int startOfCentralDirOffset;
|
||||
unsigned short commentLength;
|
||||
};
|
||||
|
||||
struct ZIP_FileHeader
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
unsigned int signature;
|
||||
unsigned short versionMadeBy;
|
||||
unsigned short versionNeededToExtract;
|
||||
unsigned short flags;
|
||||
unsigned short compressionMethod;
|
||||
unsigned short lastModifiedTime;
|
||||
unsigned short lastModifiedDate;
|
||||
unsigned int crc32;
|
||||
unsigned int compressedSize;
|
||||
unsigned int uncompressedSize;
|
||||
unsigned short fileNameLength;
|
||||
unsigned short extraFieldLength;
|
||||
unsigned short fileCommentLength;
|
||||
unsigned short diskNumberStart;
|
||||
unsigned short internalFileAttribs;
|
||||
unsigned int externalFileAttribs;
|
||||
unsigned int relativeOffsetOfLocalHeader;
|
||||
};
|
||||
|
||||
struct ZIP_LocalFileHeader
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
unsigned int signature;
|
||||
unsigned short versionNeededToExtract;
|
||||
unsigned short flags;
|
||||
unsigned short compressionMethod;
|
||||
unsigned short lastModifiedTime;
|
||||
unsigned short lastModifiedDate;
|
||||
unsigned int crc32;
|
||||
unsigned int compressedSize;
|
||||
unsigned int uncompressedSize;
|
||||
unsigned short fileNameLength;
|
||||
unsigned short extraFieldLength;
|
||||
};
|
||||
|
||||
#define PRELOAD_SECTION_NAME "__preload_section.pre"
|
||||
#define PRELOAD_HDR_VERSION 3
|
||||
#define XZIP_COMMENT_LENGTH 32
|
||||
#define INVALID_PRELOAD_ENTRY ( (unsigned short)-1 )
|
||||
|
||||
struct ZIP_PreloadHeader
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
unsigned int Version;
|
||||
unsigned int DirectoryEntries;
|
||||
unsigned int PreloadDirectoryEntries;
|
||||
unsigned int Alignment;
|
||||
};
|
||||
|
||||
struct ZIP_PreloadDirectoryEntry
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
unsigned int Length;
|
||||
unsigned int DataOffset;
|
||||
};
|
||||
|
||||
struct ZIP_PreloadRemapTable
|
||||
{
|
||||
DECLARE_BYTESWAP_DATADESC();
|
||||
unsigned short PreloadIndex;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user