|
@@ -9,13 +9,18 @@
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include "mmsplugin.h"
|
|
#include "mmsplugin.h"
|
|
|
|
|
|
-#include <fcntl.h>
|
|
|
|
-#include <gelf.h>
|
|
|
|
#include <utlmap.h>
|
|
#include <utlmap.h>
|
|
#include <utlstring.h>
|
|
#include <utlstring.h>
|
|
#include <KeyValues.h>
|
|
#include <KeyValues.h>
|
|
#include <filesystem.h>
|
|
#include <filesystem.h>
|
|
|
|
|
|
|
|
+#if WINDOWS
|
|
|
|
+#include <windows.h>
|
|
|
|
+#elif _LINUX
|
|
|
|
+#include <fcntl.h>
|
|
|
|
+#include <gelf.h>
|
|
|
|
+#endif
|
|
|
|
+
|
|
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
|
|
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
|
|
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, 0, bool, char const *, char const *, char const *, char const *, bool, bool);
|
|
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, 0, bool, char const *, char const *, char const *, char const *, bool, bool);
|
|
|
|
|
|
@@ -74,6 +79,26 @@ typedef bool (__cdecl *CEconItemAttributeInitFromKV_fn)(CEconItemAttributeDefini
|
|
#endif
|
|
#endif
|
|
CEconItemAttributeInitFromKV_fn fnItemAttributeInitFromKV = nullptr;
|
|
CEconItemAttributeInitFromKV_fn fnItemAttributeInitFromKV = nullptr;
|
|
|
|
|
|
|
|
+uintptr_t FindPattern(uintptr_t start, uintptr_t end, const char* pattern, size_t length) {
|
|
|
|
+ uintptr_t ptr = start;
|
|
|
|
+ bool f;
|
|
|
|
+ while (ptr < end - length) {
|
|
|
|
+ f = true;
|
|
|
|
+ const char* cur = reinterpret_cast<char*>(ptr);
|
|
|
|
+ for (register size_t i = 0; i < length; i++) {
|
|
|
|
+ if (pattern[i] != '\x2A' && pattern[i] != cur[i]) {
|
|
|
|
+ f = false;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (f) {
|
|
|
|
+ return ptr;
|
|
|
|
+ }
|
|
|
|
+ ptr++;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
bool DynSchema::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
|
|
bool DynSchema::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
|
|
{
|
|
{
|
|
PLUGIN_SAVEVARS();
|
|
PLUGIN_SAVEVARS();
|
|
@@ -86,20 +111,33 @@ bool DynSchema::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, boo
|
|
|
|
|
|
// get the base address of the server
|
|
// get the base address of the server
|
|
// TODO windows support
|
|
// TODO windows support
|
|
|
|
+#if WINDOWS
|
|
|
|
+ MEMORY_BASIC_INFORMATION info;
|
|
|
|
+ if (!VirtualQuery(server, &info, sizeof(MEMORY_BASIC_INFORMATION))) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ uintptr_t base = reinterpret_cast<uintptr_t>(info.AllocationBase);
|
|
|
|
+ IMAGE_DOS_HEADER *dos = reinterpret_cast<IMAGE_DOS_HEADER *>(base);
|
|
|
|
+ IMAGE_NT_HEADERS *pe = reinterpret_cast<IMAGE_NT_HEADERS *>(base + dos->e_lfanew);
|
|
|
|
+ IMAGE_OPTIONAL_HEADER *opt = &pe->OptionalHeader;
|
|
|
|
+ size_t size = opt->SizeOfImage;
|
|
|
|
+
|
|
|
|
+ fnGetEconItemSchema = (GetEconItemSchemaFn_t*) (FindPattern(base, base + size, "\xE8\x2A\x2A\x2A\x2A\x83\xC0\x04\xC3", 9));
|
|
|
|
+ fnItemAttributeInitFromKV = (CEconItemAttributeInitFromKV_fn) (FindPattern(base, base + size, "\x55\x8B\xEC\x53\x8B\x5D\x08\x56\x8B\xF1\x8B\xCB\x57\xE8\x2A\x2A\x2A\x2A", 18));
|
|
|
|
+#elif _LINUX
|
|
Dl_info info;
|
|
Dl_info info;
|
|
if (!dladdr(server, &info)) {
|
|
if (!dladdr(server, &info)) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// locate symbols within our server binary
|
|
// locate symbols within our server binary
|
|
- Elf_Scn *scn = NULL;
|
|
|
|
- GElf_Shdr shdr;
|
|
|
|
-
|
|
|
|
elf_version(EV_CURRENT);
|
|
elf_version(EV_CURRENT);
|
|
|
|
|
|
int fd = open(info.dli_fname, O_RDONLY);
|
|
int fd = open(info.dli_fname, O_RDONLY);
|
|
Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
|
|
Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
|
|
|
|
|
|
|
|
+ Elf_Scn *scn = NULL;
|
|
|
|
+ GElf_Shdr shdr;
|
|
while ((scn = elf_nextscn(elf, scn)) != NULL) {
|
|
while ((scn = elf_nextscn(elf, scn)) != NULL) {
|
|
gelf_getshdr(scn, &shdr);
|
|
gelf_getshdr(scn, &shdr);
|
|
if (shdr.sh_type == SHT_SYMTAB) {
|
|
if (shdr.sh_type == SHT_SYMTAB) {
|
|
@@ -111,9 +149,9 @@ bool DynSchema::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, boo
|
|
size_t count = shdr.sh_size / shdr.sh_entsize;
|
|
size_t count = shdr.sh_size / shdr.sh_entsize;
|
|
|
|
|
|
/* print the symbol names */
|
|
/* print the symbol names */
|
|
- for (size_t ii = 0; ii < count; ++ii) {
|
|
|
|
|
|
+ for (size_t i = 0; i < count; ++i) {
|
|
GElf_Sym sym;
|
|
GElf_Sym sym;
|
|
- gelf_getsym(data, ii, &sym);
|
|
|
|
|
|
+ gelf_getsym(data, i, &sym);
|
|
|
|
|
|
const char *symname = elf_strptr(elf, shdr.sh_link, sym.st_name);
|
|
const char *symname = elf_strptr(elf, shdr.sh_link, sym.st_name);
|
|
if (!strcmp(symname,
|
|
if (!strcmp(symname,
|
|
@@ -125,9 +163,10 @@ bool DynSchema::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, boo
|
|
}
|
|
}
|
|
elf_end(elf);
|
|
elf_end(elf);
|
|
close(fd);
|
|
close(fd);
|
|
|
|
+#endif
|
|
|
|
|
|
if (!fnItemAttributeInitFromKV || !fnGetEconItemSchema) {
|
|
if (!fnItemAttributeInitFromKV || !fnGetEconItemSchema) {
|
|
- META_CONPRINTF("Failed to get either GEconItemSchema or BInitFromKeyValues\n");
|
|
|
|
|
|
+ META_CONPRINTF("Failed to get GEIS or BIFKV\n");
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -188,7 +227,7 @@ bool DynSchema::Hook_LevelInitPost(const char *pMapName, char const *pMapEntitie
|
|
}
|
|
}
|
|
META_CONPRINTF("Successfully injected custom schema %s\n", buffer);
|
|
META_CONPRINTF("Successfully injected custom schema %s\n", buffer);
|
|
} else {
|
|
} else {
|
|
- META_CONPRINTF("Failed to locate not inject custom schema %s\n", buffer);
|
|
|
|
|
|
+ META_CONPRINTF("Failed to inject custom schema %s\n", buffer);
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
return true;
|
|
@@ -213,7 +252,7 @@ const char *DynSchema::GetLicense() {
|
|
}
|
|
}
|
|
|
|
|
|
const char *DynSchema::GetVersion() {
|
|
const char *DynSchema::GetVersion() {
|
|
- return "1.0.0.0";
|
|
|
|
|
|
+ return "1.0.1";
|
|
}
|
|
}
|
|
|
|
|
|
const char *DynSchema::GetDate() {
|
|
const char *DynSchema::GetDate() {
|