Merge branch 'master' of https://github.com/nullifiedcat/cathook/
Conflicts: banner.png
This commit is contained in:
commit
7561bd47c9
44
README.md
44
README.md
@ -1,12 +1,15 @@
|
|||||||
# Cathook Multihack
|
# Cathook Training Software
|
||||||

|

|
||||||
|
|
||||||
cathook is a multihack for Team Fortress 2 for Linux. cathook includes some joke features like
|
## Discord Server
|
||||||
|
[Official Discord Server](https://discord.gg/kvNVNSX)
|
||||||
|
|
||||||
|
cathook is a training software designed for Team Fortress 2 for Linux. cathook includes some joke features like
|
||||||
|
|
||||||
* Backpack.TF API integration with playerlist GUI, allowing you to see players' inventory values
|
* Backpack.TF API integration with playerlist GUI, allowing you to see players' inventory values
|
||||||
* Always/Never spycrab
|
* Always/Never spycrab
|
||||||
* Ignore Hoovy
|
* Ignore Hoovy
|
||||||
* 100% Casual/Comp coin flip hack
|
* 100% Casual/Comp coin flip
|
||||||
* Encrypted chat
|
* Encrypted chat
|
||||||
* Emoji ESP
|
* Emoji ESP
|
||||||
* Fidget Spinner crosshair
|
* Fidget Spinner crosshair
|
||||||
@ -14,29 +17,50 @@ cathook is a multihack for Team Fortress 2 for Linux. cathook includes some joke
|
|||||||
and a lot of useful features, including
|
and a lot of useful features, including
|
||||||
|
|
||||||
* Anti Backstab with option to say "No" voice command when spy tries to backstab you
|
* Anti Backstab with option to say "No" voice command when spy tries to backstab you
|
||||||
* Heal Arrows hack (overheal an enemy for 1200 health with single huntsman arrow, you can also do it with buildings!)
|
* Heal Arrows exploit (overheal an enemy for 1200 health with single huntsman arrow, you can also do it with buildings!)
|
||||||
* Extremely customizable spam (you can make spam lines that'll include name of random dead enemy pyro or sniper)
|
* Extremely customizable spam (you can make spam lines that'll include name of random dead enemy pyro or sniper)
|
||||||
* Follow Bots
|
* Follow Bots
|
||||||
* Working crit hack
|
* Working crit hack
|
||||||
|
|
||||||
[FULL LIST OF FEATURES HERE](https://github.com/nullifiedcat/cathook/wiki/List-of-features)
|
[FULL LIST OF FEATURES HERE](https://github.com/nullifiedcat/cathook/wiki/List-of-features)
|
||||||
|
|
||||||
# Discord Server
|
|
||||||
[Official Discord Server](https://discord.gg/kvNVNSX)
|
|
||||||
|
|
||||||
# INSTALLATION
|
# INSTALLATION
|
||||||
|
|
||||||
Ubuntu dependencies installation:
|
You **have** to use gcc6, not 7 or 5!
|
||||||
|
|
||||||
|
You also have to have g++-6-multilib package.
|
||||||
|
|
||||||
|
Ubuntu gcc6 installation: (check if you have gcc-6 installed already by typing `gcc-6 -v`
|
||||||
```bash
|
```bash
|
||||||
sudo apt update && sudo apt install build-essential software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-snapshot -y && sudo apt update && sudo apt install git libc6-dev gcc-6 g++-6 libc6-dev:i386 g++-6-multilib gdb libsdl2-dev libglew-dev libfreetype6-dev libfreetype6-dev:i386 -y
|
sudo apt update && sudo apt install build-essential software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-snapshot g++-6-multilib gcc-6 g++-6 -y
|
||||||
|
```
|
||||||
|
|
||||||
|
Ubuntu other dependencies installation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update && sudo apt install git libssl-dev:i386 libc6-dev:i386 gdb libsdl2-dev libglew-dev:i386 libfreetype6-dev:i386 -y
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Arch dependencies installation::
|
Arch gcc6 & dependencies installation:
|
||||||
```bash
|
```bash
|
||||||
sudo pacman -Syu && sudo pacman -S gdb gdb-common glew1.10 lib32-glew1.10 rsync --noconfirm && yes | sudo pacman -U https://archive.archlinux.org/packages/g/gcc-multilib/gcc-multilib-6.3.1-2-x86_64.pkg.tar.xz https://archive.archlinux.org/packages/g/gcc-libs-multilib/gcc-libs-multilib-6.3.1-2-x86_64.pkg.tar.xz https://archive.archlinux.org/packages/l/lib32-gcc-libs/lib32-gcc-libs-6.3.1-2-x86_64.pkg.tar.xz
|
sudo pacman -Syu && sudo pacman -S gdb gdb-common glew1.10 lib32-glew1.10 rsync --noconfirm && yes | sudo pacman -U https://archive.archlinux.org/packages/g/gcc-multilib/gcc-multilib-6.3.1-2-x86_64.pkg.tar.xz https://archive.archlinux.org/packages/g/gcc-libs-multilib/gcc-libs-multilib-6.3.1-2-x86_64.pkg.tar.xz https://archive.archlinux.org/packages/l/lib32-gcc-libs/lib32-gcc-libs-6.3.1-2-x86_64.pkg.tar.xz
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you don't use Ubuntu or Arch (or if Arch script gets outdated), here's the list of what cathook requires:
|
||||||
|
|
||||||
|
* `gcc-6`
|
||||||
|
* `g++-6`
|
||||||
|
* `gcc-6-multilib`
|
||||||
|
* `g++-6-multilib`
|
||||||
|
* `gdb` (for the injection script, you can use different injector if you want)
|
||||||
|
* `libssl-dev:i386`
|
||||||
|
* `libc6-dev:i386`
|
||||||
|
* `libsdl2-dev`
|
||||||
|
* `libglew-dev:i386`
|
||||||
|
* `libfreetype6-dev:i386`
|
||||||
|
* `rsync` (only for copying shaders/fonts to tf2 data directory, `update-data` script)
|
||||||
|
|
||||||
|
|
||||||
Cathook installation script:
|
Cathook installation script:
|
||||||
```bash
|
```bash
|
||||||
|
BIN
banner.png
BIN
banner.png
Binary file not shown.
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
2
makefile
2
makefile
@ -52,7 +52,7 @@ ifndef CLANG
|
|||||||
LDFLAGS+=-flto
|
LDFLAGS+=-flto
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
LDLIBS=-l:libSDL2-2.0.so.0 -static -l:libc.so.6 -static -l:libstdc++.so.6 -l:libtier0.so -l:libvstdlib.so -static -l:libGLEW.so -l:libfreetype.so
|
LDLIBS=-lssl -l:libSDL2-2.0.so.0 -static -l:libc.so.6 -static -l:libstdc++.so.6 -l:libtier0.so -l:libvstdlib.so -static -l:libGLEW.so -l:libfreetype.so
|
||||||
SRC_DIR = src
|
SRC_DIR = src
|
||||||
RES_DIR = res
|
RES_DIR = res
|
||||||
OUT_NAME = libcathook.so
|
OUT_NAME = libcathook.so
|
||||||
|
176
src/backpacktf.cpp
Normal file
176
src/backpacktf.cpp
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* backpacktf.cpp
|
||||||
|
*
|
||||||
|
* Created on: Jul 23, 2017
|
||||||
|
* Author: nullifiedcat
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backpacktf.hpp"
|
||||||
|
#include "json.hpp"
|
||||||
|
#include "https_request.hpp"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "cvwrapper.h"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
namespace backpacktf {
|
||||||
|
|
||||||
|
std::unordered_map<unsigned, backpack_data_s> cache {};
|
||||||
|
std::queue<backpack_data_s*> pending_queue {};
|
||||||
|
std::mutex queue_mutex {};
|
||||||
|
std::mutex cache_mutex {};
|
||||||
|
|
||||||
|
std::string api_key_s = "";
|
||||||
|
bool valid_api_key = false;
|
||||||
|
|
||||||
|
CatVar enable_bptf(CV_SWITCH, "bptf_enable", "0", "Enable backpack.tf", "Enable backpack.tf integration\nYou have to set your API key in cat_bptf_key");
|
||||||
|
CatCommand api_key("bptf_key", "Set API Key", [](const CCommand& args) {
|
||||||
|
api_key_s = args.ArgS();
|
||||||
|
logging::Info("API key changed!");
|
||||||
|
valid_api_key = false;
|
||||||
|
if (api_key_s.length() != 24) {
|
||||||
|
logging::Info("API key must be exactly 24 characters long");
|
||||||
|
valid_api_key = false;
|
||||||
|
} else {
|
||||||
|
valid_api_key = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
void store_data(unsigned id, float value, bool no_value, bool outdated_value);
|
||||||
|
|
||||||
|
void processing_thread() {
|
||||||
|
logging::Info("[bp.tf] Starting the thread");
|
||||||
|
while (true) {
|
||||||
|
if (enabled()) {
|
||||||
|
try {
|
||||||
|
std::vector<backpack_data_s*> batch {};
|
||||||
|
int count = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(queue_mutex);
|
||||||
|
while (not pending_queue.empty() && ++count < 100) {
|
||||||
|
batch.push_back(pending_queue.front());
|
||||||
|
pending_queue.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count) {
|
||||||
|
logging::Info("[bp.tf] Requesting data for %d users", count);
|
||||||
|
std::string id_list = "";
|
||||||
|
for (const auto& x : batch) {
|
||||||
|
x->pending = false;
|
||||||
|
id_list += format("[U:1:", x->id, "],");
|
||||||
|
}
|
||||||
|
// Remove trailing ','
|
||||||
|
id_list = id_list.substr(0, id_list.length() - 1);
|
||||||
|
std::string query = format("steamids=", id_list, "&key=", api_key_s);
|
||||||
|
try {
|
||||||
|
auto sock = https::RAII_HTTPS_Socket("backpack.tf");
|
||||||
|
std::string response = sock.get("/api/users/info/v1?" + query);
|
||||||
|
if (response.find("HTTP/1.1 200 OK\r\n") != 0) {
|
||||||
|
size_t status = response.find("\r\n");
|
||||||
|
throw std::runtime_error("Response isn't 200 OK! It's " + response.substr(0, status));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string body = response.substr(response.find("\r\n\r\n") + 4);
|
||||||
|
|
||||||
|
try {
|
||||||
|
nlohmann::json data = nlohmann::json::parse(body);
|
||||||
|
nlohmann::json users = data["users"];
|
||||||
|
std::lock_guard<std::mutex> lock(cache_mutex);
|
||||||
|
for (auto it = users.begin(); it != users.end(); ++it) {
|
||||||
|
unsigned userid = strtoul(it.key().substr(5).c_str(), nullptr, 10);
|
||||||
|
try {
|
||||||
|
unsigned userid = strtoul(it.key().substr(5).c_str(), nullptr, 10);
|
||||||
|
const auto& v = it.value();
|
||||||
|
if (not v.is_object()) {
|
||||||
|
logging::Info("Data for %u (%s) is not an object!", userid, it.key());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string name = v.at("name");
|
||||||
|
logging::Info("Parsing data for user %u (%s)", userid, name.c_str());
|
||||||
|
if (v.find("inventory") == v.end()) {
|
||||||
|
store_data(userid, 0, true, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto& inv = v.at("inventory").at("440");
|
||||||
|
if (inv.find("value") == inv.end()) {
|
||||||
|
store_data(userid, 0, true, false);
|
||||||
|
} else {
|
||||||
|
float value = float(inv["value"]);
|
||||||
|
unsigned updated = unsigned(inv["updated"]);
|
||||||
|
store_data(userid, value * REFINED_METAL_PRICE, false, (unsigned(time(0)) - updated > OUTDATED_AGE));
|
||||||
|
}
|
||||||
|
} catch (std::exception& ex) {
|
||||||
|
logging::Info("Error while parsing user %s: %s", it.key().c_str(), ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
logging::Info("[bp.tf] Exception while parsing response: %s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
logging::Info("[bp.tf] HTTPS exception: %s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
logging::Info("[bp.tf] Thread exception: %s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleep(REQUEST_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void request_data(unsigned id) {
|
||||||
|
if (cache[id].pending) return;
|
||||||
|
cache[id].pending = true;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(queue_mutex);
|
||||||
|
pending_queue.push(&cache[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enabled() {
|
||||||
|
return enable_bptf && valid_api_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
backpack_data_s& access_data(unsigned id) {
|
||||||
|
try {
|
||||||
|
return cache.at(id);
|
||||||
|
} catch (std::out_of_range& oor) {
|
||||||
|
cache.emplace(id, backpack_data_s {});
|
||||||
|
cache.at(id).id = id;
|
||||||
|
return cache.at(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void store_data(unsigned id, float value, bool none, bool outdated) {
|
||||||
|
auto& d = access_data(id);
|
||||||
|
d.last_request = unsigned(time(0));
|
||||||
|
d.bad = false;
|
||||||
|
d.value = value;
|
||||||
|
d.no_value = none;
|
||||||
|
d.outdated_value = outdated;
|
||||||
|
d.pending = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const backpack_data_s& get_data(unsigned id) {
|
||||||
|
auto& d = access_data(id);
|
||||||
|
if (d.bad || ((unsigned)time(0) - MAX_CACHE_AGE > cache[id].last_request)) {
|
||||||
|
request_data(id);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread& GetBackpackTFThread() {
|
||||||
|
static std::thread thread(processing_thread);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
GetBackpackTFThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
src/backpacktf.hpp
Normal file
35
src/backpacktf.hpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* backpacktf.hpp
|
||||||
|
*
|
||||||
|
* Created on: Jul 23, 2017
|
||||||
|
* Author: nullifiedcat
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CatVar;
|
||||||
|
|
||||||
|
namespace backpacktf {
|
||||||
|
|
||||||
|
constexpr float REFINED_METAL_PRICE = 0.075f; // $
|
||||||
|
constexpr unsigned REQUEST_INTERVAL = 10; // Make a backpack.tf request every 30 seconds
|
||||||
|
constexpr unsigned MAX_CACHE_AGE = 60 * 30;
|
||||||
|
constexpr unsigned OUTDATED_AGE = 60 * 60 * 24 * 3; // After how many seconds backpack is marked "outdated" (possibly private)
|
||||||
|
|
||||||
|
extern CatVar enable_bptf;
|
||||||
|
|
||||||
|
struct backpack_data_s {
|
||||||
|
bool pending { false };
|
||||||
|
bool bad { true };
|
||||||
|
bool no_value { false }; // No recorded value
|
||||||
|
bool outdated_value { false }; // Outdated value. Private inventory?
|
||||||
|
unsigned last_request { 0 };
|
||||||
|
float value { 0 };
|
||||||
|
unsigned id { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
const backpack_data_s& get_data(unsigned id);
|
||||||
|
void init();
|
||||||
|
bool enabled();
|
||||||
|
|
||||||
|
}
|
@ -83,6 +83,7 @@ extern "C" {
|
|||||||
#include "hooks/hookedmethods.h"
|
#include "hooks/hookedmethods.h"
|
||||||
#include "classinfo/classinfo.hpp"
|
#include "classinfo/classinfo.hpp"
|
||||||
#include "crits.h"
|
#include "crits.h"
|
||||||
|
#include "backpacktf.hpp"
|
||||||
|
|
||||||
#if ENABLE_GUI
|
#if ENABLE_GUI
|
||||||
#include "gui/GUI.h"
|
#include "gui/GUI.h"
|
||||||
|
@ -18,14 +18,15 @@ void RenderPlayer(int eid) {
|
|||||||
player_info_s info;
|
player_info_s info;
|
||||||
bool success = g_IEngine->GetPlayerInfo(eid, &info);
|
bool success = g_IEngine->GetPlayerInfo(eid, &info);
|
||||||
if (success) {
|
if (success) {
|
||||||
//ImGui::PushItemWidth(50);
|
int x = 0;
|
||||||
ImGui::Text("%d", info.userID);
|
// UserID
|
||||||
//ImGui::PopItemWidth();
|
ImGui::Text("%d", info.userID);
|
||||||
ImGui::SameLine(48);
|
x += 48;
|
||||||
//ImGui::PushItemWidth(100);
|
ImGui::SameLine(x);
|
||||||
ImGui::Text("%u", info.friendsID);
|
// SteamID
|
||||||
//ImGui::PopItemWidth();
|
ImGui::Text("%u", info.friendsID);
|
||||||
ImGui::SameLine(140);
|
x += 80;
|
||||||
|
ImGui::SameLine(x);
|
||||||
|
|
||||||
char safename[32];
|
char safename[32];
|
||||||
for (int i = 0, j = 0; i < 32; i++) {
|
for (int i = 0, j = 0; i < 32; i++) {
|
||||||
@ -36,10 +37,10 @@ void RenderPlayer(int eid) {
|
|||||||
if (info.name[i] == '\n') continue;
|
if (info.name[i] == '\n') continue;
|
||||||
safename[j++] = info.name[i];
|
safename[j++] = info.name[i];
|
||||||
}
|
}
|
||||||
//ImGui::PushItemWidth(250);
|
|
||||||
ImGui::Text("%s", safename);
|
ImGui::Text("%s", safename);
|
||||||
//ImGui::PopItemWidth();
|
x += 8 * 32;
|
||||||
ImGui::SameLine(320);
|
ImGui::SameLine(x);
|
||||||
|
|
||||||
int iclazz = 0;
|
int iclazz = 0;
|
||||||
rgba_t bgcolor = colors::empty;
|
rgba_t bgcolor = colors::empty;
|
||||||
@ -63,14 +64,14 @@ void RenderPlayer(int eid) {
|
|||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(bgcolor.r, bgcolor.g, bgcolor.b, bgcolor.a));
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(bgcolor.r, bgcolor.g, bgcolor.b, bgcolor.a));
|
||||||
}
|
}
|
||||||
|
|
||||||
//ImGui::PushItemWidth(150);
|
ImGui::Text("%s", text);
|
||||||
ImGui::Text("%s", text);
|
x += 80;
|
||||||
//ImGui::PopItemWidth();
|
ImGui::SameLine(x);
|
||||||
ImGui::SameLine(420);
|
|
||||||
|
|
||||||
if (bgcolor.a) {
|
if (bgcolor.a) {
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
playerlist::userdata& data = playerlist::AccessData(info.friendsID);
|
playerlist::userdata& data = playerlist::AccessData(info.friendsID);
|
||||||
int& state = *reinterpret_cast<int*>(&data.state);
|
int& state = *reinterpret_cast<int*>(&data.state);
|
||||||
bgcolor = playerlist::Color(info.friendsID);
|
bgcolor = playerlist::Color(info.friendsID);
|
||||||
@ -80,10 +81,42 @@ void RenderPlayer(int eid) {
|
|||||||
ImGui::PushItemWidth(120);
|
ImGui::PushItemWidth(120);
|
||||||
ImGui::Combo("", &state, playerlist::k_pszNames, 5);
|
ImGui::Combo("", &state, playerlist::k_pszNames, 5);
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
x += 124;
|
||||||
|
|
||||||
if (bgcolor.a) {
|
if (bgcolor.a) {
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
|
||||||
|
if (backpacktf::enabled()) {
|
||||||
|
ImGui::SameLine(x);
|
||||||
|
if (info.fakeplayer) {
|
||||||
|
ImGui::Text("[BOT]");
|
||||||
|
} else if (!info.friendsID) {
|
||||||
|
ImGui::Text("Unknown");
|
||||||
|
} else {
|
||||||
|
const auto& d = backpacktf::get_data(info.friendsID);
|
||||||
|
if (d.bad && not d.pending) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
ImGui::Text("Error");
|
||||||
|
} else if (d.pending) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
|
||||||
|
ImGui::Text("Loading");
|
||||||
|
} else if (d.no_value) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
|
||||||
|
ImGui::Text("Private?");
|
||||||
|
} else if (d.outdated_value) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
|
||||||
|
ImGui::Text("$%.2f", d.value);
|
||||||
|
} else {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.8f, 0.0f, 1.0f));
|
||||||
|
ImGui::Text("$%.2f", d.value);
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
x += 80;
|
||||||
|
}
|
||||||
|
ImGui::SameLine(x);
|
||||||
ImGui::PushItemWidth(200.0f);
|
ImGui::PushItemWidth(200.0f);
|
||||||
if (ImGui::ColorEdit3("", data.color)) {
|
if (ImGui::ColorEdit3("", data.color)) {
|
||||||
if (!data.color.r && !data.color.b && !data.color.g) {
|
if (!data.color.r && !data.color.b && !data.color.g) {
|
||||||
@ -92,6 +125,7 @@ void RenderPlayer(int eid) {
|
|||||||
data.color.a = 255.0f;
|
data.color.a = 255.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
x += 200;
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
@ -104,7 +138,7 @@ void RenderPlayerlist() {
|
|||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 1));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 1));
|
||||||
std::vector<int> teammates {};
|
std::vector<int> teammates {};
|
||||||
for (int i = 1; i < 32; i++) {
|
for (int i = 1; i < 32; i++) {
|
||||||
if (g_pPlayerResource->GetTeam(i) == LOCAL_E->m_iTeam) {
|
if (!g_Settings.bInvalid && (g_pPlayerResource->GetTeam(i) == LOCAL_E->m_iTeam)) {
|
||||||
teammates.push_back(i);
|
teammates.push_back(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -272,8 +272,10 @@ void hack::Initialize() {
|
|||||||
hacks::shared::anticheat::Init();
|
hacks::shared::anticheat::Init();
|
||||||
hacks::tf2::healarrow::Init();
|
hacks::tf2::healarrow::Init();
|
||||||
InitSpinner();
|
InitSpinner();
|
||||||
hacks::shared::spam::Init();
|
|
||||||
logging::Info("Initialized Fidget Spinner");
|
logging::Info("Initialized Fidget Spinner");
|
||||||
|
hacks::shared::spam::Init();
|
||||||
|
backpacktf::init();
|
||||||
|
logging::Info("Initialized Backpack.TF integration");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
125
src/https_request.cpp
Normal file
125
src/https_request.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* https_request.cpp
|
||||||
|
*
|
||||||
|
* Created on: Jul 23, 2017
|
||||||
|
* Author: nullifiedcat
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "https_request.hpp"
|
||||||
|
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
namespace https {
|
||||||
|
|
||||||
|
SSL_CTX *ssl_context;
|
||||||
|
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
|
RAII_HTTPS_Socket::RAII_HTTPS_Socket(const std::string& host) : hostname_(host) {
|
||||||
|
if (!initialized) {
|
||||||
|
logging::Info("Initializing SSL");
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
sock_ = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock_ < 0) {
|
||||||
|
throw std::runtime_error("Socket creation error");
|
||||||
|
}
|
||||||
|
host_ = gethostbyname(hostname_.c_str());
|
||||||
|
if (not host_) {
|
||||||
|
throw std::runtime_error("Could not resolve hostname: " + host);
|
||||||
|
}
|
||||||
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
|
addr_.sin_family = AF_INET;
|
||||||
|
addr_.sin_port = htons(443);
|
||||||
|
memcpy(&addr_.sin_addr.s_addr, host_->h_addr, host_->h_length);
|
||||||
|
if (connect(sock_, (sockaddr *)&addr_, sizeof(addr_)) < 0) {
|
||||||
|
close(sock_);
|
||||||
|
sock_ = -1;
|
||||||
|
throw std::runtime_error("Couldn't connect to host");
|
||||||
|
}
|
||||||
|
ssl_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
RAII_HTTPS_Socket::~RAII_HTTPS_Socket() {
|
||||||
|
ssl_die();
|
||||||
|
if (sock_ >= 0)
|
||||||
|
close(sock_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RAII_HTTPS_Socket::ssl_connect() {
|
||||||
|
connection_ = SSL_new(ssl_context);
|
||||||
|
SSL_set_fd(connection_, sock_);
|
||||||
|
int ret = SSL_connect(connection_);
|
||||||
|
if (ret != 1) {
|
||||||
|
logging::Info("SSL connection error: %d, %d, %x\n", ret, SSL_get_error(connection_, ret), ERR_get_error());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RAII_HTTPS_Socket::ssl_die() {
|
||||||
|
if (connection_) {
|
||||||
|
SSL_free(connection_);
|
||||||
|
connection_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RAII_HTTPS_Socket::get(const std::string& path) {
|
||||||
|
constexpr size_t rq_size = 1024 * 8;
|
||||||
|
constexpr size_t rs_size = 1024 * 1024;
|
||||||
|
|
||||||
|
std::unique_ptr<char>
|
||||||
|
buffer_rq(new char[rq_size]),
|
||||||
|
buffer_rs(new char[rs_size]);
|
||||||
|
|
||||||
|
memset(buffer_rq.get(), 0, rq_size);
|
||||||
|
int rq_length = snprintf(buffer_rq.get(), rq_size, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", path.c_str(), hostname_.c_str());
|
||||||
|
int sent = 0;
|
||||||
|
int chunk = 0;
|
||||||
|
do {
|
||||||
|
chunk = SSL_write(connection_, buffer_rq.get() + sent, rq_length - sent);
|
||||||
|
if (chunk < 0) {
|
||||||
|
throw std::runtime_error("Error writing to Secure Socket: " + std::to_string(ERR_get_error()));
|
||||||
|
} else if (chunk == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sent += chunk;
|
||||||
|
} while (sent < rq_length);
|
||||||
|
|
||||||
|
memset(buffer_rs.get(), 0, rs_size);
|
||||||
|
int total = rs_size - 1;
|
||||||
|
int received = 0;
|
||||||
|
do {
|
||||||
|
chunk = SSL_read(connection_, buffer_rs.get() + received, total - received);
|
||||||
|
if (chunk < 0)
|
||||||
|
throw std::runtime_error("Error reading from socket");
|
||||||
|
if (chunk == 0)
|
||||||
|
break;
|
||||||
|
received += chunk;
|
||||||
|
} while (received < total);
|
||||||
|
|
||||||
|
if (received == total)
|
||||||
|
throw std::runtime_error("Response too large");
|
||||||
|
|
||||||
|
return std::string(buffer_rs.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void initialize() {
|
||||||
|
SSL_load_error_strings();
|
||||||
|
SSL_library_init();
|
||||||
|
ssl_context = SSL_CTX_new(SSLv23_client_method());
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
src/https_request.hpp
Normal file
44
src/https_request.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* https_request.hpp
|
||||||
|
*
|
||||||
|
* Created on: Jul 23, 2017
|
||||||
|
* Author: nullifiedcat
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include "beforecheaders.h"
|
||||||
|
#include <string>
|
||||||
|
#include "aftercheaders.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace https {
|
||||||
|
|
||||||
|
extern SSL_CTX *ssl_context;
|
||||||
|
|
||||||
|
class RAII_HTTPS_Socket {
|
||||||
|
public:
|
||||||
|
RAII_HTTPS_Socket(const std::string& host);
|
||||||
|
~RAII_HTTPS_Socket();
|
||||||
|
|
||||||
|
bool ssl_connect();
|
||||||
|
void ssl_die();
|
||||||
|
|
||||||
|
std::string get(const std::string& path);
|
||||||
|
|
||||||
|
const std::string hostname_;
|
||||||
|
|
||||||
|
hostent *host_ { nullptr };
|
||||||
|
sockaddr_in addr_ {};
|
||||||
|
int sock_ { -1 };
|
||||||
|
SSL *connection_ { nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -222,10 +222,17 @@ Vector ProjectilePrediction_Engine(CachedEntity* ent, int hb, float speed, float
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CatVar debug_pp_extrapolate(CV_SWITCH, "debug_pp_extrapolate", "0", "Extrapolate entity position when predicting projectiles");
|
||||||
|
CatVar debug_pp_rockettimeping(CV_SWITCH, "debug_pp_rocket_time_ping", "0", "Compensate for ping in pp");
|
||||||
|
|
||||||
Vector ProjectilePrediction(CachedEntity* ent, int hb, float speed, float gravitymod, float entgmod) {
|
Vector ProjectilePrediction(CachedEntity* ent, int hb, float speed, float gravitymod, float entgmod) {
|
||||||
if (!ent) return Vector();
|
if (!ent) return Vector();
|
||||||
Vector result;
|
Vector result;
|
||||||
GetHitbox(ent, hb, result);
|
if (not debug_pp_extrapolate) {
|
||||||
|
GetHitbox(ent, hb, result);
|
||||||
|
} else {
|
||||||
|
result = SimpleLatencyPrediction(ent, hb);
|
||||||
|
}
|
||||||
if (speed == 0.0f) return Vector();
|
if (speed == 0.0f) return Vector();
|
||||||
float dtg = DistanceToGround(ent);
|
float dtg = DistanceToGround(ent);
|
||||||
Vector vel;
|
Vector vel;
|
||||||
@ -250,6 +257,7 @@ Vector ProjectilePrediction(CachedEntity* ent, int hb, float speed, float gravit
|
|||||||
if (curpos.z < result.z - dtg) curpos.z = result.z - dtg;
|
if (curpos.z < result.z - dtg) curpos.z = result.z - dtg;
|
||||||
}
|
}
|
||||||
float rockettime = g_pLocalPlayer->v_Eye.DistTo(curpos) / speed;
|
float rockettime = g_pLocalPlayer->v_Eye.DistTo(curpos) / speed;
|
||||||
|
if (debug_pp_rockettimeping) rockettime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING);
|
||||||
if (fabs(rockettime - currenttime) < mindelta) {
|
if (fabs(rockettime - currenttime) < mindelta) {
|
||||||
besttime = currenttime;
|
besttime = currenttime;
|
||||||
bestpos = curpos;
|
bestpos = curpos;
|
||||||
|
Reference in New Issue
Block a user