### Complete Player Data System Example in Pawn Source: https://context7.com/southclaws/pawn-requests/llms.txt This example demonstrates a full player data system using the Pawn Requests library. It covers initializing the API client, handling player connections and disconnections, loading player data via GET requests, saving player data via PUT requests, and managing JSON data structures. It also includes error handling for requests. ```pawn #include #include new RequestsClient:g_ApiClient; new Request:g_PlayerRequests[MAX_PLAYERS]; public OnGameModeInit() { g_ApiClient = RequestsClient("https://api.myserver.com/", RequestHeaders( "Authorization", "Bearer server-api-key", "Content-Type", "application/json" )); if (!IsValidRequestsClient(g_ApiClient)) { print("[ERROR] Failed to create API client!"); return 0; } print("[INFO] API client initialized"); return 1; } public OnPlayerConnect(playerid) { new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name)); new path[64]; format(path, sizeof(path), "players/%s", name); g_PlayerRequests[playerid] = RequestJSON( g_ApiClient, path, HTTP_METHOD_GET, "OnPlayerDataLoaded" ); return 1; } forward OnPlayerDataLoaded(Request:id, E_HTTP_STATUS:status, Node:node); public OnPlayerDataLoaded(Request:id, E_HTTP_STATUS:status, Node:node) { new playerid = GetPlayerFromRequest(id); if (playerid == INVALID_PLAYER_ID) return; if (status == HTTP_STATUS_NOT_FOUND) { // New player, create default data SendClientMessage(playerid, -1, "Welcome new player!"); return; } if (status != HTTP_STATUS_OK) { printf("[ERROR] Failed to load player %d data: %d", playerid, _:status); return; } // Load player data from JSON new score, money; new Float:x, Float:y, Float:z; JsonGetInt(node, "score", score); JsonGetInt(node, "money", money); new Node:position; if (JsonGetObject(node, "position", position) == 0) { JsonGetFloat(position, "x", x); JsonGetFloat(position, "y", y); JsonGetFloat(position, "z", z); SetPlayerPos(playerid, x, y, z); } SetPlayerScore(playerid, score); GivePlayerMoney(playerid, money); SendClientMessage(playerid, -1, "Your data has been loaded!"); } public OnPlayerDisconnect(playerid, reason) { SavePlayerData(playerid); return 1; } SavePlayerData(playerid) { new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name)); new Float:x, Float:y, Float:z; GetPlayerPos(playerid, x, y, z); new Node:data = JsonObject( "name", JsonString(name), "score", JsonInt(GetPlayerScore(playerid)), "money", JsonInt(GetPlayerMoney(playerid)), "position", JsonObject( "x", JsonFloat(x), "y", JsonFloat(y), "z", JsonFloat(z) ), "lastSeen", JsonInt(gettime()) ); new path[64]; format(path, sizeof(path), "players/%s", name); RequestJSON(g_ApiClient, path, HTTP_METHOD_PUT, "OnPlayerDataSaved", data); } forward OnPlayerDataSaved(Request:id, E_HTTP_STATUS:status, Node:node); public OnPlayerDataSaved(Request:id, E_HTTP_STATUS:status, Node:node) { if (status == HTTP_STATUS_OK || status == HTTP_STATUS_CREATED) { print("[INFO] Player data saved successfully"); } else { printf("[ERROR] Failed to save player data: %d", _:status); } } public OnRequestFailure(Request:id, errorCode, errorMessage[], len) { printf("[ERROR] Request %d failed: [%d] %s", _:id, errorCode, errorMessage); } GetPlayerFromRequest(Request:id) { for (new i = 0; i < MAX_PLAYERS; i++) { if (g_PlayerRequests[i] == id) { g_PlayerRequests[i] = Request:-1; return i; } } return INVALID_PLAYER_ID; } ``` -------------------------------- ### Install Pawn Requests Library Source: https://context7.com/southclaws/pawn-requests/llms.txt Installs the Pawn Requests library using the sampctl package manager and includes it in your Pawn code. ```bash sampctl package install Southclaws/pawn-requests ``` ```pawn #include ``` -------------------------------- ### Install pawn-requests Package Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Installs the pawn-requests package using the sampctl package manager. This command should be run in your project's root directory. ```bash sampctl package install Southclaws/pawn-requests ``` -------------------------------- ### CMake: Basic Setup and SAMPSDK Integration Source: https://github.com/southclaws/pawn-requests/blob/master/src/CMakeLists.txt Initializes Conan build information and sets up the basic build environment. It then finds and includes the SAMPSDK, making its include directories available for the project. This is crucial for building SAMP plugins. ```cmake include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup(NO_OUTPUT_DIRS) include(AMXConfig) include(AddSAMPPlugin) set(SAMP_SDK_ROOT "${CMAKE_SOURCE_DIR}/lib/samp-plugin-sdk") find_package(SAMPSDK REQUIRED) include_directories( ${SAMPSDK_INCLUDE_DIR} ) ``` -------------------------------- ### Perform HTTP Requests with Various Methods (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt Demonstrates how to perform various HTTP requests (GET, POST, PUT, PATCH, DELETE) using the RequestsClient. It shows how to construct JSON payloads for requests that require them and specifies callback functions for handling responses. ```pawn // Available HTTP methods // HTTP_METHOD_GET - Retrieve data // HTTP_METHOD_HEAD - Get headers only // HTTP_METHOD_POST - Submit data // HTTP_METHOD_PUT - Replace resource // HTTP_METHOD_DELETE - Remove resource // HTTP_METHOD_CONNECT - Establish tunnel // HTTP_METHOD_OPTIONS - Get allowed methods // HTTP_METHOD_TRACE - Debug loop-back // HTTP_METHOD_PATCH - Partial update new RequestsClient:client = RequestsClient("https://api.example.com/"); // GET - Retrieve a resource RequestJSON(client, "users/123", HTTP_METHOD_GET, "OnGetUser"); // POST - Create a resource RequestJSON(client, "users", HTTP_METHOD_POST, "OnCreateUser", JsonObject("name", JsonString("NewUser")) ); // PUT - Replace a resource RequestJSON(client, "users/123", HTTP_METHOD_PUT, "OnUpdateUser", JsonObject("name", JsonString("UpdatedName"), "email", JsonString("new@email.com")) ); // PATCH - Partial update RequestJSON(client, "users/123", HTTP_METHOD_PATCH, "OnPatchUser", JsonObject("email", JsonString("patched@email.com")) ); // DELETE - Remove a resource RequestJSON(client, "users/123", HTTP_METHOD_DELETE, "OnDeleteUser"); ``` -------------------------------- ### Include pawn-requests Library Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Includes the pawn-requests library in your Pawn code to start using its functionalities. This is a prerequisite for making any HTTP requests. ```pawn #include ``` -------------------------------- ### Perform Text HTTP Requests with Pawn Requests Source: https://context7.com/southclaws/pawn-requests/llms.txt Shows how to perform HTTP requests for plain text data using the Request function. It covers GET and POST methods, sending data in the request body, and handling asynchronous responses via a callback function. The callback processes the HTTP status and received data. ```pawn new RequestsClient:client; new Request:requestId; main() { client = RequestsClient("http://httpbin.org/"); // Make a GET request for text data requestId = Request( client, "robots.txt", HTTP_METHOD_GET, "OnTextResponse", .headers = RequestHeaders() ); if (!IsValidRequest(requestId)) { print("Failed to create request!"); } } forward OnTextResponse(Request:id, E_HTTP_STATUS:status, data[], dataLen); public OnTextResponse(Request:id, E_HTTP_STATUS:status, data[], dataLen) { if (status == HTTP_STATUS_OK) { printf("Response received (%d bytes):", dataLen); print(data); } else { printf("Request failed with status: %d", _:status); } } // POST request with text body Request( client, "post", HTTP_METHOD_POST, "OnPostResponse", "This is the request body", RequestHeaders("Content-Type", "text/plain") ); ``` -------------------------------- ### CMake: Configure Conan Dependency Management Source: https://github.com/southclaws/pawn-requests/blob/master/CMakeLists.txt This snippet configures Conan to manage project dependencies, specifically requesting the 'cpprestsdk' version 2.10.18. It sets up basic build environment setup and specifies the target architecture as x86. Ensure the 'conan.cmake' file is present in the specified path. ```cmake cmake_minimum_required(VERSION 3.20) project(requests) list(APPEND CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR};${CMAKE_SOURCE_DIR}/lib/cmake-modules") list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}) if(WIN32) if(NOT DEFINED ENV{CONAN_VCVARS_VER}) set(ENV{CONAN_VCVARS_VER} "14.4") endif() if(NOT DEFINED ENV{VCVARS_VER}) set(ENV{VCVARS_VER} "14.4") endif() if(NOT DEFINED ENV{VSCMD_ARG_VCVARS_VER}) set(ENV{VSCMD_ARG_VCVARS_VER} "14.4") endif() endif() set(CONAN_CMAKE_FILE "${CMAKE_SOURCE_DIR}/lib/cmake-conan/conan.cmake") if(NOT EXISTS "${CONAN_CMAKE_FILE}") message(FATAL_ERROR "Missing ${CONAN_CMAKE_FILE}; ensure the vendored conan.cmake is present in the repository.") endif() include("${CONAN_CMAKE_FILE}") conan_cmake_run(REQUIRES cpprestsdk/2.10.18 BASIC_SETUP BUILD missing SETTINGS arch=x86) ``` -------------------------------- ### Access JSON Arrays: Get, Length, Elements (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt Provides functions to interact with JSON arrays. JsonGetArray retrieves an array by key, JsonArrayLength returns the number of elements, and JsonArrayObject accesses individual elements by index. Error codes are returned for failures. ```pawn // JSON: {"inventory":[{"name":"M4","ammo":120},{"name":"Deagle","ammo":35}]} forward OnInventoryData(Request:id, E_HTTP_STATUS:status, Node:node); public OnInventoryData(Request:id, E_HTTP_STATUS:status, Node:node) { new Node:inventory; new ret = JsonGetArray(node, "inventory", inventory); if (ret != 0) { print("Failed to get inventory array"); return; } new length; ret = JsonArrayLength(inventory, length); if (ret != 0) { print("Failed to get array length"); return; } printf("Inventory has %d items:", length); for (new i = 0; i < length; i++) { new Node:item; ret = JsonArrayObject(inventory, i, item); if (ret != 0) { printf("Failed to get item %d", i); continue; } new itemName[32]; new ammo; JsonGetString(item, "name", itemName); JsonGetInt(item, "ammo", ammo); printf(" [%d] %s - %d ammo", i, itemName, ammo); } } ``` -------------------------------- ### Get Nested JSON Objects and Values (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt Allows access to nested JSON objects using JsonGetObject and extraction of primitive values from Node references with JsonGetNode* functions. This is useful for navigating complex JSON structures, including elements within arrays. ```pawn // JSON: {"player":{"stats":{"kills":150,"deaths":45}}} forward OnStatsData(Request:id, E_HTTP_STATUS:status, Node:node); public OnStatsData(Request:id, E_HTTP_STATUS:status, Node:node) { // Get nested object new Node:player; JsonGetObject(node, "player", player); new Node:stats; JsonGetObject(player, "stats", stats); // Method 1: Direct access with JsonGet* new kills, deaths; JsonGetInt(stats, "kills", kills); JsonGetInt(stats, "deaths", deaths); // Method 2: Get node then extract with JsonGetNode* new Node:killsNode; JsonGetObject(stats, "kills", killsNode); new killsValue; JsonGetNodeInt(killsNode, killsValue); printf("Kills: %d, Deaths: %d, K/D: %.2f", kills, deaths, float(kills) / float(deaths)); } // Working with array of primitives // JSON: {"scores":[100,250,500]} new Node:scoresArray; JsonGetArray(node, "scores", scoresArray); new length; JsonArrayLength(scoresArray, length); for (new i = 0; i < length; i++) { new Node:scoreNode; JsonArrayObject(scoresArray, i, scoreNode); new score; JsonGetNodeInt(scoreNode, score); printf("Score %d: %d", i, score); } ``` -------------------------------- ### Build and Test Pawn Plugin on Windows Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Instructions for building and running unit tests for the Pawn plugin on Windows using Visual Studio and CMake. It covers initializing and updating git submodules, building the debug and release versions of the plugin, and locating the compiled .dll files. ```powershell make test-windows-debug ``` -------------------------------- ### Create HTTP Client with Pawn Requests Source: https://context7.com/southclaws/pawn-requests/llms.txt Demonstrates how to create an HTTP client using the RequestsClient function. Clients can be initialized with a base URL and optional authentication or custom headers, which are then applied to all subsequent requests made with that client. ```pawn // Create a basic HTTP client new RequestsClient:client; main() { client = RequestsClient("https://api.example.com/"); if (!IsValidRequestsClient(client)) { print("Failed to create client!"); return; } printf("Client created: %d", _:client); } // Create a client with authentication headers new RequestsClient:authClient; main() { authClient = RequestsClient("https://api.example.com/", RequestHeaders( "Authorization", "Bearer your-api-token", "Content-Type", "application/json", "X-Custom-Header", "custom-value" )); } ``` -------------------------------- ### Get JSON Node Type (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt The JsonNodeType function returns the type of a JSON node, which is essential for validating data before attempting to extract it. It supports types like JSON_NODE_NUMBER, JSON_NODE_BOOLEAN, JSON_NODE_STRING, JSON_NODE_OBJECT, JSON_NODE_ARRAY, and JSON_NODE_NULL. ```pawn new Node:node; JsonParse("{\"name\":\"test\",\"count\":5,\"active\":true,\"items\":[1,2,3]}", node); // Check types before accessing new Node:nameNode; JsonGetObject(node, "name", nameNode); if (JsonNodeType(nameNode) == JSON_NODE_STRING) { new name[32]; JsonGetNodeString(nameNode, name); printf("Name is a string: %s", name); } // Validate node types new Node:testNode = JsonInt(42); switch (JsonNodeType(testNode)) { case JSON_NODE_NUMBER: print("It's a number"); case JSON_NODE_BOOLEAN: print("It's a boolean"); case JSON_NODE_STRING: print("It's a string"); case JSON_NODE_OBJECT: print("It's an object"); case JSON_NODE_ARRAY: print("It's an array"); case JSON_NODE_NULL: print("It's null"); } // JSON_NODE enum values: // JSON_NODE_NUMBER, JSON_NODE_BOOLEAN, JSON_NODE_STRING // JSON_NODE_OBJECT, JSON_NODE_ARRAY, JSON_NODE_NULL ``` -------------------------------- ### Build Pawn Plugin for Linux on Windows Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Command to build the Linux version of the Pawn plugin from a Windows machine using Docker. This process generates the 'requests.so' file in the './test/plugins' directory. ```powershell make build-linux ``` -------------------------------- ### Run Unit Tests for Pawn Plugin on Linux Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Command to execute unit tests for the Pawn plugin on a Linux environment. The tests are run using 'sampctl' with the '--container' flag, ensuring a consistent testing environment. ```powershell make test-linux ``` -------------------------------- ### RequestsClient API Source: https://context7.com/southclaws/pawn-requests/llms.txt This section details how to create and configure an HTTP client for making requests to a base endpoint. Clients can be initialized with or without authentication headers. ```APIDOC ## RequestsClient API ### Description Creates a new HTTP client with a base endpoint URL. The client is reused for multiple requests to the same server. Headers set on the client are sent with every request. ### Method `RequestsClient(const url[], RequestHeaders:headers = RequestHeaders()) ` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```pawn // Create a basic HTTP client new RequestsClient:client; main() { client = RequestsClient("https://api.example.com/"); if (!IsValidRequestsClient(client)) { print("Failed to create client!"); return; } printf("Client created: %d", _:client); } // Create a client with authentication headers new RequestsClient:authClient; main() { authClient = RequestsClient("https://api.example.com/", RequestHeaders( "Authorization", "Bearer your-api-token", "Content-Type", "application/json", "X-Custom-Header", "custom-value" )); } ``` ### Response #### Success Response (200) Returns a valid `RequestsClient` handle if successful, otherwise an invalid handle. #### Response Example ```json { "example": "Client created: 1" } ``` ``` -------------------------------- ### Create Empty JSON Object (Pawn) Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Demonstrates how to initialize an empty JSON object using the JsonObject() function in Pawn. This is the root for building more complex JSON structures. ```pawn new Node:node = JsonObject(); ``` -------------------------------- ### Create Requests Client with Headers Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Initializes a RequestsClient with a base endpoint and custom headers. These headers will be sent with every request made using this client, useful for authentication or setting default request properties. ```pawn new RequestsClient:client; main() { client = RequestsClient("http://httpbin.org/", RequestHeaders( "Authorization", "Bearer xyz" )); } ``` -------------------------------- ### Configure CMakeSettings.json for C++ Development Source: https://github.com/southclaws/pawn-requests/blob/master/README.md This JSON configuration file is used by Visual Studio to manage CMake projects. It specifies build configurations (Debug/Release), generator settings, build roots, and crucial CMake variables like CMAKE_TOOLCHAIN_FILE, which points to the vcpkg toolchain file for dependency management. ```json { "configurations": [ { "name": "x86-Release", "generator": "Visual Studio 15 2017", "configurationType": "Release", "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-m -v:minimal", "variables": [ { "name": "CMAKE_TOOLCHAIN_FILE", "value": "C:/Users/Southclaws/vcpkg/scripts/buildsystems/vcpkg.cmake" } ] }, { "name": "x86-Debug", "generator": "Visual Studio 15 2017", "configurationType": "Debug", "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-m -v:minimal", "variables": [ { "name": "CMAKE_TOOLCHAIN_FILE", "value": "C:/Users/Southclaws/vcpkg/scripts/buildsystems/vcpkg.cmake" } ] } ] } ``` -------------------------------- ### CMake: Add SAMP Plugin Source Files Source: https://github.com/southclaws/pawn-requests/blob/master/src/CMakeLists.txt Defines the main plugin target named 'requests' and lists all its source files, including those from the SAMPSDK and project-specific headers and source files. This command compiles the plugin. ```cmake add_samp_plugin(requests ${SAMPSDK_DIR}/amxplugin.cpp ${SAMPSDK_DIR}/amxplugin2.cpp ${SAMPSDK_DIR}/amx/getch.c common.hpp requests.cpp impl.cpp impl.hpp natives.cpp natives.hpp plugin.def ) ``` -------------------------------- ### Request API (Plain Text) Source: https://context7.com/southclaws/pawn-requests/llms.txt This section covers making HTTP requests for plain text data. It details how to send requests with various HTTP methods and handle text-based responses asynchronously. ```APIDOC ## Request API (Plain Text) ### Description Performs an HTTP request to send or receive plain text data. The response is delivered asynchronously to the specified callback function. ### Method `Request(RequestsClient:client, const url[], E_HTTP_METHOD:method, const callback[], const body[] = "", RequestHeaders:headers = RequestHeaders()) ` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **client** (RequestsClient) - The client handle to use for the request. - **url** (const string) - The endpoint path relative to the client's base URL. - **method** (E_HTTP_METHOD) - The HTTP method to use (e.g., `HTTP_METHOD_GET`, `HTTP_METHOD_POST`). - **callback** (const string) - The name of the forward function to call with the response. - **body** (const string, optional) - The plain text data to send in the request body. Defaults to an empty string. - **headers** (RequestHeaders, optional) - A `RequestHeaders` object containing custom headers. Defaults to an empty header set. ### Request Example ```pawn new RequestsClient:client; new Request:requestId; main() { client = RequestsClient("http://httpbin.org/"); // Make a GET request for text data requestId = Request( client, "robots.txt", HTTP_METHOD_GET, "OnTextResponse", .headers = RequestHeaders() ); if (!IsValidRequest(requestId)) { print("Failed to create request!"); } } forward OnTextResponse(Request:id, E_HTTP_STATUS:status, data[], dataLen); public OnTextResponse(Request:id, E_HTTP_STATUS:status, data[], dataLen) { if (status == HTTP_STATUS_OK) { printf("Response received (%d bytes):\n", dataLen); print(data); } else { printf("Request failed with status: %d", _:status); } } // POST request with text body Request( client, "post", HTTP_METHOD_POST, "OnPostResponse", "This is the request body", RequestHeaders("Content-Type", "text/plain") ); ``` ### Response #### Success Response (200) - **id** (Request) - A handle to the created request. - **status** (E_HTTP_STATUS) - The HTTP status code of the response. - **data** (char[]) - A buffer containing the response body data. - **dataLen** (integer) - The length of the data in the response buffer. #### Response Example ```json { "example": "Response received (123 bytes):\nHello, world!" } ``` ``` -------------------------------- ### CMake: MSVC Post-Build Copy Command Source: https://github.com/southclaws/pawn-requests/blob/master/src/CMakeLists.txt For MSVC builds, this defines a custom command that executes after the 'requests' target is built. It copies the generated 'requests.dll' from the build directory to the project's test plugins directory. ```cmake if (MSVC) add_custom_command( TARGET requests POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/requests.dll ${CMAKE_SOURCE_DIR}/test/plugins/requests.dll) endif() ``` -------------------------------- ### HTTP Methods API Source: https://context7.com/southclaws/pawn-requests/llms.txt Provides functionality to make HTTP requests using various standard HTTP methods. ```APIDOC ## HTTP Methods API ### Description The library supports all standard HTTP methods through the E_HTTP_METHOD enumeration for making various API calls. ### Available HTTP Methods - `HTTP_METHOD_GET` - Retrieve data - `HTTP_METHOD_HEAD` - Get headers only - `HTTP_METHOD_POST` - Submit data - `HTTP_METHOD_PUT` - Replace resource - `HTTP_METHOD_DELETE` - Remove resource - `HTTP_METHOD_CONNECT` - Establish tunnel - `HTTP_METHOD_OPTIONS` - Get allowed methods - `HTTP_METHOD_TRACE` - Debug loop-back - `HTTP_METHOD_PATCH` - Partial update ### Method `RequestJSON(client, endpoint, method, callback_function, [json_body])` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **json_body** (JsonObject) - Optional. The JSON object to send with the request for POST, PUT, PATCH methods. ### Request Example ```pawn new RequestsClient:client = RequestsClient("https://api.example.com/"); // GET - Retrieve a resource RequestJSON(client, "users/123", HTTP_METHOD_GET, "OnGetUser"); // POST - Create a resource RequestJSON(client, "users", HTTP_METHOD_POST, "OnCreateUser", JsonObject("name", JsonString("NewUser")) ); // PUT - Replace a resource RequestJSON(client, "users/123", HTTP_METHOD_PUT, "OnUpdateUser", JsonObject("name", JsonString("UpdatedName"), "email", JsonString("new@email.com")) ); // PATCH - Partial update RequestJSON(client, "users/123", HTTP_METHOD_PATCH, "OnPatchUser", JsonObject("email", JsonString("patched@email.com")) ); // DELETE - Remove a resource RequestJSON(client, "users/123", HTTP_METHOD_DELETE, "OnDeleteUser"); ``` ### Response #### Success Response (200 OK) Responses vary based on the HTTP method and the API endpoint. Callbacks handle the response data. #### Response Example (Response structure depends on the specific API endpoint and HTTP method used. Handled via callback functions like `OnGetUser`, `OnCreateUser`, etc.) ``` -------------------------------- ### Create Requests Client with Endpoint Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Initializes a RequestsClient with a specified base endpoint. This client instance should typically be stored globally and used for all subsequent requests to that endpoint. ```pawn new RequestsClient:client; main() { client = RequestsClient("http://httpbin.org/"); } ``` -------------------------------- ### Connect and Communicate with WebSocket (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt Establishes a WebSocket connection for real-time bidirectional text communication. It handles connection, message sending, and receiving messages via a callback function. Disconnection events are also managed. ```pawn new WebSocket:ws; ConnectWebSocket() { ws = WebSocketClient("wss://ws.example.com/socket", "OnWebSocketMessage"); if (_:ws == -1) { print("Failed to connect to WebSocket!"); return; } print("WebSocket connected!"); // Send a message WebSocketSend(ws, "Hello Server!"); } forward OnWebSocketMessage(WebSocket:wsId, const data[], dataLen); public OnWebSocketMessage(WebSocket:wsId, const data[], dataLen) { printf("Received message (%d bytes): %s", dataLen, data); // Echo back new response[128]; format(response, sizeof(response), "Received: %s", data); WebSocketSend(wsId, response); } forward OnWebSocketDisconnect(WebSocket:wsId, bool:isJson, status, reason[], reasonLen, errorCode); public OnWebSocketDisconnect(WebSocket:wsId, bool:isJson, status, reason[], reasonLen, errorCode) { printf("WebSocket %d disconnected", _:wsId); printf("Status: %d, Error: %d", status, errorCode); if (reasonLen > 0) { printf("Reason: %s", reason); } } ``` -------------------------------- ### Create JSON Array with Various Nodes (Pawn) Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Demonstrates creating a JSON array in Pawn that can contain strings, objects, and other node types. This is useful for representing lists of data. ```pawn new Node:node = JsonObject( "key", JsonArray( JsonString("one"), JsonString("two"), JsonString("three"), JsonObject( "more_stuff1", JsonString("uno"), "more_stuff2", JsonString("dos"), "more_stuff3", JsonString("tres") ) ) ); ``` -------------------------------- ### Make Basic HTTP Request Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Sends a basic HTTP request for plain text data. It specifies the client, the resource path, the HTTP method, and a callback function to handle the response. Supports custom headers. ```pawn Request( client, "robots.txt", HTTP_METHOD_GET, "OnGetData", .headers = RequestHeaders() ); public OnGetData(Request:id, E_HTTP_STATUS:status, data[], dataLen) { printf("status: %d, data: '%s'", _:status, data); } ``` -------------------------------- ### RequestJSON API (JSON Data) Source: https://context7.com/southclaws/pawn-requests/llms.txt This section details how to make HTTP requests that send or receive JSON data. It supports constructing JSON objects dynamically and parsing JSON responses into a `Node` object. ```APIDOC ## RequestJSON API (JSON Data) ### Description Performs an HTTP request to send or receive JSON data. Supports inline JSON construction and provides a parsed JSON Node in the callback. ### Method `RequestJSON(RequestsClient:client, const url[], E_HTTP_METHOD:method, const callback[], Node:body = _, RequestHeaders:headers = RequestHeaders()) ` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **client** (RequestsClient) - The client handle to use for the request. - **url** (const string) - The endpoint path relative to the client's base URL. - **method** (E_HTTP_METHOD) - The HTTP method to use (e.g., `HTTP_METHOD_GET`, `HTTP_METHOD_POST`). - **callback** (const string) - The name of the forward function to call with the response. - **body** (Node, optional) - A `Node` object representing the JSON body to send. Defaults to `_` (no body). - **headers** (RequestHeaders, optional) - A `RequestHeaders` object containing custom headers. Defaults to an empty header set. ### Request Example ```pawn new RequestsClient:client; main() { client = RequestsClient("https://api.example.com/"); // GET request expecting JSON response RequestJSON( client, "users/123", HTTP_METHOD_GET, "OnGetUser" ); // POST request with JSON body RequestJSON( client, "users", HTTP_METHOD_POST, "OnCreateUser", JsonObject( "username", JsonString("Southclaws"), "email", JsonString("user@example.com"), "age", JsonInt(25), "vip", JsonBool(true), "scores", JsonArray( JsonInt(100), JsonInt(250), JsonInt(500) ) ), .headers = RequestHeaders( "Authorization", "Bearer token123" ) ); } forward OnGetUser(Request:id, E_HTTP_STATUS:status, Node:node); public OnGetUser(Request:id, E_HTTP_STATUS:status, Node:node) { if (status != HTTP_STATUS_OK) { printf("Error: %d", _:status); return; } new username[64]; JsonGetString(node, "username", username); new age; JsonGetInt(node, "age", age); printf("User: %s, Age: %d", username, age); } forward OnCreateUser(Request:id, E_HTTP_STATUS:status, Node:node); public OnCreateUser(Request:id, E_HTTP_STATUS:status, Node:node) { if (status == HTTP_STATUS_CREATED) { new userId; JsonGetInt(node, "id", userId); printf("User created with ID: %d", userId); } } ``` ### Response #### Success Response (200) - **id** (Request) - A handle to the created request. - **status** (E_HTTP_STATUS) - The HTTP status code of the response. - **node** (Node) - A `Node` object representing the parsed JSON response body. #### Response Example ```json { "example": "User created with ID: 42" } ``` ``` -------------------------------- ### Create Primitive JSON Nodes (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt JsonInt, JsonFloat, JsonBool, and JsonString functions create primitive JSON nodes for integer, floating-point, boolean, and string values, respectively. These are fundamental building blocks for constructing more complex JSON structures. ```pawn // Create primitive nodes new Node:intNode = JsonInt(42); new Node:floatNode = JsonFloat(3.14159); new Node:boolNode = JsonBool(true); new Node:stringNode = JsonString("Hello World"); // Use in objects new Node:playerData = JsonObject( "id", JsonInt(1001), "name", JsonString("Southclaws"), "balance", JsonFloat(5000.50), "premium", JsonBool(true) ); // Stringify to verify new buf[256]; JsonStringify(playerData, buf); printf("%s\n", buf); // Output: {"id":1001,"name":"Southclaws","balance":5000.5,"premium":true} ``` -------------------------------- ### WebSocketClient API Source: https://context7.com/southclaws/pawn-requests/llms.txt Establishes a WebSocket connection for real-time bidirectional text communication. Messages are received via a callback function. ```APIDOC ## WebSocketClient API ### Description Creates a WebSocket connection for real-time bidirectional text communication. Messages are received through a callback function. ### Method `WebSocketClient(url, callback_function)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```pawn new WebSocket:ws; ConnectWebSocket() { ws = WebSocketClient("wss://ws.example.com/socket", "OnWebSocketMessage"); if (_:ws == -1) { print("Failed to connect to WebSocket!"); return; } print("WebSocket connected!"); // Send a message WebSocketSend(ws, "Hello Server!"); } forward OnWebSocketMessage(WebSocket:wsId, const data[], dataLen); public OnWebSocketMessage(WebSocket:wsId, const data[], dataLen) { printf("Received message (%d bytes): %s", dataLen, data); // Echo back new response[128]; format(response, sizeof(response), "Received: %s", data); WebSocketSend(wsId, response); } forward OnWebSocketDisconnect(WebSocket:wsId, bool:isJson, status, reason[], reasonLen, errorCode); public OnWebSocketDisconnect(WebSocket:wsId, bool:isJson, status, reason[], reasonLen, errorCode) { printf("WebSocket %d disconnected", _:wsId); printf("Status: %d, Error: %d", status, errorCode); if (reasonLen > 0) { printf("Reason: %s", reason); } } ``` ### Response #### Success Response (Connection Established) Returns a WebSocket handle on success, or -1 on failure. #### Response Example (No direct response object, check callback for connection status) ``` -------------------------------- ### JsonWebSocketClient API Source: https://context7.com/southclaws/pawn-requests/llms.txt Establishes a WebSocket connection for real-time JSON message exchange. Messages are automatically parsed into JSON nodes. ```APIDOC ## JsonWebSocketClient API ### Description Creates a WebSocket connection for real-time JSON message exchange. Messages are automatically parsed and provided as JSON nodes. ### Method `JsonWebSocketClient(url, callback_function)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```pawn new JsonWebSocket:jws; ConnectJsonWebSocket() { jws = JsonWebSocketClient("wss://ws.example.com/json", "OnJsonWebSocketMessage"); if (_:jws == -1) { print("Failed to connect to JSON WebSocket!"); return; } // Send JSON message JsonWebSocketSend(jws, JsonObject( "type", JsonString("join"), "room", JsonString("lobby"), "user", JsonObject( "id", JsonInt(1001), "name", JsonString("Southclaws") ) )); } forward OnJsonWebSocketMessage(JsonWebSocket:wsId, Node:node); public OnJsonWebSocketMessage(JsonWebSocket:wsId, Node:node) { new type[32]; JsonGetString(node, "type", type); if (!strcmp(type, "chat")) { new sender[32], message[256]; JsonGetString(node, "sender", sender); JsonGetString(node, "message", message); printf("[%s]: %s", sender, message); } else if (!strcmp(type, "player_update")) { new playerId; JsonGetInt(node, "playerId", playerId); new Node:position; JsonGetObject(node, "position", position); new Float:x, Float:y, Float:z; JsonGetFloat(position, "x", x); JsonGetFloat(position, "y", y); JsonGetFloat(position, "z", z); printf("Player %d moved to %.2f, %.2f, %.2f", playerId, x, y, z); } } ``` ### Response #### Success Response (Connection Established) Returns a JsonWebSocket handle on success, or -1 on failure. #### Response Example (No direct response object, check callback for connection status and received JSON nodes) ``` -------------------------------- ### Define Request Headers Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Constructs a set of headers for an HTTP request. The RequestHeaders function takes an even number of string arguments, representing key-value pairs for the headers. ```pawn RequestHeaders( "Authorization", "Bearer xyz", "Connection", "keep-alive", "Cache-Control", "no-cache" ) ``` -------------------------------- ### Perform JSON HTTP Requests with Pawn Requests Source: https://context7.com/southclaws/pawn-requests/llms.txt Details how to make HTTP requests involving JSON data using the RequestJSON function. This includes sending JSON payloads in POST requests and receiving/parsing JSON responses. The library provides utilities for constructing JSON objects and accessing parsed data in the callback. ```pawn new RequestsClient:client; main() { client = RequestsClient("https://api.example.com/"); // GET request expecting JSON response RequestJSON( client, "users/123", HTTP_METHOD_GET, "OnGetUser" ); // POST request with JSON body RequestJSON( client, "users", HTTP_METHOD_POST, "OnCreateUser", JsonObject( "username", JsonString("Southclaws"), "email", JsonString("user@example.com"), "age", JsonInt(25), "vip", JsonBool(true), "scores", JsonArray( JsonInt(100), JsonInt(250), JsonInt(500) ) ), .headers = RequestHeaders( "Authorization", "Bearer token123" ) ); } forward OnGetUser(Request:id, E_HTTP_STATUS:status, Node:node); public OnGetUser(Request:id, E_HTTP_STATUS:status, Node:node) { if (status != HTTP_STATUS_OK) { printf("Error: %d", _:status); return; } new username[64]; JsonGetString(node, "username", username); new age; JsonGetInt(node, "age", age); printf("User: %s, Age: %d", username, age); } forward OnCreateUser(Request:id, E_HTTP_STATUS:status, Node:node); public OnCreateUser(Request:id, E_HTTP_STATUS:status, Node:node) { if (status == HTTP_STATUS_CREATED) { new userId; JsonGetInt(node, "id", userId); printf("User created with ID: %d", userId); } } ``` -------------------------------- ### CMake: MSVC Specific Build Configurations Source: https://github.com/southclaws/pawn-requests/blob/master/src/CMakeLists.txt Configures specific settings for the Microsoft Visual C++ compiler. This includes setting the runtime library, defining secure warnings and Windows version, and enabling multi-processor compilation for faster builds. ```cmake if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") target_compile_definitions(requests PRIVATE _CRT_SECURE_NO_WARNINGS NOMINMAX _WIN32_WINNT=0x0600 _SCL_SECURE_NO_WARNINGS ) target_compile_options(requests PRIVATE /W4 /permissive- ) # also enable multi-processor compilation target_compile_options(requests PRIVATE /MP ) endif() ``` -------------------------------- ### CMake: Link Conan Libraries Source: https://github.com/southclaws/pawn-requests/blob/master/src/CMakeLists.txt Links the 'requests' target against libraries managed by Conan. This ensures that all necessary dependencies are correctly linked during the build process. ```cmake conan_target_link_libraries(requests) ``` -------------------------------- ### Stringify JSON Node to Buffer (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt Encodes a JSON node into a string buffer using the JsonStringify function. It returns 0 on success and a non-zero error code otherwise. The output is a string representation of the JSON structure. ```pawn new Node:node = JsonObject( "server", JsonString("SA:MP Server"), "players", JsonInt(50), "maxPlayers", JsonInt(100), "gamemode", JsonString("Roleplay"), "settings", JsonObject( "pvp", JsonBool(true), "weather", JsonInt(10) ) ); new buf[512]; new ret = JsonStringify(node, buf); if (ret == 0) { printf("JSON output: %s", buf); // Output: {"server":"SA:MP Server","players":50,"maxPlayers":100,"gamemode":"Roleplay","settings":{"pvp":true,"weather":10}} } else { printf("Stringify error: %d", ret); } ``` -------------------------------- ### Handle HTTP Status Codes in Pawn Source: https://context7.com/southclaws/pawn-requests/llms.txt This Pawn code snippet demonstrates how to use the E_HTTP_STATUS enum to handle different HTTP response codes. It includes success, client error, and server error codes, providing a basic switch statement for processing responses. ```pawn forward OnApiResponse(Request:id, E_HTTP_STATUS:status, Node:node); public OnApiResponse(Request:id, E_HTTP_STATUS:status, Node:node) { switch (status) { // Success codes case HTTP_STATUS_OK: { // 200 print("Request successful"); } case HTTP_STATUS_CREATED: { // 201 print("Resource created"); } case HTTP_STATUS_NO_CONTENT: { // 204 print("Success, no content returned"); } // Client errors case HTTP_STATUS_BAD_REQUEST: { // 400 print("Invalid request"); } case HTTP_STATUS_UNAUTHORIZED: { // 401 print("Authentication required"); } case HTTP_STATUS_FORBIDDEN: { // 403 print("Access denied"); } case HTTP_STATUS_NOT_FOUND: { // 404 print("Resource not found"); } case HTTP_STATUS_TOO_MANY_REQUESTS: { // 429 print("Rate limited, slow down"); } // Server errors case HTTP_STATUS_SERVER_ERROR: { // 500 print("Server error"); } case HTTP_STATUS_BAD_GATEWAY: { // 502 print("Bad gateway"); } case HTTP_STATUS_SERVICE_UNAVAILABLE: { // 503 print("Service unavailable"); } default: { printf("Unhandled status: %d", _:status); } } } ``` -------------------------------- ### Nest JSON Objects (Pawn) Source: https://github.com/southclaws/pawn-requests/blob/master/README.md Illustrates how to create nested JSON objects in Pawn. This allows for complex data structures by embedding objects within other objects. ```pawn new Node:node = JsonObject( "key", JsonObject( "key", JsonString("value") ) ); ``` -------------------------------- ### Connect and Exchange JSON via WebSocket (Pawn) Source: https://context7.com/southclaws/pawn-requests/llms.txt Establishes a WebSocket connection specifically for JSON message exchange. It automatically parses incoming JSON messages into nodes and allows sending structured JSON data. Includes handling for different message types like 'chat' and 'player_update'. ```pawn new JsonWebSocket:jws; ConnectJsonWebSocket() { jws = JsonWebSocketClient("wss://ws.example.com/json", "OnJsonWebSocketMessage"); if (_:jws == -1) { print("Failed to connect to JSON WebSocket!"); return; } // Send JSON message JsonWebSocketSend(jws, JsonObject( "type", JsonString("join"), "room", JsonString("lobby"), "user", JsonObject( "id", JsonInt(1001), "name", JsonString("Southclaws") ) )); } forward OnJsonWebSocketMessage(JsonWebSocket:wsId, Node:node); public OnJsonWebSocketMessage(JsonWebSocket:wsId, Node:node) { new type[32]; JsonGetString(node, "type", type); if (!strcmp(type, "chat")) { new sender[32], message[256]; JsonGetString(node, "sender", sender); JsonGetString(node, "message", message); printf("[%s]: %s", sender, message); } else if (!strcmp(type, "player_update")) { new playerId; JsonGetInt(node, "playerId", playerId); new Node:position; JsonGetObject(node, "position", position); new Float:x, Float:y, Float:z; JsonGetFloat(position, "x", x); JsonGetFloat(position, "y", y); JsonGetFloat(position, "z", z); printf("Player %d moved to %.2f, %.2f, %.2f", playerId, x, y, z); } } ```