123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- #ifndef _CLIENT_GAMEMODE_H_
- #define _CLIENT_GAMEMODE_H_
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <dlfcn.h>
- #include <errno.h>
- #include <string.h>
- char _client_error_string[512] = { 0 };
- volatile int _libgamemode_loaded = 1;
- typedef int (*_gamemode_request_start)(void);
- typedef int (*_gamemode_request_end)(void);
- typedef const char *(*_gamemode_error_string)(void);
- _gamemode_request_start _REAL_gamemode_request_start = NULL;
- _gamemode_request_end _REAL_gamemode_request_end = NULL;
- _gamemode_error_string _REAL_gamemode_error_string = NULL;
- __attribute__((always_inline)) inline int _bind_libgamemode_symbol(void *handle, const char *name,
- void **out_func,
- size_t func_size)
- {
- void *symbol_lookup = NULL;
- char *dl_error = NULL;
-
- symbol_lookup = dlsym(handle, name);
- dl_error = dlerror();
- if (dl_error || !symbol_lookup) {
- snprintf(_client_error_string, sizeof(_client_error_string), "dlsym failed - %s", dl_error);
- return -1;
- }
-
- memcpy(out_func, &symbol_lookup, func_size);
- return 0;
- }
- __attribute__((always_inline)) inline int _load_libgamemode(void)
- {
-
- if (_libgamemode_loaded != 1) {
- return _libgamemode_loaded;
- }
-
- struct binding {
- const char *name;
- void **functor;
- size_t func_size;
- } bindings[] = {
- { "real_gamemode_request_start",
- (void **)&_REAL_gamemode_request_start,
- sizeof(_REAL_gamemode_request_start) },
- { "real_gamemode_request_end",
- (void **)&_REAL_gamemode_request_end,
- sizeof(_REAL_gamemode_request_end) },
- { "real_gamemode_error_string",
- (void **)&_REAL_gamemode_error_string,
- sizeof(_REAL_gamemode_error_string) },
- };
- void *libgamemode = NULL;
-
- libgamemode = dlopen("libgamemode.so", RTLD_NOW);
- if (!libgamemode) {
- snprintf(_client_error_string,
- sizeof(_client_error_string),
- "dylopen failed - %s",
- dlerror());
- _libgamemode_loaded = -1;
- return -1;
- }
-
- for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) {
- struct binding *binder = &bindings[i];
- if (_bind_libgamemode_symbol(libgamemode,
- binder->name,
- binder->functor,
- binder->func_size) != 0) {
- _libgamemode_loaded = -1;
- return -1;
- };
- }
-
- _libgamemode_loaded = 0;
- return 0;
- }
- __attribute__((always_inline)) inline const char *gamemode_error_string(void)
- {
-
- if (_load_libgamemode() < 0) {
- return _client_error_string;
- }
- return _REAL_gamemode_error_string();
- }
- #ifdef GAMEMODE_AUTO
- __attribute__((constructor))
- #else
- __attribute__((always_inline)) inline
- #endif
- int gamemode_request_start(void)
- {
-
- if (_load_libgamemode() < 0) {
- #ifdef GAMEMODE_AUTO
- fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
- #endif
- return -1;
- }
- if (_REAL_gamemode_request_start() < 0) {
- #ifdef GAMEMODE_AUTO
- fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
- #endif
- return -1;
- }
- return 0;
- }
- #ifdef GAMEMODE_AUTO
- __attribute__((destructor))
- #else
- __attribute__((always_inline)) inline
- #endif
- int gamemode_request_end(void)
- {
-
- if (_load_libgamemode() < 0) {
- #ifdef GAMEMODE_AUTO
- fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
- #endif
- return -1;
- }
- if (_REAL_gamemode_request_end() < 0) {
- #ifdef GAMEMODE_AUTO
- fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
- #endif
- return -1;
- }
- return 0;
- }
- #endif
|