mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-07 18:38:37 +00:00
Moved webternet patches to new git repository
This commit is contained in:
parent
58c00f4487
commit
d357d3de6d
81
extensions/curl/FileDownloader.cpp
Normal file
81
extensions/curl/FileDownloader.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod Webternet Extension
|
||||||
|
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||||
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||||
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||||
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FileDownloader.h"
|
||||||
|
|
||||||
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
FileDownloader::FileDownloader( const char *file )
|
||||||
|
{
|
||||||
|
fpLocal = fopen(file, "wb");
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDownloader::~FileDownloader(void)
|
||||||
|
{
|
||||||
|
if(this->fpLocal != NULL)
|
||||||
|
{
|
||||||
|
fclose(this->fpLocal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadWriteStatus FileDownloader::OnDownloadWrite(IWebTransfer *session,
|
||||||
|
void *userdata,
|
||||||
|
void *ptr,
|
||||||
|
size_t size,
|
||||||
|
size_t nmemb)
|
||||||
|
{
|
||||||
|
size_t total = size * nmemb;
|
||||||
|
|
||||||
|
if (this->fpLocal == NULL)
|
||||||
|
{
|
||||||
|
return DownloadWrite_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(ptr, size, nmemb, this->fpLocal) == total)
|
||||||
|
{
|
||||||
|
return DownloadWrite_Okay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DownloadWrite_Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileDownloader::GetSize()
|
||||||
|
{
|
||||||
|
return ftell(this->fpLocal);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *SourceMod::FileDownloader::GetBuffer()
|
||||||
|
{
|
||||||
|
// TODO: implement this!
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
61
extensions/curl/FileDownloader.h
Normal file
61
extensions/curl/FileDownloader.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod Webternet Extension
|
||||||
|
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||||
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||||
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||||
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_CURLEXT_FILE_DOWNLOADER_IMPL_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_CURLEXT_FILE_DOWNLOADER_IMPL_H_
|
||||||
|
|
||||||
|
#include <IBaseDownloader.h>
|
||||||
|
|
||||||
|
namespace SourceMod
|
||||||
|
{
|
||||||
|
class FileDownloader : public IBaseDownloader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileDownloader(const char *file);
|
||||||
|
~FileDownloader(void);
|
||||||
|
|
||||||
|
virtual DownloadWriteStatus OnDownloadWrite(IWebTransfer *session,
|
||||||
|
void *userdata,
|
||||||
|
void *ptr,
|
||||||
|
size_t size,
|
||||||
|
size_t nmemb);
|
||||||
|
|
||||||
|
virtual size_t GetSize();
|
||||||
|
|
||||||
|
virtual char * GetBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE *fpLocal;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
85
extensions/curl/MemoryDownloader.cpp
Normal file
85
extensions/curl/MemoryDownloader.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod Updater Extension
|
||||||
|
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||||
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||||
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||||
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "MemoryDownloader.h"
|
||||||
|
|
||||||
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
MemoryDownloader::MemoryDownloader() : buffer(NULL), bufsize(0), bufpos(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryDownloader::~MemoryDownloader()
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadWriteStatus MemoryDownloader::OnDownloadWrite(IWebTransfer *session,
|
||||||
|
void *userdata,
|
||||||
|
void *ptr,
|
||||||
|
size_t size,
|
||||||
|
size_t nmemb)
|
||||||
|
{
|
||||||
|
size_t total = size * nmemb;
|
||||||
|
|
||||||
|
if (bufpos + total > bufsize)
|
||||||
|
{
|
||||||
|
size_t rem = (bufpos + total) - bufsize;
|
||||||
|
bufsize += rem + (rem / 2);
|
||||||
|
buffer = (char *)realloc(buffer, bufsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(bufpos + total <= bufsize);
|
||||||
|
|
||||||
|
memcpy(&buffer[bufpos], ptr, total);
|
||||||
|
bufpos += total;
|
||||||
|
|
||||||
|
return DownloadWrite_Okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryDownloader::Reset()
|
||||||
|
{
|
||||||
|
bufpos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *MemoryDownloader::GetBuffer()
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MemoryDownloader::GetSize()
|
||||||
|
{
|
||||||
|
return bufpos;
|
||||||
|
}
|
||||||
|
|
||||||
62
extensions/curl/MemoryDownloader.h
Normal file
62
extensions/curl/MemoryDownloader.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod Webternet Extension
|
||||||
|
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||||
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||||
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||||
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_UPDATER_MEMORY_DOWNLOADER_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_UPDATER_MEMORY_DOWNLOADER_H_
|
||||||
|
|
||||||
|
#include <IBaseDownloader.h>
|
||||||
|
|
||||||
|
namespace SourceMod
|
||||||
|
{
|
||||||
|
class MemoryDownloader : public IBaseDownloader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemoryDownloader();
|
||||||
|
~MemoryDownloader();
|
||||||
|
public:
|
||||||
|
DownloadWriteStatus OnDownloadWrite(IWebTransfer *session,
|
||||||
|
void *userdata,
|
||||||
|
void *ptr,
|
||||||
|
size_t size,
|
||||||
|
size_t nmemb);
|
||||||
|
public:
|
||||||
|
void Reset();
|
||||||
|
char *GetBuffer();
|
||||||
|
size_t GetSize();
|
||||||
|
private:
|
||||||
|
char *buffer;
|
||||||
|
size_t bufsize;
|
||||||
|
size_t bufpos;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _INCLUDE_SOURCEMOD_UPDATER_MEMORY_DOWNLOADER_H_ */
|
||||||
|
|
||||||
@ -35,6 +35,9 @@
|
|||||||
#include <sm_platform.h>
|
#include <sm_platform.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "curlapi.h"
|
#include "curlapi.h"
|
||||||
|
#include "FileDownloader.h"
|
||||||
|
#include "MemoryDownloader.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file extension.cpp
|
* @file extension.cpp
|
||||||
@ -45,6 +48,17 @@ CurlExt curl_ext; /**< Global singleton for extension's main interface */
|
|||||||
|
|
||||||
SMEXT_LINK(&curl_ext);
|
SMEXT_LINK(&curl_ext);
|
||||||
|
|
||||||
|
SessionHandler g_SessionHandler;
|
||||||
|
HandleType_t g_SessionHandle = 0;
|
||||||
|
FormHandler g_FormHandler;
|
||||||
|
HandleType_t g_FormHandle = 0;
|
||||||
|
DownloadHandler g_DownloadHandler;
|
||||||
|
HandleType_t g_DownloadHandle = 0;
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
HTTPSessionManager& g_SessionManager = HTTPSessionManager::instance();
|
||||||
|
|
||||||
bool CurlExt::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
bool CurlExt::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||||
{
|
{
|
||||||
long flags;
|
long flags;
|
||||||
@ -68,11 +82,35 @@ bool CurlExt::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register natives
|
||||||
|
g_pShareSys->AddNatives(myself, curlext_natives);
|
||||||
|
// Register session handle handler
|
||||||
|
g_SessionHandle = g_pHandleSys->CreateType("HTTPSession",
|
||||||
|
&g_SessionHandler, 0, 0, NULL, myself->GetIdentity(), NULL);
|
||||||
|
// Register web form handle handler
|
||||||
|
g_FormHandle = g_pHandleSys->CreateType("HTTPWebForm",
|
||||||
|
&g_FormHandler, 0, 0, NULL, myself->GetIdentity(), NULL);
|
||||||
|
// Register web form handle handler
|
||||||
|
g_DownloadHandle = g_pHandleSys->CreateType("HTTPDownloader",
|
||||||
|
&g_DownloadHandler, 0, 0, NULL, myself->GetIdentity(), NULL);
|
||||||
|
plsys->AddPluginsListener(this);
|
||||||
|
smutils->AddGameFrameHook(&OnGameFrame);
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
g_SessionManager.Initialize();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurlExt::SDK_OnUnload()
|
void CurlExt::SDK_OnUnload()
|
||||||
{
|
{
|
||||||
|
g_pHandleSys->RemoveType(g_SessionHandle, myself->GetIdentity());
|
||||||
|
g_pHandleSys->RemoveType(g_FormHandle, myself->GetIdentity());
|
||||||
|
g_pHandleSys->RemoveType(g_DownloadHandle, myself->GetIdentity());
|
||||||
|
plsys->RemovePluginsListener(this);
|
||||||
|
smutils->RemoveGameFrameHook(&OnGameFrame);
|
||||||
|
g_SessionManager.Cleanup();
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,3 +124,754 @@ const char *CurlExt::GetExtensionDateString()
|
|||||||
return SOURCEMOD_BUILD_TIME;
|
return SOURCEMOD_BUILD_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnGameFrame(bool simulating)
|
||||||
|
{
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
g_SessionManager.RunFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurlExt::OnPluginUnloaded( IPlugin *plugin )
|
||||||
|
{
|
||||||
|
g_SessionManager.PluginUnloaded(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_CreateFileDownloader(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
char *file;
|
||||||
|
// 1st param: file name
|
||||||
|
pCtx->LocalToString(params[1], &file);
|
||||||
|
|
||||||
|
char localPath[PLATFORM_MAX_PATH];
|
||||||
|
// Build absolute path for fopen()
|
||||||
|
smutils->BuildPath(Path_Game, localPath, PLATFORM_MAX_PATH, file);
|
||||||
|
|
||||||
|
// Use file-based download handler
|
||||||
|
FileDownloader *downloader = new FileDownloader(localPath);
|
||||||
|
|
||||||
|
// This should never happen but, oh well...
|
||||||
|
if (!downloader)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Could not create downloader");
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_pHandleSys->CreateHandle(g_DownloadHandle,
|
||||||
|
(void*)downloader,
|
||||||
|
pCtx->GetIdentity(),
|
||||||
|
myself->GetIdentity(),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_CreateMemoryDownloader(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
MemoryDownloader *downloader = new MemoryDownloader();
|
||||||
|
|
||||||
|
if (!downloader)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Could not create downloader");
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_pHandleSys->CreateHandle(g_DownloadHandle,
|
||||||
|
(void*)downloader,
|
||||||
|
pCtx->GetIdentity(),
|
||||||
|
myself->GetIdentity(),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_CreateWebForm(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
IWebForm *form = g_webternet.CreateForm();
|
||||||
|
|
||||||
|
if (!form)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Could not create web form");
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_pHandleSys->CreateHandle(g_FormHandle,
|
||||||
|
(void*)form,
|
||||||
|
pCtx->GetIdentity(),
|
||||||
|
myself->GetIdentity(),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_AddStringToWebForm(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
// 1st param: web form handle
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IWebForm *form;
|
||||||
|
|
||||||
|
// Validate handle data
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(hndl, g_FormHandle, &sec, (void **)&form)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid web form handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!form)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Web Form data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *name, *data;
|
||||||
|
// 2nd param: name of the POST variable
|
||||||
|
pCtx->LocalToString(params[2], &name);
|
||||||
|
// 3rd param: value of the POST variable
|
||||||
|
pCtx->LocalToString(params[3], &data);
|
||||||
|
|
||||||
|
return form->AddString(name, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_AddFileToWebForm(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
// 1st param: web form handle
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IWebForm *form;
|
||||||
|
|
||||||
|
// Validate handle data
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(hndl, g_FormHandle, &sec, (void **)&form)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid web form handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!form)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Web Form data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *name, *path;
|
||||||
|
// 2nd param: name of the POST variable
|
||||||
|
pCtx->LocalToString(params[2], &name);
|
||||||
|
// 3rd param: value of the POST variable
|
||||||
|
pCtx->LocalToString(params[3], &path);
|
||||||
|
|
||||||
|
return form->AddFile(name, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_CreateSession(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
IWebTransfer *x = g_webternet.CreateSession();
|
||||||
|
|
||||||
|
if (!x)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Could not create session");
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_pHandleSys->CreateHandle(g_SessionHandle,
|
||||||
|
(void*)x,
|
||||||
|
pCtx->GetIdentity(),
|
||||||
|
myself->GetIdentity(),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_GetLastError(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
// 1st param: session handle
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IWebTransfer *x;
|
||||||
|
|
||||||
|
// Validate handle data
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(hndl, g_SessionHandle, &sec, (void **)&x)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid session handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!x)
|
||||||
|
{
|
||||||
|
pCtx->ThrowNativeError("HTTP Session data not found\n");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy error message in output string
|
||||||
|
pCtx->StringToLocalUTF8(params[2], params[3], x->LastErrorMessage(), NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_PostAndDownload(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
HTTPRequestHandleSet handles;
|
||||||
|
// 1st param: session handle
|
||||||
|
handles.hndlSession = static_cast<Handle_t>(params[1]);
|
||||||
|
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IWebTransfer *x;
|
||||||
|
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(handles.hndlSession,
|
||||||
|
g_SessionHandle, &sec, (void **)&x)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid session handle %x (error %d)",
|
||||||
|
handles.hndlSession, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!x)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Session data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2nd param: downloader handle
|
||||||
|
handles.hndlDownloader = static_cast<Handle_t>(params[2]);
|
||||||
|
IBaseDownloader *downloader;
|
||||||
|
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(handles.hndlDownloader,
|
||||||
|
g_DownloadHandle, &sec, (void **)&downloader)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid downloader handle %x (error %d)",
|
||||||
|
handles.hndlDownloader, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!downloader)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Downloader data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3rd param: web form handle
|
||||||
|
handles.hndlForm = static_cast<Handle_t>(params[3]);;
|
||||||
|
IWebForm *form;
|
||||||
|
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(handles.hndlForm,
|
||||||
|
g_FormHandle, &sec, (void **)&form)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid web form handle %x (error %d)",
|
||||||
|
handles.hndlForm, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!form)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Web Form data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *url;
|
||||||
|
// 4th param: target URL
|
||||||
|
pCtx->LocalToString(params[4], &url);
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
HTTPRequestCompletedContextPack contextPack;
|
||||||
|
contextPack.pCallbackFunction = new HTTPRequestCompletedContextFunction;
|
||||||
|
|
||||||
|
contextPack.pCallbackFunction->pContext = pCtx;
|
||||||
|
// 5th param: callback function
|
||||||
|
contextPack.pCallbackFunction->uPluginFunction = params[5];
|
||||||
|
|
||||||
|
// 6th param: custom user data
|
||||||
|
if (params[0] >= 6)
|
||||||
|
{
|
||||||
|
contextPack.pCallbackFunction->bHasContext = true;
|
||||||
|
contextPack.iPluginContextValue = params[6];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue request for asynchronous execution
|
||||||
|
g_SessionManager.PostAndDownload(pCtx, handles, url, contextPack);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_Download(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
HTTPRequestHandleSet handles;
|
||||||
|
// 1st param: session handle
|
||||||
|
handles.hndlSession = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IWebTransfer *x;
|
||||||
|
|
||||||
|
// Validate handle data
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(handles.hndlSession,
|
||||||
|
g_SessionHandle, &sec, (void **)&x)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid session handle %x (error %d)",
|
||||||
|
handles.hndlSession, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!x)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Session data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2nd param: downloader handle
|
||||||
|
handles.hndlDownloader = static_cast<Handle_t>(params[2]);
|
||||||
|
IBaseDownloader *downloader;
|
||||||
|
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(handles.hndlDownloader,
|
||||||
|
g_DownloadHandle, &sec, (void **)&downloader)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid downloader handle %x (error %d)",
|
||||||
|
handles.hndlDownloader, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!downloader)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Downloader data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *url;
|
||||||
|
// 3rd param: target URL
|
||||||
|
pCtx->LocalToString(params[3], &url);
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
HTTPRequestCompletedContextPack contextPack;
|
||||||
|
contextPack.pCallbackFunction = new HTTPRequestCompletedContextFunction;
|
||||||
|
|
||||||
|
contextPack.pCallbackFunction->pContext = pCtx;
|
||||||
|
// 4th param: callback function
|
||||||
|
contextPack.pCallbackFunction->uPluginFunction = params[4];
|
||||||
|
|
||||||
|
// 5th param: custom user data
|
||||||
|
if (params[0] >= 5)
|
||||||
|
{
|
||||||
|
contextPack.pCallbackFunction->bHasContext = true;
|
||||||
|
contextPack.iPluginContextValue = params[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue request for asynchronous execution
|
||||||
|
g_SessionManager.Download(pCtx, handles, url, contextPack);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_GetBodySize(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
// 1st param: session handle
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IBaseDownloader *dldr = NULL;
|
||||||
|
|
||||||
|
// Validate handle data
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(hndl,
|
||||||
|
g_DownloadHandle, &sec, (void **)&dldr)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid downloader handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dldr)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Downloader data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return dldr->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_GetBodyContent(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
// 1st param: session handle
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IBaseDownloader *dldr = NULL;
|
||||||
|
|
||||||
|
// Validate handle data
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(hndl,
|
||||||
|
g_DownloadHandle, &sec, (void **)&dldr)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid downloader handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dldr)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Downloader data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *body;
|
||||||
|
// 2nd param: receiving buffer
|
||||||
|
pCtx->LocalToString(params[2], &body);
|
||||||
|
// 3rd param: max buffer length
|
||||||
|
uint32_t bodySize = params[3];
|
||||||
|
|
||||||
|
// NOTE: we need one additional byte for the null terminator
|
||||||
|
if (bodySize < (dldr->GetSize() + 1))
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Buffer too small\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(body, dldr->GetBuffer(), params[3]);
|
||||||
|
body[dldr->GetSize()] = '\0';
|
||||||
|
|
||||||
|
return pCtx->StringToLocal(params[2], params[3], body);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t HTTP_SetFailOnHTTPError(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
// 1st param: session handle
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IWebTransfer *xfer;
|
||||||
|
|
||||||
|
// Validate handle data
|
||||||
|
if ((err = g_pHandleSys->ReadHandle(hndl,
|
||||||
|
g_SessionHandle, &sec, (void **)&xfer)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid session handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xfer)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("HTTP Session data not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return xfer->SetFailOnHTTPError(static_cast<bool>(params[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
const sp_nativeinfo_t curlext_natives[] =
|
||||||
|
{
|
||||||
|
{"HTTP_CreateFileDownloader", HTTP_CreateFileDownloader},
|
||||||
|
{"HTTP_CreateMemoryDownloader", HTTP_CreateMemoryDownloader},
|
||||||
|
{"HTTP_CreateSession", HTTP_CreateSession},
|
||||||
|
{"HTTP_SetFailOnHTTPError", HTTP_SetFailOnHTTPError},
|
||||||
|
{"HTTP_GetLastError", HTTP_GetLastError},
|
||||||
|
{"HTTP_Download", HTTP_Download},
|
||||||
|
{"HTTP_PostAndDownload", HTTP_PostAndDownload},
|
||||||
|
{"HTTP_CreateWebForm", HTTP_CreateWebForm},
|
||||||
|
{"HTTP_AddStringToWebForm", HTTP_AddStringToWebForm},
|
||||||
|
{"HTTP_AddFileToWebForm", HTTP_AddFileToWebForm},
|
||||||
|
{"HTTP_GetBodySize", HTTP_GetBodySize},
|
||||||
|
{"HTTP_GetBodyContent", HTTP_GetBodyContent},
|
||||||
|
{NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::PluginUnloaded( IPlugin *plugin )
|
||||||
|
{
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
// Check for pending requests and cancel them
|
||||||
|
{
|
||||||
|
pRequestsLock->Lock();
|
||||||
|
|
||||||
|
if (!requests.empty())
|
||||||
|
{
|
||||||
|
// Run through requests queue
|
||||||
|
for (std::deque<HTTPRequest>::iterator i(requests.begin()), end(requests.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
// Identify requests associated to (nearly) unmapped plugin context
|
||||||
|
if (i->pCtx == plugin->GetBaseContext())
|
||||||
|
{
|
||||||
|
// All context related data and callbacks are marked invalid
|
||||||
|
i->pCtx = NULL;
|
||||||
|
i->contextPack.pCallbackFunction = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pRequestsLock->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for running requests to finish
|
||||||
|
if (!threads.empty())
|
||||||
|
{
|
||||||
|
for (std::list<IThreadHandle*>::iterator i(threads.begin()), end(threads.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
if ((*i) != NULL)
|
||||||
|
{
|
||||||
|
(*i)->WaitForThread();
|
||||||
|
// NOTE: do not remove handles here as it would break
|
||||||
|
// the iteration. Dead thread handles are destroyed
|
||||||
|
// on the next available game frame in the main thread
|
||||||
|
|
||||||
|
// Check for pending callbacks and cancel them
|
||||||
|
{
|
||||||
|
pCallbacksLock->Lock();
|
||||||
|
|
||||||
|
if (!callbacks.empty())
|
||||||
|
{
|
||||||
|
// Run through callback queue
|
||||||
|
for (std::deque<HTTPRequest>::iterator i(callbacks.begin()), end(callbacks.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
// Identify callbacks associated to (nearly) unmapped plugin context
|
||||||
|
if (i->pCtx == plugin->GetBaseContext())
|
||||||
|
{
|
||||||
|
// All context related data and callbacks are marked invalid
|
||||||
|
i->pCtx = NULL;
|
||||||
|
i->contextPack.pCallbackFunction = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pCallbacksLock->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::PostAndDownload( IPluginContext *pCtx,
|
||||||
|
HTTPRequestHandleSet handles, const char *url,
|
||||||
|
HTTPRequestCompletedContextPack contextPack )
|
||||||
|
{
|
||||||
|
HTTPRequest request;
|
||||||
|
BurnSessionHandle(pCtx, handles);
|
||||||
|
|
||||||
|
request.pCtx = pCtx;
|
||||||
|
request.handles = handles;
|
||||||
|
request.method = HTTP_POST;
|
||||||
|
request.url = url;
|
||||||
|
request.contextPack = contextPack;
|
||||||
|
|
||||||
|
pRequestsLock->Lock();
|
||||||
|
this->requests.push_front(request);
|
||||||
|
pRequestsLock->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::Download( IPluginContext *pCtx,
|
||||||
|
HTTPRequestHandleSet handles, const char *url,
|
||||||
|
HTTPRequestCompletedContextPack contextPack )
|
||||||
|
{
|
||||||
|
HTTPRequest request;
|
||||||
|
BurnSessionHandle(pCtx, handles);
|
||||||
|
|
||||||
|
request.pCtx = pCtx;
|
||||||
|
request.handles = handles;
|
||||||
|
request.method = HTTP_GET;
|
||||||
|
request.url = url;
|
||||||
|
request.contextPack = contextPack;
|
||||||
|
|
||||||
|
pRequestsLock->Lock();
|
||||||
|
this->requests.push_front(request);
|
||||||
|
pRequestsLock->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::BurnSessionHandle( IPluginContext * pCtx, HTTPRequestHandleSet &handles )
|
||||||
|
{
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
// TODO: maybe better way to do this?
|
||||||
|
// Make session handle inaccessible to the user
|
||||||
|
Handle_t hndlNew = g_pHandleSys->FastCloneHandle(handles.hndlSession);
|
||||||
|
if (g_pHandleSys->FreeHandle(handles.hndlSession, &sec) !=
|
||||||
|
HandleError_None)
|
||||||
|
{
|
||||||
|
pCtx->ThrowNativeError("Couldn't free HTTP session handle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handles.hndlSession = hndlNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::RunFrame()
|
||||||
|
{
|
||||||
|
// Try to execute pending callbacks
|
||||||
|
if (this->pCallbacksLock->TryLock())
|
||||||
|
{
|
||||||
|
if (!this->callbacks.empty())
|
||||||
|
{
|
||||||
|
HTTPRequest request = this->callbacks.front();
|
||||||
|
IPluginContext *pCtx = request.pCtx;
|
||||||
|
|
||||||
|
// Is the requesting plugin still alive?
|
||||||
|
if (pCtx != NULL)
|
||||||
|
{
|
||||||
|
// TODO: this may be unnecessary
|
||||||
|
if (plsys->FindPluginByContext(request.pCtx->GetContext()))
|
||||||
|
{
|
||||||
|
funcid_t id = request.contextPack.pCallbackFunction->uPluginFunction;
|
||||||
|
IPluginFunction *pFunction = NULL;
|
||||||
|
pFunction = pCtx->GetFunctionById(id);
|
||||||
|
|
||||||
|
if (pFunction != NULL)
|
||||||
|
{
|
||||||
|
// Push data and execute callback
|
||||||
|
pFunction->PushCell(request.handles.hndlSession);
|
||||||
|
pFunction->PushCell(request.result);
|
||||||
|
pFunction->PushCell(request.handles.hndlDownloader);
|
||||||
|
if (request.contextPack.pCallbackFunction->bHasContext)
|
||||||
|
{
|
||||||
|
pFunction->PushCell(request.contextPack.iPluginContextValue);
|
||||||
|
}
|
||||||
|
pFunction->Execute(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->callbacks.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pCallbacksLock->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to fire up some new asynchronous requests
|
||||||
|
if (pRequestsLock->TryLock())
|
||||||
|
{
|
||||||
|
if (!this->requests.empty())
|
||||||
|
{
|
||||||
|
// NOTE: this is my "burst thread creation" solution
|
||||||
|
// Using a thread pool is slow as it executes the threads
|
||||||
|
// sequentially and not parallel.
|
||||||
|
// Not using a thread pool might cause SRCDS to crash, so
|
||||||
|
// we are spawning just a few threads every frame to not
|
||||||
|
// affect performance too much and still having the advantage
|
||||||
|
// of parallel execution.
|
||||||
|
for (unsigned int i = 0; i < iMaxRequestsPerFrame; i++)
|
||||||
|
{
|
||||||
|
// Create new thread object
|
||||||
|
HTTPAsyncRequestHandler *async =
|
||||||
|
new HTTPAsyncRequestHandler(this->requests.front());
|
||||||
|
// Skip requests with unloaded parent plugin
|
||||||
|
if (this->requests.front().pCtx != NULL)
|
||||||
|
{
|
||||||
|
// Create new thread
|
||||||
|
IThreadHandle *pThread =
|
||||||
|
threader->MakeThread(async, Thread_Default);
|
||||||
|
// Save thread handle
|
||||||
|
this->threads.push_front(pThread);
|
||||||
|
}
|
||||||
|
// Remove request as it's being handled now
|
||||||
|
this->requests.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pRequestsLock->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do some quick "garbage collection" on finished threads
|
||||||
|
if (!this->threads.empty())
|
||||||
|
{
|
||||||
|
for (std::list<IThreadHandle*>::iterator i(threads.begin()), end(threads.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
if ((*i) != NULL)
|
||||||
|
{
|
||||||
|
if ((*i)->GetState() == Thread_Done)
|
||||||
|
{
|
||||||
|
(*i)->DestroyThis();
|
||||||
|
this->threads.remove((*i));
|
||||||
|
// NOTE: this action breaks the iteration so we have
|
||||||
|
// to leave the loop and start over on next frame
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::Initialize()
|
||||||
|
{
|
||||||
|
pRequestsLock = threader->MakeMutex();
|
||||||
|
pCallbacksLock = threader->MakeMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::Cleanup()
|
||||||
|
{
|
||||||
|
if (pRequestsLock != NULL)
|
||||||
|
{
|
||||||
|
pRequestsLock->DestroyThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCallbacksLock != NULL)
|
||||||
|
{
|
||||||
|
pCallbacksLock->DestroyThis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::AddCallback( HTTPRequest request )
|
||||||
|
{
|
||||||
|
this->pCallbacksLock->Lock();
|
||||||
|
this->callbacks.push_front(request);
|
||||||
|
this->pCallbacksLock->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
void HTTPSessionManager::HTTPAsyncRequestHandler::RunThread( IThreadHandle *pHandle )
|
||||||
|
{
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = this->request.pCtx->GetIdentity();
|
||||||
|
sec.pIdentity = myself->GetIdentity();
|
||||||
|
|
||||||
|
IWebTransfer *xfer = NULL;
|
||||||
|
g_pHandleSys->ReadHandle(this->request.handles.hndlSession,
|
||||||
|
g_SessionHandle, &sec, (void **)&xfer);
|
||||||
|
|
||||||
|
IBaseDownloader *downldr = NULL;
|
||||||
|
g_pHandleSys->ReadHandle(this->request.handles.hndlDownloader,
|
||||||
|
g_DownloadHandle, &sec, (void **)&downldr);
|
||||||
|
|
||||||
|
switch (this->request.method)
|
||||||
|
{
|
||||||
|
case HTTP_GET:
|
||||||
|
this->request.result =
|
||||||
|
xfer->Download(this->request.url, downldr, NULL);
|
||||||
|
break;
|
||||||
|
case HTTP_POST:
|
||||||
|
IWebForm *form = NULL;
|
||||||
|
g_pHandleSys->ReadHandle(this->request.handles.hndlForm,
|
||||||
|
g_FormHandle, &sec, (void **)&form);
|
||||||
|
|
||||||
|
this->request.result =
|
||||||
|
xfer->PostAndDownload(this->request.url, form, downldr, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
//g_pHandleSys->FreeHandle(this->request.handles.hndlDownloader, &sec);
|
||||||
|
//smutils->AddFrameAction(ExecuteCallback, new HTTPRequest(this->request));
|
||||||
|
g_SessionManager.AddCallback(request);
|
||||||
|
}
|
||||||
|
|||||||
@ -38,13 +38,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "smsdk_ext.h"
|
#include "smsdk_ext.h"
|
||||||
|
#include "IWebternet.h"
|
||||||
|
#include "IBaseDownloader.h"
|
||||||
|
#include <queue>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sample implementation of the SDK Extension.
|
* @brief Sample implementation of the SDK Extension.
|
||||||
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
|
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
|
||||||
*/
|
*/
|
||||||
class CurlExt : public SDKExtension
|
class CurlExt : public SDKExtension, IPluginsListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -83,6 +87,9 @@ public:
|
|||||||
//virtual bool QueryRunning(char *error, size_t maxlength);
|
//virtual bool QueryRunning(char *error, size_t maxlength);
|
||||||
const char *GetExtensionVerString();
|
const char *GetExtensionVerString();
|
||||||
const char *GetExtensionDateString();
|
const char *GetExtensionDateString();
|
||||||
|
|
||||||
|
virtual void OnPluginUnloaded( IPlugin *plugin );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if defined SMEXT_CONF_METAMOD
|
#if defined SMEXT_CONF_METAMOD
|
||||||
/**
|
/**
|
||||||
@ -121,4 +128,146 @@ public:
|
|||||||
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
|
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
|
||||||
size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list ap);
|
size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list ap);
|
||||||
|
|
||||||
|
// Handle helper class
|
||||||
|
class SessionHandler : public IHandleTypeDispatch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void OnHandleDestroy( HandleType_t type, void *object )
|
||||||
|
{
|
||||||
|
delete ((IWebTransfer *)object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SessionHandler g_SessionHandler;
|
||||||
|
extern HandleType_t g_SessionHandle;
|
||||||
|
|
||||||
|
class FormHandler : public IHandleTypeDispatch
|
||||||
|
{
|
||||||
|
virtual void OnHandleDestroy( HandleType_t type, void *object )
|
||||||
|
{
|
||||||
|
delete ((IWebForm *)object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FormHandler g_FormHandler;
|
||||||
|
extern HandleType_t g_FormHandle;
|
||||||
|
|
||||||
|
class DownloadHandler : public IHandleTypeDispatch
|
||||||
|
{
|
||||||
|
virtual void OnHandleDestroy( HandleType_t type, void *object )
|
||||||
|
{
|
||||||
|
delete ((IBaseDownloader *)object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DownloadHandler g_DownloadHandler;
|
||||||
|
extern HandleType_t g_DownloadHandle;
|
||||||
|
|
||||||
|
struct HTTPRequestCompletedContextFunction {
|
||||||
|
// NOTE: deprecated!
|
||||||
|
IPluginContext *pContext;
|
||||||
|
funcid_t uPluginFunction;
|
||||||
|
bool bHasContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
union HTTPRequestCompletedContextPack {
|
||||||
|
uint64_t ulContextValue;
|
||||||
|
struct {
|
||||||
|
HTTPRequestCompletedContextFunction *pCallbackFunction;
|
||||||
|
cell_t iPluginContextValue;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NEW CODE */
|
||||||
|
/************************************************************************/
|
||||||
|
struct HTTPRequestHandleSet
|
||||||
|
{
|
||||||
|
Handle_t hndlSession;
|
||||||
|
Handle_t hndlDownloader;
|
||||||
|
Handle_t hndlForm;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HTTPSessionManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static HTTPSessionManager& instance()
|
||||||
|
{
|
||||||
|
static HTTPSessionManager _instance;
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
~HTTPSessionManager() {}
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
void Cleanup();
|
||||||
|
void PluginUnloaded(IPlugin *plugin);
|
||||||
|
void RunFrame();
|
||||||
|
void BurnSessionHandle(IPluginContext * pCtx, HTTPRequestHandleSet &handles);
|
||||||
|
void PostAndDownload(IPluginContext *pCtx,
|
||||||
|
HTTPRequestHandleSet handles,
|
||||||
|
const char *url,
|
||||||
|
HTTPRequestCompletedContextPack contextPack);
|
||||||
|
void Download(IPluginContext *pCtx,
|
||||||
|
HTTPRequestHandleSet handles,
|
||||||
|
const char *url,
|
||||||
|
HTTPRequestCompletedContextPack contextPack);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
HTTPSessionManager() {}
|
||||||
|
HTTPSessionManager(const HTTPSessionManager&);
|
||||||
|
HTTPSessionManager & operator = (const HTTPSessionManager &);
|
||||||
|
|
||||||
|
enum HTTPRequestMethod
|
||||||
|
{
|
||||||
|
HTTP_GET,
|
||||||
|
HTTP_POST
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HTTPRequest
|
||||||
|
{
|
||||||
|
IPluginContext *pCtx;
|
||||||
|
HTTPRequestMethod method;
|
||||||
|
HTTPRequestHandleSet handles;
|
||||||
|
const char *url;
|
||||||
|
HTTPRequestCompletedContextPack contextPack;
|
||||||
|
cell_t result;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned int iMaxRequestsPerFrame = 20;
|
||||||
|
IMutex *pRequestsLock;
|
||||||
|
std::deque<HTTPRequest> requests;
|
||||||
|
// NOTE: this needs no lock since it's only accessed from main thread
|
||||||
|
std::list<IThreadHandle*> threads;
|
||||||
|
IMutex *pCallbacksLock;
|
||||||
|
std::deque<HTTPRequest> callbacks;
|
||||||
|
|
||||||
|
class HTTPAsyncRequestHandler : public IThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HTTPAsyncRequestHandler(HTTPRequest request)
|
||||||
|
{
|
||||||
|
this->request = request;
|
||||||
|
}
|
||||||
|
~HTTPAsyncRequestHandler() {}
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
HTTPRequest request;
|
||||||
|
virtual void RunThread( IThreadHandle *pHandle );
|
||||||
|
virtual void OnTerminate( IThreadHandle *pHandle, bool cancel )
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
static void ExecuteCallback(void *data);
|
||||||
|
};
|
||||||
|
|
||||||
|
void AddCallback(HTTPRequest request);
|
||||||
|
};
|
||||||
|
|
||||||
|
void OnGameFrame(bool simulating);
|
||||||
|
|
||||||
|
// Natives
|
||||||
|
extern const sp_nativeinfo_t curlext_natives[];
|
||||||
|
|
||||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||||
|
|||||||
98
extensions/curl/msvc10/curl.sln
Normal file
98
extensions/curl/msvc10/curl.sln
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
|
# Visual Studio 2010
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curl", "curl.vcxproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curllib", "..\curl-src\lib\curllib.vcxproj", "{32E22C76-2FE8-2308-E702-DB81C76357DB}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curlsrc", "..\curl-src\src\curlsrc.vcxproj", "{1E99F660-6BDD-C14B-4931-6D6FCFB83177}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB} = {32E22C76-2FE8-2308-E702-DB81C76357DB}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
DLL Debug|Win32 = DLL Debug|Win32
|
||||||
|
DLL Release|Win32 = DLL Release|Win32
|
||||||
|
LIB Debug|Win32 = LIB Debug|Win32
|
||||||
|
LIB Release|Win32 = LIB Release|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Template|Win32 = Template|Win32
|
||||||
|
using libcurl DLL Debug|Win32 = using libcurl DLL Debug|Win32
|
||||||
|
using libcurl DLL Release|Win32 = using libcurl DLL Release|Win32
|
||||||
|
using libcurl LIB Debug|Win32 = using libcurl LIB Debug|Win32
|
||||||
|
using libcurl LIB Release|Win32 = using libcurl LIB Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.DLL Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.DLL Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.DLL Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.DLL Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.LIB Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.LIB Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.LIB Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.LIB Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Template|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Template|Win32.Build.0 = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl DLL Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl DLL Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl DLL Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl DLL Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl LIB Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl LIB Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl LIB Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.using libcurl LIB Release|Win32.Build.0 = Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.Debug|Win32.ActiveCfg = LIB Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.Debug|Win32.Build.0 = LIB Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.LIB Debug|Win32.ActiveCfg = LIB Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.LIB Debug|Win32.Build.0 = LIB Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.LIB Release|Win32.ActiveCfg = LIB Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.LIB Release|Win32.Build.0 = LIB Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.Release|Win32.ActiveCfg = LIB Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.Release|Win32.Build.0 = LIB Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.Template|Win32.ActiveCfg = LIB Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.Template|Win32.Build.0 = LIB Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl LIB Debug|Win32.ActiveCfg = LIB Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl LIB Debug|Win32.Build.0 = LIB Debug|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl LIB Release|Win32.ActiveCfg = LIB Release|Win32
|
||||||
|
{32E22C76-2FE8-2308-E702-DB81C76357DB}.using libcurl LIB Release|Win32.Build.0 = LIB Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.Debug|Win32.ActiveCfg = using libcurl LIB Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.Debug|Win32.Build.0 = using libcurl LIB Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.DLL Debug|Win32.ActiveCfg = using libcurl DLL Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.DLL Debug|Win32.Build.0 = using libcurl DLL Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.DLL Release|Win32.ActiveCfg = using libcurl DLL Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.DLL Release|Win32.Build.0 = using libcurl DLL Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.LIB Debug|Win32.ActiveCfg = using libcurl LIB Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.LIB Debug|Win32.Build.0 = using libcurl LIB Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.LIB Release|Win32.ActiveCfg = using libcurl LIB Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.LIB Release|Win32.Build.0 = using libcurl LIB Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.Release|Win32.ActiveCfg = using libcurl LIB Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.Release|Win32.Build.0 = using libcurl LIB Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.Template|Win32.ActiveCfg = Template|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.Template|Win32.Build.0 = Template|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl DLL Debug|Win32.ActiveCfg = using libcurl DLL Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl DLL Debug|Win32.Build.0 = using libcurl DLL Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl DLL Release|Win32.ActiveCfg = using libcurl DLL Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl DLL Release|Win32.Build.0 = using libcurl DLL Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl LIB Debug|Win32.ActiveCfg = using libcurl LIB Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl LIB Debug|Win32.Build.0 = using libcurl LIB Debug|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl LIB Release|Win32.ActiveCfg = using libcurl LIB Release|Win32
|
||||||
|
{1E99F660-6BDD-C14B-4931-6D6FCFB83177}.using libcurl LIB Release|Win32.Build.0 = using libcurl LIB Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@ -60,18 +60,18 @@
|
|||||||
|
|
||||||
/** Enable interfaces you want to use here by uncommenting lines */
|
/** Enable interfaces you want to use here by uncommenting lines */
|
||||||
//#define SMEXT_ENABLE_FORWARDSYS
|
//#define SMEXT_ENABLE_FORWARDSYS
|
||||||
//#define SMEXT_ENABLE_HANDLESYS
|
#define SMEXT_ENABLE_HANDLESYS
|
||||||
//#define SMEXT_ENABLE_PLAYERHELPERS
|
//#define SMEXT_ENABLE_PLAYERHELPERS
|
||||||
//#define SMEXT_ENABLE_DBMANAGER
|
//#define SMEXT_ENABLE_DBMANAGER
|
||||||
//#define SMEXT_ENABLE_GAMECONF
|
//#define SMEXT_ENABLE_GAMECONF
|
||||||
//#define SMEXT_ENABLE_MEMUTILS
|
//#define SMEXT_ENABLE_MEMUTILS
|
||||||
//#define SMEXT_ENABLE_GAMEHELPERS
|
//#define SMEXT_ENABLE_GAMEHELPERS
|
||||||
//#define SMEXT_ENABLE_TIMERSYS
|
//#define SMEXT_ENABLE_TIMERSYS
|
||||||
//#define SMEXT_ENABLE_THREADER
|
#define SMEXT_ENABLE_THREADER
|
||||||
//#define SMEXT_ENABLE_LIBSYS
|
//#define SMEXT_ENABLE_LIBSYS
|
||||||
//#define SMEXT_ENABLE_MENUS
|
//#define SMEXT_ENABLE_MENUS
|
||||||
//#define SMEXT_ENABLE_ADTFACTORY
|
//#define SMEXT_ENABLE_ADTFACTORY
|
||||||
//#define SMEXT_ENABLE_PLUGINSYS
|
#define SMEXT_ENABLE_PLUGINSYS
|
||||||
//#define SMEXT_ENABLE_ADMINSYS
|
//#define SMEXT_ENABLE_ADMINSYS
|
||||||
//#define SMEXT_ENABLE_TEXTPARSERS
|
//#define SMEXT_ENABLE_TEXTPARSERS
|
||||||
//#define SMEXT_ENABLE_USERMSGS
|
//#define SMEXT_ENABLE_USERMSGS
|
||||||
|
|||||||
@ -50,7 +50,7 @@ BEGIN
|
|||||||
VALUE "FileVersion", SM_VERSION_STRING
|
VALUE "FileVersion", SM_VERSION_STRING
|
||||||
VALUE "InternalName", "SourceMod Webternet Extension"
|
VALUE "InternalName", "SourceMod Webternet Extension"
|
||||||
VALUE "LegalCopyright", "Copyright (c) 2004-2009, AlliedModders LLC"
|
VALUE "LegalCopyright", "Copyright (c) 2004-2009, AlliedModders LLC"
|
||||||
VALUE "OriginalFilename", BINARY_NAME
|
VALUE "OriginalFilename", "webternet.ext.dll"
|
||||||
VALUE "ProductName", "SourceMod Webternet Extension"
|
VALUE "ProductName", "SourceMod Webternet Extension"
|
||||||
VALUE "ProductVersion", SM_VERSION_STRING
|
VALUE "ProductVersion", SM_VERSION_STRING
|
||||||
END
|
END
|
||||||
|
|||||||
58
plugins/include/webternet.inc
Normal file
58
plugins/include/webternet.inc
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#if defined _webternet_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _webternet_included
|
||||||
|
|
||||||
|
#define HTTP_OK 1
|
||||||
|
#define HTTP_ERROR 0
|
||||||
|
|
||||||
|
funcenum HTTP_SessionCallback {
|
||||||
|
public(Handle:session, result),
|
||||||
|
public(Handle:session, result, Handle:downloader),
|
||||||
|
public(Handle:session, result, Handle:downloader, any:data),
|
||||||
|
};
|
||||||
|
|
||||||
|
native Handle:HTTP_CreateSession();
|
||||||
|
|
||||||
|
native HTTP_SetFailOnHTTPError(Handle:session, bool:fail);
|
||||||
|
|
||||||
|
native HTTP_GetLastError(Handle:session, String:error[], maxlen);
|
||||||
|
|
||||||
|
native Handle:HTTP_CreateFileDownloader(const String:file[]);
|
||||||
|
|
||||||
|
native Handle:HTTP_CreateMemoryDownloader();
|
||||||
|
|
||||||
|
native HTTP_Download(Handle:session, Handle:downloader, const String:url[], HTTP_SessionCallback:callback, any:data = INVALID_HANDLE);
|
||||||
|
|
||||||
|
native HTTP_PostAndDownload(Handle:session, Handle:downloader, Handle:form, const String:url[], HTTP_SessionCallback:callback, any:data = INVALID_HANDLE);
|
||||||
|
|
||||||
|
native Handle:HTTP_CreateWebForm();
|
||||||
|
|
||||||
|
native HTTP_AddStringToWebForm(Handle:form, const String:name[], const String:data[]);
|
||||||
|
|
||||||
|
native HTTP_AddFileToWebForm(Handle:form, const String:name[], const String:path[]);
|
||||||
|
|
||||||
|
native HTTP_GetBodySize(Handle:downloader);
|
||||||
|
|
||||||
|
native HTTP_GetBodyContent(Handle:downloader, String:body[], maxlen);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not edit below this line!
|
||||||
|
*/
|
||||||
|
public Extension:__ext_webternet =
|
||||||
|
{
|
||||||
|
name = "webternet",
|
||||||
|
file = "webternet.ext",
|
||||||
|
#if defined AUTOLOAD_EXTENSIONS
|
||||||
|
autoload = 1,
|
||||||
|
#else
|
||||||
|
autoload = 0,
|
||||||
|
#endif
|
||||||
|
#if defined REQUIRE_EXTENSIONS
|
||||||
|
required = 1,
|
||||||
|
#else
|
||||||
|
required = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
|
||||||
# Visual Studio 2008
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamedatamd5", "gamedatamd5.vcproj", "{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@ -1,219 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="9.00"
|
|
||||||
Name="gamedatamd5"
|
|
||||||
ProjectGUID="{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
|
|
||||||
Keyword="Win32Proj"
|
|
||||||
TargetFrameworkVersion="0"
|
|
||||||
>
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"
|
|
||||||
/>
|
|
||||||
</Platforms>
|
|
||||||
<ToolFiles>
|
|
||||||
</ToolFiles>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="Debug"
|
|
||||||
IntermediateDirectory="Debug"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="2"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
|
|
||||||
MinimalRebuild="true"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="1"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="false"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
LinkIncremental="2"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="1"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="Release"
|
|
||||||
IntermediateDirectory="Release"
|
|
||||||
ConfigurationType="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
|
|
||||||
RuntimeLibrary="0"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="false"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
LinkIncremental="2"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="1"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
EnableCOMDATFolding="2"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Header Files"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\main.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\md5.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sm_memtable.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\TextParsers.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Resource Files"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Source Files"
|
|
||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\main.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\md5.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sm_memtable.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\TextParsers.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
||||||
Loading…
Reference in New Issue
Block a user