diff --git a/update_tool/api_link.asm b/update_tool/api_link.asm
index af93081..7ebcc81 100644
--- a/update_tool/api_link.asm
+++ b/update_tool/api_link.asm
@@ -16,10 +16,15 @@
section .text
-global GetThisPointer, GetGameDir
-global _GetThisPointer, _GetGameDir
+global GetThisPointer, GetGameDir, ServerCommand
+global _GetThisPointer, _GetGameDir, _ServerCommand
+global _GetICvar
extern _LoadFunction
+_GetICvar
+ mov eax, [icvar]
+ ret
+
GetThisPointer:
_GetThisPointer:
mov eax, GLOBAL_POINTER
@@ -44,21 +49,42 @@ _GetGameDir:
pop ebp
ret
-
+
+ServerCommand
+_ServerCommand:
+ push ebp
+ mov ebp, esp
+
+ mov ecx, [engine] ;get this pointer
+ mov edx, [ecx] ;get the vtable
+ push dword [ebp+8] ;push string
+ %ifdef LINUX
+ push ecx ;push this pointer
+ %endif
+ call dword [edx+144] ;call IVEngineServer::ServerCommand
+ %ifdef LINUX
+ add esp, 8 ;correct stack
+ %endif
+
+ pop ebp
+ ret
+
thisLoadFunction:
push ebp
mov ebp, esp
+ push edi
+
;get factory
%ifdef LINUX
- mov eax, [ebp+12]
+ mov edi, [ebp+12]
%else
- mov eax, [ebp+8]
+ mov edi, [ebp+8]
%endif
push dword 0 ;NULL
push dword VENGINESERVER ;iface name
- call eax ;call factory
+ call edi ;call factory
add esp, 8 ;correct stack
test eax, eax ;do we have a valid pointer?
@@ -66,11 +92,24 @@ thisLoadFunction:
mov [engine], eax ;store the engine pointer
+ push dword 0 ;NULL
+ push dword VENGINECVAR ;iface name
+ call edi ;call factory
+ add esp, 8 ;correct stack
+
+ test eax, eax ;do we have a valid pointer?
+ jz .end ;no, bail out
+
+ mov [icvar], eax ;store the icvar pointer
+
call _LoadFunction
.end:
;We never load, never ever ever!
xor eax, eax
+
+ pop edi
+
pop ebp
%ifdef LINUX
ret
@@ -84,6 +123,7 @@ thisUnloadFunction:
section .data
INTERFACE_NAME DB "ISERVERPLUGINCALLBACKS001", 0
VENGINESERVER DB "VEngineServer021", 0
+ VENGINECVAR DB "VEngineCvar003", 0
VIRTUAL_TABLE DD thisLoadFunction
DD thisUnloadFunction
@@ -94,3 +134,4 @@ section .data
temp_ret DD 0
temp_ptr DD temp_ret
engine DD 0
+ icvar DD 0
\ No newline at end of file
diff --git a/update_tool/msvc8/update_tool.vcproj b/update_tool/msvc8/update_tool.vcproj
index dc09f92..f1c905c 100644
--- a/update_tool/msvc8/update_tool.vcproj
+++ b/update_tool/msvc8/update_tool.vcproj
@@ -24,7 +24,7 @@
>
#include
-extern "C" void GetGameDir(char *buffer, int maxlength);
-extern "C" void *GetThisPointer();
-
#if defined _MSC_VER
#define SEPCHAR "\\"
#define MMPATH "addons\\metamod\\bin"
@@ -17,9 +14,17 @@ extern "C" void *GetThisPointer();
#include
#endif
+#include
+
+extern "C" void GetGameDir(char *buffer, int maxlength);
+extern "C" void *GetThisPointer();
+extern "C" void ServerCommand(const char *command);
+extern "C" ICvar *GetICvar();
+
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
bool s_isspace(char c);
bool RenameFile(const char *old, const char *newf);
+bool RemoveFile(const char *file);
/* This will be called by the thunk */
#if defined _MSC_VER
@@ -28,6 +33,13 @@ extern "C" void LoadFunction()
extern "C" void _LoadFunction()
#endif
{
+ ICvar *pCvar = GetICvar();
+ if (pCvar->FindVar("metamod_version") != NULL)
+ {
+ /* Already exists, bail out */
+ return;
+ }
+
char gamedir[260];
char mmpath[260];
@@ -141,6 +153,8 @@ extern "C" void _LoadFunction()
char input[1024];
char backup[1024];
+
+ bool bWroteOutput = false;
while (!feof(fp) && fgets(input, sizeof(input), fp) != NULL)
{
@@ -199,10 +213,11 @@ extern "C" void _LoadFunction()
op = NULL;
break; /* Nothing more to do! */
} else {
- fputs("\t\t\tGameBin\t\t\t|gameinfo_path|", op);
+ fputs("\t\t\tGameBin\t\t\t", op);
fputs(mmpath, op);
fputs("\n", op);
ps = Parse_None;
+ bWroteOutput = true;
}
}
}
@@ -222,6 +237,13 @@ extern "C" void _LoadFunction()
fclose(op);
fclose(fp);
+ /* If we didn't change anything, abort here */
+ if (!bWroteOutput)
+ {
+ RemoveFile(new_path);
+ return;
+ }
+
/* Move the old file to a backup name */
char backup_name[260];
UTIL_Format(backup_name, sizeof(backup_name), "%s" SEPCHAR "gameinfo.backup.txt", gamedir);
@@ -242,10 +264,17 @@ extern "C" void _LoadFunction()
RenameFile(backup_name, old_path);
return;
}
+ RemoveFile(new_path);
+
+ Error("Server is restarting to load Metamod:Source");
+}
+
+bool RemoveFile(const char *file)
+{
#if defined _MSC_VER
- _unlink(new_path);
+ return (_unlink(file) == 0);
#else
- unlink(new_path);
+ return (unlink(file) == 0);
#endif
}