summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--TODO/.autojump6
-rw-r--r--TODO/autojump5
-rw-r--r--compile1
-rw-r--r--compile.bat5
-rw-r--r--gamedata/gamelib.kv2
-rw-r--r--src/autojump.c124
-rw-r--r--src/autojump.h27
-rw-r--r--src/sst.c6
8 files changed, 166 insertions, 10 deletions
diff --git a/TODO/.autojump b/TODO/.autojump
new file mode 100644
index 0000000..1b41226
--- /dev/null
+++ b/TODO/.autojump
@@ -0,0 +1,6 @@
+Add back autojump
+====
+I already wrote (and rewrote) the code long ago, but we kept it secret for a
+long time to prevent L4D2 cheating. Now that proof standards are soon to
+raised across the board, this is safe to include without having to worry about
+verification headaches.
diff --git a/TODO/autojump b/TODO/autojump
deleted file mode 100644
index 7b9c8b4..0000000
--- a/TODO/autojump
+++ /dev/null
@@ -1,5 +0,0 @@
-Add back autojump
-====
-I already wrote (and rewrote) the code long ago, but it's a secret until we
-further raise the verification standard for L4D2. Stupid, but less stupid than
-having no idea whether anyone's cheating, I guess.
diff --git a/compile b/compile
index d48ee0e..fa4f5a0 100644
--- a/compile
+++ b/compile
@@ -25,6 +25,7 @@ ld() {
}
src="\
+ autojump.c \
con_.c \
demorec.c \
dbg.c \
diff --git a/compile.bat b/compile.bat
index 06596b0..844ce01 100644
--- a/compile.bat
+++ b/compile.bat
@@ -24,8 +24,8 @@ clang -municode -O2 -fuse-ld=lld %warnings% -D_CRT_SECURE_NO_WARNINGS -ladvapi32
-o .build/codegen.exe src/build/codegen.c src/build/cmeta.c src/os.c || exit /b
clang -municode -O2 -fuse-ld=lld %warnings% -D_CRT_SECURE_NO_WARNINGS -ladvapi32 ^
-o .build/mkgamedata.exe src/build/mkgamedata.c src/kv.c src/os.c || exit /b
-.build\codegen.exe src/con_.c src/demorec.c src/dbg.c src/fixes.c src/gamedata.c ^
-src/gameinfo.c src/hook.c src/kv.c src/os.c src/sst.c src/udis86.c || exit /b
+.build\codegen.exe src/autojump.c src/con_.c src/demorec.c src/dbg.c src/fixes.c ^
+src/gamedata.c src/gameinfo.c src/hook.c src/kv.c src/os.c src/sst.c src/udis86.c || exit /b
.build\mkgamedata.exe gamedata/engine.kv gamedata/gamelib.kv || exit /b
:: llvm-rc doesn't preprocess, looks like it might later:
:: https://reviews.llvm.org/D100755?id=339141
@@ -35,6 +35,7 @@ llvm-rc /FO .build\dll.res .build\dll.pp.rc || exit /b
:: might as well remove the temp file afterwards
del .build\dll.pp.rc
clang -m32 -shared -fuse-ld=lld -O0 -w -o .build/tier0.dll src/tier0stub.c
+call :cc src/autojump.c || exit /b
call :cc src/con_.c || exit /b
call :cc src/demorec.c || exit /b
call :cc src/dbg.c || exit /b
diff --git a/gamedata/gamelib.kv b/gamedata/gamelib.kv
index 388abb9..f6a989d 100644
--- a/gamedata/gamelib.kv
+++ b/gamedata/gamelib.kv
@@ -1,4 +1,4 @@
-// = client and server libaries =
+// = client and server libraries =
// CGameMovement
vtidx_CheckJumpButton {
diff --git a/src/autojump.c b/src/autojump.c
new file mode 100644
index 0000000..fa0f4b5
--- /dev/null
+++ b/src/autojump.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright © 2021 Michael Smith <mikesmiffy128@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdbool.h>
+
+#include "con_.h"
+#include "factory.h"
+#include "gamedata.h"
+#include "intdefs.h"
+#include "hook.h"
+#include "mem.h"
+#include "os.h"
+#include "vcall.h"
+
+DEF_CVAR(sst_autojump, "Jump upon hitting the group while holding space", "0",
+ CON_REPLICATE | CON_DEMO | CON_HIDDEN)
+
+struct vec3f { float x, y, z; };
+struct CMoveData {
+ bool firstrun : 1;
+ bool gamecodemoved : 1;
+ ulong playerhandle;
+ int impulse;
+ struct vec3f viewangles;
+ struct vec3f absviewangles;
+ int buttons;
+ int oldbuttons;
+ float mv_forward;
+ float mv_side;
+ float mv_up;
+ float maxspeed;
+ float clientmaxspeed;
+ struct vec3f vel;
+ struct vec3f angles;
+ struct vec3f oldangles;
+ float out_stepheight;
+ struct vec3f out_wishvel;
+ struct vec3f out_jumpvel;
+ struct vec3f constraint_center;
+ float constraint_radius;
+ float constraint_width;
+ float constraint_speedfactor;
+ struct vec3f origin;
+};
+
+#define IN_JUMP 2
+#define NIDX 256 // *completely* arbitrary lol
+static bool justjumped[NIDX] = {0};
+static inline int handleidx(ulong h) { return h & (1 << 11) - 1; }
+
+static void *gmsv = 0, *gmcl = 0;
+typedef bool (VCALLCONV *CheckJumpButton_f)(void *);
+static CheckJumpButton_f origsv, origcl;
+
+static bool VCALLCONV hook(void *this) {
+ struct CMoveData **mvp = mem_offset(this, gamedata_off_mv), *mv = *mvp;
+ // use 0 idx for client side, as server indices start at 1
+ // FIXME: does this account for splitscreen???
+ int i = this == gmsv ? handleidx(mv->playerhandle) : 0;
+ if (con_getvari(sst_autojump) && !justjumped[i]) mv->oldbuttons &= ~IN_JUMP;
+ return justjumped[i] = (this == gmsv ? origsv : origcl)(this);
+}
+
+static bool unprot(void *gm) {
+ void **vtable = *(void ***)gm;
+ bool ret = os_mprot(vtable + gamedata_vtidx_CheckJumpButton,
+ sizeof(void *), PAGE_EXECUTE_READWRITE);
+ if (!ret) con_warn("autojump: couldn't make memory writeable\n");
+ return ret;
+}
+
+bool autojump_init(void) {
+ // TODO(featgen): auto-check these factories
+ if (!factory_client || !factory_server) {
+ con_warn("autojump: missing required interfaces\n");
+ return false;
+ }
+ if (!gamedata_has_vtidx_CheckJumpButton || !gamedata_has_off_mv) {
+ con_warn("autojump: missing gamedata entries for this engine\n");
+ return false;
+ }
+
+ gmsv = factory_server("GameMovement001", 0);
+ if (!gmsv) {
+ con_warn("autojump: couldn't get server-side game movement interface\n");
+ return false;
+ }
+ if (!unprot(gmsv)) return false;
+ gmcl = factory_client("GameMovement001", 0);
+ if (!gmcl) {
+ con_warn("autojump: couldn't get client-side game movement interface\n");
+ return false;
+ }
+ if (!unprot(gmcl)) return false;
+ origsv = (CheckJumpButton_f)hook_vtable(*(void ***)gmsv,
+ gamedata_vtidx_CheckJumpButton, (void *)&hook);
+ origcl = (CheckJumpButton_f)hook_vtable(*(void ***)gmcl,
+ gamedata_vtidx_CheckJumpButton, (void *)&hook);
+
+ sst_autojump->base.flags &= ~CON_HIDDEN;
+ return true;
+}
+
+void autojump_end(void) {
+ unhook_vtable(*(void ***)gmsv, gamedata_vtidx_CheckJumpButton,
+ (void *)origsv);
+ unhook_vtable(*(void ***)gmcl, gamedata_vtidx_CheckJumpButton,
+ (void *)origcl);
+}
+
+// vi: sw=4 ts=4 noet tw=80 cc=80
diff --git a/src/autojump.h b/src/autojump.h
new file mode 100644
index 0000000..efcde2e
--- /dev/null
+++ b/src/autojump.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright © 2021 Michael Smith <mikesmiffy128@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INC_AUTOJUMP_H
+#define INC_AUTOJUMP_H
+
+#include <stdbool.h>
+
+bool autojump_init(void);
+void autojump_end(void);
+
+#endif
+
+// vi: sw=4 ts=4 noet tw=80 cc=80
diff --git a/src/sst.c b/src/sst.c
index d13ba5d..183a73a 100644
--- a/src/sst.c
+++ b/src/sst.c
@@ -17,6 +17,7 @@
#include <stdbool.h>
#include <string.h>
+#include "autojump.h"
#include "con_.h"
#include "demorec.h"
#include "factory.h"
@@ -65,6 +66,7 @@ ifacefactory factory_client = 0, factory_server = 0, factory_engine = 0;
// figures out the dependencies at build time and generates all the init glue
// but we want to actually release the plugin this decade so for now I'm just
// plonking ~~some bools~~ one bool here and worrying about it later. :^)
+static bool has_autojump = false;
static bool has_demorec = false;
// HACK: later versions of L4D2 show an annoying dialog on every plugin_load.
@@ -122,7 +124,7 @@ static bool do_load(ifacefactory enginef, ifacefactory serverf) {
}
nc: gamedata_init();
- // TODO(autojump): we'd init that here
+ has_autojump = autojump_init();
has_demorec = demorec_init();
fixes_apply();
@@ -164,7 +166,7 @@ e: con_colourmsg(RGBA(64, 255, 64, 255),
}
static void do_unload(void) {
- // TODO(autojump): we'd end that here
+ if (has_autojump) autojump_end();
if (has_demorec) demorec_end();
#ifdef __linux__