add extension DP_QC_URI_GET (downloads HTTP/whatever URLs to QC strings using a callback)
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 12 Sep 2008 08:14:24 +0000 (08:14 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 12 Sep 2008 08:14:24 +0000 (08:14 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8502 d7cf8633-e32d-0410-b094-e92efae38249

clvm_cmds.c
mvm_cmds.c
progsvm.h
prvm_cmds.c
prvm_cmds.h
prvm_edict.c
svvm_cmds.c

index 16c9ce8..f1d3b4a 100644 (file)
@@ -3487,7 +3487,7 @@ NULL,                                                     // #509
 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
index 0581a1c..5b507dd 100644 (file)
@@ -26,6 +26,7 @@ char *vm_m_extensions =
 "DP_QC_TOKENIZEBYSEPARATOR "
 "DP_QC_UNLIMITEDTEMPSTRINGS "
 "DP_QC_URI_ESCAPE "
+"DP_QC_URI_GET "
 "DP_QC_WHICHPACK "
 "FTE_STRINGS "
 ;
@@ -1356,7 +1357,7 @@ NULL,                                                                     // #509
 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
index 41640fc..cabd7b4 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -286,6 +286,7 @@ typedef struct prvm_prog_funcoffsets_s
        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
index 82cbb3f..2a4ebc8 100644 (file)
@@ -7,6 +7,7 @@
 #include "quakedef.h"
 
 #include "prvm_cmds.h"
+#include "libcurl.h"
 #include <time.h>
 
 extern cvar_t prvm_backtraceforwarnings;
@@ -4846,3 +4847,71 @@ void VM_whichpack (void)
        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;
+       }
+}
index d6ab827..54c8d7d 100644 (file)
@@ -429,3 +429,4 @@ void VM_uri_unescape (void);
 void VM_whichpack (void);
 
 void VM_etof (void);
+void VM_uri_get (void);
index 65ba909..7c6e16c 100644 (file)
@@ -1482,6 +1482,7 @@ void PRVM_FindOffsets(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");
index d7fe26d..a042dee 100644 (file)
@@ -92,6 +92,7 @@ char *vm_sv_extensions =
 "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 "
@@ -3411,7 +3412,7 @@ NULL,                                                     // #509
 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