VM_uri_escape, // #510 string(string in) uri_escape = #510;
VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
-NULL, // #513
+VM_uri_get, // #513 float(string uril, float id) uri_get = #512; (DP_QC_URI_GET)
NULL, // #514
NULL, // #515
NULL, // #516
"DP_QC_TOKENIZEBYSEPARATOR "
"DP_QC_UNLIMITEDTEMPSTRINGS "
"DP_QC_URI_ESCAPE "
+"DP_QC_URI_GET "
"DP_QC_WHICHPACK "
"FTE_STRINGS "
;
VM_uri_escape, // #510 string(string in) uri_escape = #510;
VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
-NULL, // #513
+VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
NULL, // #514
NULL, // #515
NULL, // #516
func_t SV_OnEntityNoSpawnFunction; // ssqc
func_t GameCommand; // any
func_t SV_Shutdown; // ssqc
+ func_t URI_Get_Callback; // any
// menu qc only uses some functions, nothing else
func_t m_draw; // mqc
#include "quakedef.h"
#include "prvm_cmds.h"
+#include "libcurl.h"
#include <time.h>
extern cvar_t prvm_backtraceforwarnings;
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(pack ? pack : "");
}
+typedef struct
+{
+ int prognr;
+ double starttime;
+ float id;
+ char buffer[MAX_INPUTLINE];
+}
+uri_to_prog_t;
+
+static void uri_to_string_callback(int status, size_t length_received, unsigned char *buffer, void *cbdata)
+{
+ uri_to_prog_t *handle = cbdata;
+
+ if(!PRVM_ProgLoaded(handle->prognr))
+ {
+ // curl reply came too late... so just drop it
+ Z_Free(handle);
+ return;
+ }
+
+ PRVM_SetProg(handle->prognr);
+ PRVM_Begin;
+ if((prog->starttime == handle->starttime) && (prog->funcoffsets.URI_Get_Callback))
+ {
+ if(length_received >= sizeof(handle->buffer))
+ length_received = sizeof(handle->buffer) - 1;
+ handle->buffer[length_received] = 0;
+
+ PRVM_G_FLOAT(OFS_PARM0) = handle->id;
+ PRVM_G_FLOAT(OFS_PARM1) = status;
+ PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(handle->buffer);
+ PRVM_ExecuteProgram(prog->funcoffsets.URI_Get_Callback, "QC function URI_Get_Callback is missing");
+ }
+ PRVM_End;
+
+ Z_Free(handle);
+}
+
+// uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned
+// returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string
+void VM_uri_get (void)
+{
+ const char *url;
+ float id;
+ qboolean ret;
+ uri_to_prog_t *handle;
+
+ if(!prog->funcoffsets.URI_Get_Callback)
+ PRVM_ERROR("uri_get called by %s without URI_Get_Callback defined", PRVM_NAME);
+
+ url = PRVM_G_STRING(OFS_PARM0);
+ id = PRVM_G_FLOAT(OFS_PARM1);
+ handle = Z_Malloc(sizeof(*handle)); // this can't be the prog's mem pool, as curl may call the callback later!
+
+ handle->prognr = PRVM_GetProgNr();
+ handle->starttime = prog->starttime;
+ handle->id = id;
+ ret = Curl_Begin_ToMemory(url, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle);
+ if(ret)
+ {
+ PRVM_G_INT(OFS_RETURN) = 1;
+ }
+ else
+ {
+ Z_Free(handle);
+ PRVM_G_INT(OFS_RETURN) = 0;
+ }
+}
void VM_whichpack (void);
void VM_etof (void);
+void VM_uri_get (void);
prog->funcoffsets.SV_OnEntityNoSpawnFunction = PRVM_ED_FindFunctionOffset("SV_OnEntityNoSpawnFunction");
prog->funcoffsets.GameCommand = PRVM_ED_FindFunctionOffset("GameCommand");
prog->funcoffsets.SV_Shutdown = PRVM_ED_FindFunctionOffset("SV_Shutdown");
+ prog->funcoffsets.URI_Get_Callback = PRVM_ED_FindFunctionOffset("URI_Get_Callback");
prog->globaloffsets.SV_InitCmd = PRVM_ED_FindGlobalOffset("SV_InitCmd");
prog->globaloffsets.self = PRVM_ED_FindGlobalOffset("self");
prog->globaloffsets.time = PRVM_ED_FindGlobalOffset("time");
"DP_QC_TRACE_MOVETYPE_WORLDONLY "
"DP_QC_UNLIMITEDTEMPSTRINGS "
"DP_QC_URI_ESCAPE "
+"DP_QC_URI_GET "
"DP_QC_VECTOANGLES_WITH_ROLL "
"DP_QC_VECTORVECTORS "
"DP_QC_WHICHPACK "
VM_uri_escape, // #510 string(string in) uri_escape = #510;
VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
-NULL, // #513
+VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
NULL, // #514
NULL, // #515
NULL, // #516