- Поддерживаемые игры
-
- CS: Source (OrangeBox)
- CS: GO
- Team Fortress 2
- DOD: Source
- L4D 1 & 2
TLS v1.3 не поддерживается! Подробнее
Ещё одно расширение для работы с HTTP, но заточенное под работу с JSON REST API. Оно поддерживает HTTPS и gzip, и представляет функционал в виде методмапов (methodmaps) для работы с JSON объектами и массивами.
Если у Вас сервер в CS:GO / L4D2, и на Линуксе, рекомендую прочесть данный пост. Более не актуально с версии 1.0.2.
Получение предмета
Получение коллекции предметов (массива)
Создание предмета
Обновление предмета
Удаление предмета
Добавление параметров запроса в URL
Имя параметра и его значение автоматически экранируются, как того требует стандарт.
Установка аутентификационных данных
Установка заголовков запроса
Ещё одно расширение для работы с HTTP, но заточенное под работу с JSON REST API. Оно поддерживает HTTPS и gzip, и представляет функционал в виде методмапов (methodmaps) для работы с JSON объектами и массивами.
Создание JSON-объекта
Убедитесь перед освобождением памяти от самого JSON-объекта, что Вы освободили память от всех вложенных JSON-объектов и массивов.
Создание JSON-массива
Вы так же можете использовать Set*() методы, если Вам надо установить для конкретных индексов значения.
Вложение массива в JSON-объекте
Get() создаёт новый Handle, так что не забудьте закрыть его, когда закончите работать с ним.
Экспорт, импорт из файлов или строк
Если Вы хотите отформатировать итоговый JSON, см. флаги экспорта в самом верху инклюды json.inc
C-подобный:
JSONObject someObject = new JSONObject();
someObject.SetBool("someBool", false);
someObject.SetFloat("someFloat", 1.0);
someObject.SetInt("someInt", 2);
someObject.SetString("someString", "three");
someObject.SetNull("someNull");
Создание JSON-массива
C-подобный:
JSONArray someArray = new JSONArray();
someArray.PushBool(false);
someArray.PushFloat(1.0);
someArray.PushInt(2);
someArray.PushString("three");
someArray.PushNull();
Вложение массива в JSON-объекте
C-подобный:
someObject.Set("someArray", someArray);
JSONArray otherArray = view_as<JSONArray>(someObject.Get("someArray"));
Экспорт, импорт из файлов или строк
C-подобный:
// Экспорт
char json[256];
someObject.ToString(json, sizeof(json));
// Импорт
char path[PLATFORM_MAX_PATH + 1];
BuildPath(Path_SM, path, sizeof(path), "data/array.json");
JSONArray fileArray = JSONArray.FromFile(path);
Установка заголовка запроса
Получение предмета
Получение коллекции предметов (массива)
Создание предмета
Обновление предмета
Удаление предмета
C-подобный:
#include <sourcemod>
#include <ripext>
HTTPClient httpClient;
public void OnPluginStart()
{
httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");
httpClient.SetHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
}
Получение предмета
C-подобный:
#include <sourcemod>
#include <ripext>
HTTPClient httpClient;
public void OnPluginStart()
{
httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");
httpClient.Get("todos/1", OnTodoReceived);
}
public void OnTodoReceived(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to retrieve todo
return;
}
if (response.Data == null) {
// Invalid JSON response
return;
}
// Indicate that the response is a JSON object
JSONObject todo = view_as<JSONObject>(response.Data);
char todoTitle[256];
todo.GetString("title", todoTitle, sizeof(todoTitle));
PrintToServer("Retrieved todo with title '%s'", todoTitle);
}
Получение коллекции предметов (массива)
C-подобный:
#include <sourcemod>
#include <ripext>
HTTPClient httpClient;
public void OnPluginStart()
{
httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");
httpClient.Get("todos", OnTodosReceived);
}
public void OnTodosReceived(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to retrieve todos
return;
}
if (response.Data == null) {
// Invalid JSON response
return;
}
// Indicate that the response is a JSON array
JSONArray todos = view_as<JSONArray>(response.Data);
int numTodos = todos.Length;
JSONObject todo;
char todoTitle[256];
for (int i = 0; i < numTodos; i++) {
todo = view_as<JSONObject>(todos.Get(i));
todo.GetString("title", todoTitle, sizeof(todoTitle));
PrintToServer("Retrieved todo with title '%s'", todoTitle);
// Get() creates a new handle, so delete it when we are done with it
delete todo;
}
}
Создание предмета
C-подобный:
#include <sourcemod>
#include <ripext>
HTTPClient httpClient;
public void OnPluginStart()
{
httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");
JSONObject todo = new JSONObject();
todo.SetBool("completed", false);
todo.SetInt("userId", 1);
todo.SetString("title", "foo");
httpClient.Post("todos", todo, OnTodoCreated);
// JSON objects and arrays must be deleted when you are done with them
delete todo;
}
public void OnTodoCreated(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_Created) {
// Failed to create todo
return;
}
if (response.Data == null) {
// Invalid JSON response
return;
}
JSONObject todo = view_as<JSONObject>(response.Data);
int todoId = todo.GetInt("id");
PrintToServer("Created todo with ID %d", todoId);
}
Обновление предмета
C-подобный:
#include <sourcemod>
#include <ripext>
HTTPClient httpClient;
public void OnPluginStart()
{
httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");
JSONObject todo = new JSONObject();
todo.SetBool("completed", true);
// Some APIs replace the entire object when using PUT,
// in which case you need to use PATCH instead.
httpClient.Put("todos/1", todo, OnTodoUpdated);
delete todo;
}
public void OnTodoUpdated(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to update todo
return;
}
if (response.Data == null) {
// Invalid JSON response
return;
}
JSONObject todo = view_as<JSONObject>(response.Data);
int todoId = todo.GetInt("id");
PrintToServer("Updated todo with ID %d", todoId);
}
Удаление предмета
C-подобный:
#include <sourcemod>
#include <ripext>
HTTPClient httpClient;
public void OnPluginStart()
{
httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");
httpClient.Delete("todos/1", OnTodoDeleted, 1);
}
public void OnTodoDeleted(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to delete todo
return;
}
PrintToServer("Deleted todo with ID %d", value);
}
Получение предмета
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
HTTPRequest request = new HTTPRequest("https://jsonplaceholder.typicode.com/todos/1");
request.Get(OnTodoReceived);
}
void OnTodoReceived(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to retrieve todo
return;
}
// Indicate that the response contains a JSON object
JSONObject todo = view_as<JSONObject>(response.Data);
char title[256];
todo.GetString("title", title, sizeof(title));
PrintToServer("Retrieved todo with title '%s'", title);
}
Получение коллекции предметов (массива)
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
HTTPRequest request = new HTTPRequest("https://jsonplaceholder.typicode.com/todos");
request.Get(OnTodosReceived);
}
void OnTodosReceived(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to retrieve todos
return;
}
// Indicate that the response contains a JSON array
JSONArray todos = view_as<JSONArray>(response.Data);
int numTodos = todos.Length;
JSONObject todo;
char title[256];
for (int i = 0; i < numTodos; i++) {
todo = view_as<JSONObject>(todos.Get(i));
todo.GetString("title", title, sizeof(title));
PrintToServer("Retrieved todo with title '%s'", title);
// Get() creates a new handle, so delete it when you are done with it
delete todo;
}
}
Создание предмета
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
JSONObject todo = new JSONObject();
todo.SetBool("completed", false);
todo.SetInt("userId", 1);
todo.SetString("title", "foo");
HTTPRequest request = new HTTPRequest("https://jsonplaceholder.typicode.com/todos");
request.Post(todo, OnTodoCreated);
// JSON objects and arrays must be deleted when you are done with them
delete todo;
}
void OnTodoCreated(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_Created) {
// Failed to create todo
return;
}
JSONObject todo = view_as<JSONObject>(response.Data);
PrintToServer("Created todo with ID %d", todo.GetInt("id"));
}
Обновление предмета
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
JSONObject todo = new JSONObject();
todo.SetBool("completed", true);
HTTPRequest request = new HTTPRequest("https://jsonplaceholder.typicode.com/todos/1");
// Some APIs replace the entire object when using Put,
// in which case you need to use Patch instead.
httpClient.Put(todo, OnTodoUpdated);
delete todo;
}
void OnTodoUpdated(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to update todo
return;
}
JSONObject todo = view_as<JSONObject>(response.Data);
PrintToServer("Updated todo with ID %d", todo.GetInt("id"));
}
Удаление предмета
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
HTTPRequest request = new HTTPRequest("https://jsonplaceholder.typicode.com/todos/1");
request.Delete(OnTodoDeleted);
}
void OnTodoDeleted(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_OK) {
// Failed to delete todo
return;
}
PrintToServer("Deleted todo");
}
Добавление параметров запроса в URL
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
HTTPRequest request = new HTTPRequest("https://jsonplaceholder.typicode.com/todos");
request.AppendQueryParam("userId", "%d", 1);
}
Установка аутентификационных данных
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
HTTPRequest request = new HTTPRequest("https://nghttp2.org/httpbin/basic-auth/username/password");
request.SetBasicAuth("username", "password");
}
Установка заголовков запроса
C-подобный:
#include <sourcemod>
#include <ripext>
public void OnPluginStart()
{
HTTPRequest request = new HTTPRequest("https://nghttp2.org/httpbin/bearer");
request.SetHeader("Authorization", "Bearer %s", "some-token");
}
Так же, Вы можете написать свой методмап, наследуясь от JSONObject. Это сделает Ваш код чище при чтении и установке значений в JSON.
plugin.inc
plugin.sp
plugin.inc
C-подобный:
methodmap Todo < JSONObject
{
// Constructor
public Todo() { return view_as<Todo>(new JSONObject()); }
public void GetTitle(char[] buffer, int maxlength)
{
this.GetString("title", buffer, maxlength);
}
public void SetTitle(const char[] value)
{
this.SetString("title", value);
}
property bool Completed {
public get() { return this.GetBool("completed"); }
public set(bool value) { this.SetBool("completed", value); }
}
property int Id {
public get() { return this.GetInt("id"); }
}
property int UserId {
public get() { return this.GetInt("userId"); }
public set(int value) { this.SetInt("userId", value); }
}
};
plugin.sp
C-подобный:
#include <sourcemod>
#include <ripext>
#include <plugin>
HTTPClient httpClient;
public void OnPluginStart()
{
httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");
Todo todo = new Todo();
todo.Completed = false;
todo.UserId = 1;
todo.SetTitle("foo");
httpClient.Post("todos", todo, OnTodoCreated);
delete todo;
}
public void OnTodoCreated(HTTPResponse response, any value)
{
if (response.Status != HTTPStatus_Created) {
// Failed to create todo
return;
}
if (response.Data == null) {
// Invalid JSON response
return;
}
Todo todo = view_as<Todo>(response.Data);
PrintToServer("Todo created with ID %d", todo.Id);
}
- Требования
-
- SourceMod 1.8 или выше
- Установка
-
- Скачать архив с расширением.
- Распаковать архив.
- Загрузить распакованные файлы на сервер, соблюдая структуру.