summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hook.c16
-rw-r--r--src/hook.h4
-rw-r--r--src/sst.c28
3 files changed, 43 insertions, 5 deletions
diff --git a/src/hook.c b/src/hook.c
index bca226d..8465fbe 100644
--- a/src/hook.c
+++ b/src/hook.c
@@ -29,14 +29,20 @@
#if defined(_WIN32) && !defined(_WIN64)
+#if defined(__GNUC__) || defined(__clang__)
__attribute__((aligned(4096)))
+#elif defined(_MSC_VER)
+__declspec(align(4096))
+#else
+#error no way to align stuff!
+#endif
static uchar trampolines[4096];
static uchar *nexttrampoline = trampolines;
-__attribute__((constructor))
-static void setrwx(void) {
- // PE doesn't support rwx sections, not sure about ELF. Eh, just hack it in
- // a constructor instead. If this fails and we segfault later, too bad!
- os_mprot(trampolines, sizeof(trampolines), PAGE_EXECUTE_READWRITE);
+
+bool hook_init(void) {
+ // PE doesn't support rwx sections, not sure about ELF. Meh, just set it
+ // here instead.
+ return os_mprot(trampolines, sizeof(trampolines), PAGE_EXECUTE_READWRITE);
}
void *hook_inline(void *func_, void *target) {
diff --git a/src/hook.h b/src/hook.h
index e432eb7..ff1acff 100644
--- a/src/hook.h
+++ b/src/hook.h
@@ -17,8 +17,12 @@
#ifndef INC_HOOK_H
#define INC_HOOK_H
+#include <stdbool.h>
+
#include "intdefs.h"
+bool hook_init(void);
+
/*
* Replaces a vtable entry with a target function and returns the original
* function.
diff --git a/src/sst.c b/src/sst.c
index 2ba4e9e..b7298ef 100644
--- a/src/sst.c
+++ b/src/sst.c
@@ -198,6 +198,11 @@ static bool already_loaded = false, skip_unload = false;
#define RGBA(r, g, b, a) (&(struct con_colour){(r), (g), (b), (a)})
+// auto-update message. see below in do_featureinit()
+static const char *updatenotes = "\
+* various internal cleanup\n\
+";
+
static void do_featureinit(void) {
has_autojump = autojump_init();
has_demorec = demorec_init();
@@ -217,6 +222,24 @@ static void do_featureinit(void) {
LONGNAME " v" VERSION " successfully loaded");
con_colourmsg(RGBA(255, 255, 255, 255), " for game ");
con_colourmsg(RGBA(0, 255, 255, 255), "%s\n", gameinfo_title);
+
+ // if we're autoloaded and the external autoupdate script downloaded a new
+ // version, let the user know about the cool new stuff!
+ if (getenv("SST_UPDATED")) {
+ // avoid displaying again if we're unloaded and reloaded in one session
+#ifdef _WIN32
+ SetEnvironmentVariableA("SST_UPDATED", 0);
+#else
+ unsetenv("SST_UPDATED");
+#endif
+ struct con_colour gold = {255, 210, 0, 255};
+ struct con_colour white = {255, 255, 255, 255};
+ con_colourmsg(&white, "\n" NAME " was just ");
+ con_colourmsg(&gold, "UPDATED");
+ con_colourmsg(&white, " to version ");
+ con_colourmsg(&gold, "%s", VERSION);
+ con_colourmsg(&white, "!\n\nNew in this version:\n%s\n", updatenotes);
+ }
}
static void *vgui;
@@ -268,6 +291,11 @@ e: con_warn("!!! SOME FEATURES MAY BE BROKEN !!!\n");
}
static bool do_load(ifacefactory enginef, ifacefactory serverf) {
+ if (!hook_init()) {
+ errmsg_warnsys("couldn't set up memory for function hooking");
+ return false;
+ }
+
factory_engine = enginef; factory_server = serverf;
if (!engineapi_init(ifacever)) return false;