diff --git a/.cproject b/.cproject
index 8725a931..d9de7e37 100644
--- a/.cproject
+++ b/.cproject
@@ -66,7 +66,6 @@
-
@@ -117,11 +116,12 @@
-
+
-
+
+
@@ -130,7 +130,8 @@
-
+
+
diff --git a/include/gui/GUI.hpp b/include/gui/GUI.hpp
index 6959a97b..ec2cb951 100644
--- a/include/gui/GUI.hpp
+++ b/include/gui/GUI.hpp
@@ -7,6 +7,14 @@
#pragma once
+#include "cmdui/cmdui.hpp"
+namespace gui
+{
+void init();
+void update();
+void draw();
+
+}
diff --git a/include/gui/cmdui/cmdui.hpp b/include/gui/cmdui/cmdui.hpp
new file mode 100644
index 00000000..9029a7a7
--- /dev/null
+++ b/include/gui/cmdui/cmdui.hpp
@@ -0,0 +1,16 @@
+/*
+ * cmdui.hpp
+ *
+ * Created on: Nov 17, 2017
+ * Author: nullifiedcat
+ */
+
+#pragma once
+
+namespace gui { namespace cmdui {
+
+void init();
+void update();
+void draw();
+
+}}
diff --git a/include/gui/cmdui/node.hpp b/include/gui/cmdui/node.hpp
new file mode 100644
index 00000000..60c8f9ac
--- /dev/null
+++ b/include/gui/cmdui/node.hpp
@@ -0,0 +1,55 @@
+/*
+ * node.hpp
+ *
+ * Created on: Nov 17, 2017
+ * Author: nullifiedcat
+ */
+
+#pragma once
+
+#include "common.hpp"
+
+namespace gui { namespace cmdui {
+
+struct node_descriptor
+{
+ enum nodetype
+ {
+ UNDEFINED,
+ LIST,
+ VARIABLE,
+ COMMAND
+ };
+ nodetype type;
+ std::shared_ptr node;
+};
+
+class node
+{
+public:
+ int dummy;
+};
+
+class node_list: public node
+{
+public:
+ node_list();
+ std::vector children {};
+};
+
+class node_variable: public node
+{
+public:
+ node_variable(const CatVar& catvar);
+
+};
+
+class node_command: public node
+{
+public:
+ const node_descriptor type { node_descriptor::nodetype::COMMAND };
+};
+
+}}
+
+
diff --git a/include/helpers.hpp b/include/helpers.hpp
index 6a106506..1d432d64 100644
--- a/include/helpers.hpp
+++ b/include/helpers.hpp
@@ -33,6 +33,7 @@ void SetCVarInterface(ICvar* iface);
#include
#include
#include
+#include
#include
#include
@@ -70,7 +71,7 @@ weaponmode GetWeaponMode();
void FixMovement(CUserCmd& cmd, Vector& viewangles);
void VectorAngles(Vector &forward, Vector &angles);
-
+extern std::mutex trace_lock;
bool IsEntityVisible(CachedEntity* entity, int hb);
bool IsEntityVectorVisible(CachedEntity* entity, Vector endpos);
bool VisCheckEntFromEnt(CachedEntity* startEnt, CachedEntity* endEnt);
diff --git a/makefile b/makefile
index 0161966a..bedaa546 100644
--- a/makefile
+++ b/makefile
@@ -17,7 +17,7 @@
GAME=tf2
ENABLE_VISUALS=1
-ENABLE_GUI:=1
+ENABLE_GUI=1
ENABLE_IPC=1
ENABLE_NULL_GRAPHICS=0
TEXTMODE_STDIN=0
diff --git a/src/globals.cpp b/src/globals.cpp
index d06049da..607eb52e 100644
--- a/src/globals.cpp
+++ b/src/globals.cpp
@@ -34,13 +34,13 @@ bool* bSendPackets; // i'd probably want to hook it, idk.
//CatVar send_packets(CV_SWITCH, "sendpackets", "1", "Send packets", "Internal use");
CatVar show_antiaim(CV_SWITCH, "thirdperson_angles", "1", "Real TP angles", "You can see your own AA/Aimbot angles in thirdperson");
CatVar force_thirdperson(CV_SWITCH, "thirdperson", "0", "Thirdperson", "Enable thirdperson view");
-CatVar console_logging(CV_SWITCH, "log", "1", "Debug Log", "Disable this if you don't need cathook messages in your console");
+CatVar console_logging(CV_SWITCH, "log", "0", "Debug Log", "Disable this if you don't need cathook messages in your console");
//CatVar fast_outline(CV_SWITCH, "fastoutline", "0", "Low quality outline", "Might increase performance when there is a lot of ESP text to draw");
CatVar roll_speedhack(CV_KEY, "rollspeedhack", "0", "Roll Speedhack", "Roll speedhack key");
char* disconnect_reason_newlined = new char[256] { 0 };
CatVar disconnect_reason(CV_STRING, "disconnect_reason", "", "Disconnect reason", "A custom disconnect reason");
-CatVar event_log(CV_SWITCH, "events", "1", "Advanced Events");
+CatVar event_log(CV_SWITCH, "events", "0", "Advanced Events");
void GlobalSettings::Init() {
sv_client_min_interp_ratio = g_ICvar->FindVar("sv_client_min_interp_ratio");
cl_interp_ratio = g_ICvar->FindVar("cl_interp_ratio");
diff --git a/src/gui/GUI.cpp b/src/gui/GUI.cpp
new file mode 100644
index 00000000..b968a203
--- /dev/null
+++ b/src/gui/GUI.cpp
@@ -0,0 +1,28 @@
+/*
+ * GUI.cpp
+ *
+ * Created on: Nov 17, 2017
+ * Author: nullifiedcat
+ */
+
+#include "common.hpp"
+
+namespace gui
+{
+
+void init()
+{
+ cmdui::init();
+}
+
+void update()
+{
+ cmdui::update();
+}
+
+void draw()
+{
+ cmdui::draw();
+}
+
+}
diff --git a/src/gui/cmdui/cmdui.cpp b/src/gui/cmdui/cmdui.cpp
new file mode 100644
index 00000000..3d7b1d39
--- /dev/null
+++ b/src/gui/cmdui/cmdui.cpp
@@ -0,0 +1,29 @@
+/*
+ * cmdui.cpp
+ *
+ * Created on: Nov 17, 2017
+ * Author: nullifiedcat
+ */
+
+#include "common.hpp"
+
+namespace gui { namespace cmdui {
+
+bool active = false;
+
+void init()
+{
+
+}
+
+void update()
+{
+
+}
+
+void draw()
+{
+
+}
+
+}}
diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp
index acdbe7ff..8f336229 100644
--- a/src/hacks/ESP.cpp
+++ b/src/hacks/ESP.cpp
@@ -530,7 +530,7 @@ void _FASTCALL ProcessEntityPT(CachedEntity* ent) {
// If the origin is centered, we use one method. if not, the other
if (!origin_is_zero || true) {
- draw_api::draw_string_with_outline(draw_point.x, draw_point.y, string.data.c_str(), fonts::main_font, color, colors::black, 1.0f);
+ draw_api::draw_string_with_outline(draw_point.x, draw_point.y, string.data.c_str(), fonts::main_font, color, colors::black, 1.5f);
} else {/*
int size_x;
FTGL_StringLength(string.data, fonts::font_main, &size_x);
@@ -538,7 +538,7 @@ void _FASTCALL ProcessEntityPT(CachedEntity* ent) {
*/}
// Add to the y due to their being text in that spot
- draw_point.y += /*((int)fonts::font_main->height)*/ 14 - 1;
+ draw_point.y += /*((int)fonts::font_main->height)*/ 15 - 1;
}
}
diff --git a/src/hacks/Walkbot.cpp b/src/hacks/Walkbot.cpp
index 19a92aac..e6d52f39 100644
--- a/src/hacks/Walkbot.cpp
+++ b/src/hacks/Walkbot.cpp
@@ -880,7 +880,7 @@ void DrawNode(index_t node, bool draw_back) {
if (not draw::WorldToScreen(n.xyz(), wts))
return;
- draw_api::draw_string_with_outline(wts.x, wts.y, std::to_string(node).c_str(), fonts::main_font, *color, colors::black, 1.0f);
+ draw_api::draw_string_with_outline(wts.x, wts.y, std::to_string(node).c_str(), fonts::main_font, *color, colors::black, 1.5f);
}
}
diff --git a/src/prediction.cpp b/src/prediction.cpp
index fe9b1db0..8dac2139 100644
--- a/src/prediction.cpp
+++ b/src/prediction.cpp
@@ -9,6 +9,31 @@
// TODO there is a Vector() object created each call.
+struct pp_data_player
+{
+ Vector velocity {};
+ float distance_to_ground { 0.0f };
+
+ long tick { 0 };
+};
+
+pp_data_player& pp_data(CachedEntity *ent)
+{
+ static pp_data_player data[32] {};
+
+ auto& d = data[ent->m_IDX - 1];
+ if (d.tick != tickcount)
+ {
+ d.distance_to_ground = DistanceToGround(ent);
+ if (velocity::EstimateAbsVelocity)
+ velocity::EstimateAbsVelocity(RAW_ENT(ent), d.velocity);
+ else
+ d.velocity = CE_VECTOR(ent, netvar.vVelocity);
+ d.tick = tickcount;
+ }
+ return d;
+}
+
Vector SimpleLatencyPrediction(CachedEntity* ent, int hb) {
if (!ent) return Vector();
Vector result;
@@ -37,8 +62,118 @@ bool PerformProjectilePrediction(CachedEntity* target, int hitbox) {
std::vector> predicted_players {};
int predicted_player_count = 0;
+Timer record_timer {};
+int recording = 0;
+void pp_record_start();
static CatVar debug_enginepred(CV_SWITCH, "debug_engine_pred_others", "0", "DO NOT USE - MOVEMENT");
+static CatVar debug_projpred(CV_SWITCH, "debug_pp", "0", "Debug projectile prediction");
+static CatVar debug_pp_record_ms(CV_INT, "debug_pp_record_ms", "1000", "Milliseconds");
+static CatCommand debug_projpred_record("debug_pp_record", "", []() {
+ recording = 1;
+});
+static CatCommand debug_pp_record_reset("debug_pp_record_reset", "", []() {
+ recording = 0;
+});
+
+struct record_data
+{
+ std::vector predicted {};
+ std::vector real {};
+};
+
+std::vector debug_data_records {};
+
+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");
+
+namespace predict_move
+{
+
+struct move_prediction_data
+{
+ CachedEntity *entity;
+ float dt;
+ float groundt;
+ Vector current;
+ Vector velocity;
+};
+
+move_prediction_data begin(CachedEntity *entity)
+{
+ return move_prediction_data { entity, 0, 0, entity->m_vecOrigin, pp_data(entity).velocity };
+}
+
+void step(move_prediction_data& data, float dt)
+{
+ data.dt += dt;
+ if (debug_pp_extrapolate)
+ {
+ float latency = g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) +
+ g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_INCOMING);
+ data.current += data.velocity * latency * dt;
+ }
+ data.current += data.velocity * dt;
+ float dtg = DistanceToGround(data.current);
+ bool correction = false;
+ while (dtg >= 4000) // precision
+ {
+ data.current.z += 200.0f;
+ dtg = DistanceToGround(data.current);
+ correction = true;
+ }
+ if (correction)
+ {
+ data.current.z -= dtg;
+ data.velocity.z = 0;
+ }
+ else
+ {
+ if (dtg)
+ {
+ data.velocity.z -= dt * 800.0f * PlayerGravityMod(data.entity);
+ //float s = data.current.z;
+ //data.current.z -= (data.dt - data.groundt) * (data.dt - data.groundt) * 400.0f * PlayerGravityMod(data.entity);
+ //if (data.current.z < s - dtg) data.current.z = s - dtg;
+ }
+ else
+ {
+ data.velocity.z = 0;
+ data.groundt = 0;
+ }
+ }
+}
+
+}
+
+void pp_record_start()
+{
+ record_timer.update();
+ if (debug_data_records.size() != 1 + g_GlobalVars->maxClients)
+ debug_data_records.resize(1 + g_GlobalVars->maxClients);
+ for (int i = 1; i < g_GlobalVars->maxClients; ++i)
+ {
+ CachedEntity *ent = ENTITY(i);
+ if (CE_BAD(ent))
+ continue;
+
+ auto& data = debug_data_records[i];
+
+ data.predicted.clear();
+ data.real.clear();
+ data.predicted.push_back(ent->m_vecOrigin);
+ data.real.push_back(ent->m_vecOrigin);
+
+ auto mp = predict_move::begin(ent);
+ trace::filter_no_player.SetSelf(RAW_ENT(ent));
+ for (int i = 1; i < 50; ++i)
+ {
+ predict_move::step(mp, ((float)debug_pp_record_ms / 1000.0f) / 50.0f);
+ data.predicted.push_back(mp.current);
+ }
+ }
+ recording = 2;
+}
void Prediction_CreateMove() {
static bool setup = false;
@@ -46,6 +181,28 @@ void Prediction_CreateMove() {
setup = true;
predicted_players.resize(32);
}
+ if (recording == 1)
+ {
+ std::lock_guard mtx(trace_lock);
+ pp_record_start();
+ }
+ if (recording == 2)
+ {
+ for (int i = 1; i < g_GlobalVars->maxClients; ++i)
+ {
+ CachedEntity *ent = ENTITY(i);
+ if (CE_BAD(ent))
+ continue;
+
+ auto& data = debug_data_records[i];
+
+ data.real.push_back(ent->m_vecOrigin);
+ }
+ if (record_timer.test_and_set((int)debug_pp_record_ms))
+ {
+ recording = 3;
+ }
+ }
if (!debug_enginepred) return;
for (int i = 1; i < g_GlobalVars->maxClients; i++) {
CachedEntity* ent = ENTITY(i);
@@ -66,6 +223,52 @@ void Prediction_CreateMove() {
}
#if ENABLE_VISUALS == 1
void Prediction_PaintTraverse() {
+ if (recording)
+ {
+ Vector pscreen;
+ for (int i = 1; i < g_GlobalVars->maxClients; i++) {
+ CachedEntity* ent = ENTITY(i);
+ if (CE_GOOD(ent)) {
+ {
+ rgba_t color_real = colors::FromRGBA8(0, 255, 0, 255);
+ rgba_t color_pred = colors::FromRGBA8(255, 0, 0, 255);
+ auto& data = debug_data_records[i];
+ if (data.real.size() == 0 || data.predicted.size() == 0)
+ continue;
+ Vector orgn;
+ if (draw::WorldToScreen(ent->m_vecOrigin, orgn))
+ {
+ char *str = strfmt("DTG: %.2f", DistanceToGround(ent));
+ draw_api::draw_string(orgn.x, orgn.y, str, fonts::main_font, colors::EntityF(ent));
+ free(str);
+ }
+ if (!draw::WorldToScreen(data.real[0], pscreen)) continue;
+ for (int j = 0; j < data.real.size(); j++) {
+ Vector screen;
+ if (draw::WorldToScreen(data.real[j], screen)) {
+ draw_api::draw_line(screen.x, screen.y, pscreen.x - screen.x, pscreen.y - screen.y, color_real, 0.5f);
+ pscreen = screen;
+ } else {
+ break;
+ }
+ color_real.b -= 1.0f / 200.0f;
+ }
+ if (!draw::WorldToScreen(data.predicted[0], pscreen)) continue;
+ for (int j = 0; j < data.predicted.size(); j++) {
+ Vector screen;
+ if (draw::WorldToScreen(data.predicted[j], screen)) {
+ draw_api::draw_line(screen.x, screen.y, pscreen.x - screen.x, pscreen.y - screen.y, color_pred, 0.5f);
+ pscreen = screen;
+ } else {
+ break;
+ }
+ color_pred.r -= 1.0f / 200.0f;
+ }
+ }
+
+ }
+ }
+ }
if (!debug_enginepred) return;
for (int i = 1; i < predicted_player_count; i++) {
CachedEntity* ent = ENTITY(i);
@@ -205,24 +408,11 @@ Vector ProjectilePrediction_Engine(CachedEntity* ent, int hb, float speed, float
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) {
if (!ent) return Vector();
Vector result;
- if (not debug_pp_extrapolate) {
- GetHitbox(ent, hb, result);
- } else {
- result = SimpleLatencyPrediction(ent, hb);
- }
+ GetHitbox(ent, hb, result);
if (speed == 0.0f) return Vector();
- float dtg = DistanceToGround(ent);
- Vector vel;
- if (velocity::EstimateAbsVelocity)
- velocity::EstimateAbsVelocity(RAW_ENT(ent), vel);
- else
- vel = CE_VECTOR(ent, netvar.vVelocity);
// TODO ProjAim
float medianTime = g_pLocalPlayer->v_Eye.DistTo(result) / speed;
float range = 1.5f;
@@ -231,19 +421,17 @@ Vector ProjectilePrediction(CachedEntity* ent, int hb, float speed, float gravit
float besttime = currenttime;
float mindelta = 65536.0f;
Vector bestpos = result;
- int maxsteps = 300;
+ int maxsteps = 100;
+ auto mp = predict_move::begin(ent);
+ trace::filter_no_player.SetSelf(RAW_ENT(ent));
+ std::lock_guard mtx(trace_lock);
for (int steps = 0; steps < maxsteps; steps++, currenttime += ((float)(2 * range) / (float)maxsteps)) {
- Vector curpos = result;
- curpos += vel * currenttime;
- if (dtg > 0.0f) {
- curpos.z -= currenttime * currenttime * 400 * entgmod;
- if (curpos.z < result.z - dtg) curpos.z = result.z - dtg;
- }
- float rockettime = g_pLocalPlayer->v_Eye.DistTo(curpos) / speed;
+ predict_move::step(mp, ((float)(2 * range) / (float)maxsteps));
+ float rockettime = g_pLocalPlayer->v_Eye.DistTo(mp.current) / speed;
if (debug_pp_rockettimeping) rockettime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING);
if (fabs(rockettime - currenttime) < mindelta) {
besttime = currenttime;
- bestpos = curpos;
+ bestpos = mp.current;
mindelta = fabs(rockettime - currenttime);
}
}
@@ -257,21 +445,26 @@ float DistanceToGround(CachedEntity* ent) {
if (CE_INT(ent, netvar.iFlags) & FL_ONGROUND) return 0;
}
Vector& origin = ent->m_vecOrigin;
+ trace::filter_no_player.SetSelf(RAW_ENT(ent));
float v1 = DistanceToGround(origin + Vector(10.0f, 10.0f, 0.0f));
- float v2 = DistanceToGround(origin + Vector(-10.0f, 10.0f, 0.0f));
- float v3 = DistanceToGround(origin + Vector(10.0f, -10.0f, 0.0f));
- float v4 = DistanceToGround(origin + Vector(-10.0f, -10.0f, 0.0f));
- return MIN(v1, MIN(v2, MIN(v3, v4)));
+ float v2 = DistanceToGround(origin + Vector(-10.0f, -10.0f, 0.0f));
+
+ //float v1 = DistanceToGround(origin + Vector(10.0f, 10.0f, 0.0f));
+ //float v2 = DistanceToGround(origin + Vector(-10.0f, 10.0f, 0.0f));
+ //float v3 = DistanceToGround(origin + Vector(10.0f, -10.0f, 0.0f));
+ //float v4 = DistanceToGround(origin + Vector(-10.0f, -10.0f, 0.0f));
+ //return MIN(v1, MIN(v2, MIN(v3, v4)));
+ return MIN(v1, v2);
}
float DistanceToGround(Vector origin) {
trace_t ground_trace;
Ray_t ray;
Vector endpos = origin;
- endpos.z -= 8192;
+ endpos.z -= 4096;
ray.Init(origin, endpos);
g_ITrace->TraceRay(ray, MASK_PLAYERSOLID, &trace::filter_no_player, &ground_trace);
- return 8192.0f * ground_trace.fraction;
+ return 4096.0f * ground_trace.fraction;
}
/*
diff --git a/src/visual/drawing.cpp b/src/visual/drawing.cpp
index af1fb8ed..86880453 100644
--- a/src/visual/drawing.cpp
+++ b/src/visual/drawing.cpp
@@ -37,14 +37,14 @@ void AddSideString(const std::string& string, const rgba_t& color) {
void DrawStrings() {
int y { 8 };
for (size_t i = 0; i < side_strings_count; ++i) {
- draw_api::draw_string_with_outline(8, y, side_strings[i].c_str(), fonts::main_font, side_strings_colors[i], colors::black, 1.0f);
+ draw_api::draw_string_with_outline(8, y, side_strings[i].c_str(), fonts::main_font, side_strings_colors[i], colors::black, 1.5f);
y += /*((int)fonts::font_main->height)*/ 14 + 1;
}
y = draw::height / 2;
for (size_t i = 0; i < center_strings_count; ++i) {
float sx, sy;
draw_api::get_string_size(center_strings[i].c_str(), fonts::main_font, &sx, &sy);
- draw_api::draw_string_with_outline((draw::width - sx) / 2, y, center_strings[i].c_str(), fonts::main_font, center_strings_colors[i], colors::black, 1.0f);
+ draw_api::draw_string_with_outline((draw::width - sx) / 2, y, center_strings[i].c_str(), fonts::main_font, center_strings_colors[i], colors::black, 1.5f);
y += /*((int)fonts::font_main->height)*/ 14 + 1;
}
}