/** * vim: set ts=4 : * ============================================================================= * SourceMod REST in Pawn Extension * Copyright 2017-2026 Erik Minekus * ============================================================================= * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * 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 . */ #ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ #define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ #include #include #include #include #include #include #include #include "smsdk_ext.h" #define SM_RIPEXT_CA_BUNDLE_PATH "configs/ripext/ca-bundle.crt" #define SM_RIPEXT_USER_AGENT "sm-ripext/" SMEXT_CONF_VERSION extern uv_loop_t *g_Loop; typedef StringHashMap HTTPHeaderMap; class IHTTPContext { public: virtual bool InitCurl() = 0; virtual void OnCompleted() = 0; virtual ~IHTTPContext() {} CURL *curl; }; struct CurlContext { CurlContext(curl_socket_t socket) : socket(socket) { uv_poll_init_socket(g_Loop, &poll_handle, socket); poll_handle.data = this; } void Destroy() { uv_poll_stop(&poll_handle); uv_close((uv_handle_t *)&poll_handle, OnClosed); } static void OnClosed(uv_handle_t *handle) { delete (CurlContext *)handle->data; } curl_socket_t socket; uv_poll_t poll_handle; }; struct HTTPResponse { long status = 0; json_t *data = NULL; Handle_t hndlData = BAD_HANDLE; HTTPHeaderMap headers; char *body = NULL; size_t size = 0; }; struct JSONObjectKeys { JSONObjectKeys(json_t *object) : object(object), iter(json_object_iter(object)) {} const char *GetKey() { return json_object_iter_key(iter); } void Next() { iter = json_object_iter_next(object, iter); } private: json_t *object; void *iter; }; /** * @brief Implementation of the REST in Pawn Extension. * Note: Uncomment one of the pre-defined virtual functions in order to use it. */ class RipExt : public SDKExtension { public: /** * @brief This is called after the initial loading sequence has been processed. * * @param error Error message buffer. * @param maxlength Size of error message buffer. * @param late Whether or not the module was loaded after map load. * @return True to succeed loading, false to fail. */ virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); /** * @brief This is called right before the extension is unloaded. */ virtual void SDK_OnUnload(); /** * @brief This is called once all known extensions have been loaded. * Note: It is is a good idea to add natives here, if any are provided. */ //virtual void SDK_OnAllLoaded(); /** * @brief Called when the pause state is changed. */ //virtual void SDK_OnPauseChange(bool paused); /** * @brief this is called when Core wants to know if your extension is working. * * @param error Error message buffer. * @param maxlength Size of error message buffer. * @return True if working, false otherwise. */ //virtual bool QueryRunning(char *error, size_t maxlength); public: #if defined SMEXT_CONF_METAMOD /** * @brief Called when Metamod is attached, before the extension version is called. * * @param error Error buffer. * @param maxlength Maximum size of error buffer. * @param late Whether or not Metamod considers this a late load. * @return True to succeed, false to fail. */ //virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); /** * @brief Called when Metamod is detaching, after the extension version is called. * NOTE: By default this is blocked unless sent from SourceMod. * * @param error Error buffer. * @param maxlength Maximum size of error buffer. * @return True to succeed, false to fail. */ //virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); /** * @brief Called when Metamod's pause state is changing. * NOTE: By default this is blocked unless sent from SourceMod. * * @param paused Pause state being set. * @param error Error buffer. * @param maxlength Maximum size of error buffer. * @return True to succeed, false to fail. */ //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); #endif public: void AddRequestToQueue(IHTTPContext *context); char caBundlePath[PLATFORM_MAX_PATH]; }; class HTTPClientHandler : public IHandleTypeDispatch { public: void OnHandleDestroy(HandleType_t type, void *object); }; class HTTPRequestHandler : public IHandleTypeDispatch { public: void OnHandleDestroy(HandleType_t type, void *object); }; class HTTPResponseHandler : public IHandleTypeDispatch { public: void OnHandleDestroy(HandleType_t type, void *object); }; class JSONHandler : public IHandleTypeDispatch { public: void OnHandleDestroy(HandleType_t type, void *object); }; class JSONObjectKeysHandler : public IHandleTypeDispatch { public: void OnHandleDestroy(HandleType_t type, void *object); }; extern RipExt g_RipExt; extern HTTPClientHandler g_HTTPClientHandler; extern HandleType_t htHTTPClient; extern HTTPRequestHandler g_HTTPRequestHandler; extern HandleType_t htHTTPRequest; extern HTTPResponseHandler g_HTTPResponseHandler; extern HandleType_t htHTTPResponse; extern JSONHandler g_JSONHandler; extern HandleType_t htJSON; extern JSONObjectKeysHandler g_JSONObjectKeysHandler; extern HandleType_t htJSONObjectKeys; extern const sp_nativeinfo_t http_natives[]; extern const sp_nativeinfo_t json_natives[]; #endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_