REST in Pawn 1.0.1

Нативы для работы с HTTP и JSON

  1. Kruzya
    Поддерживаемые игры:
    • CS: Source
    • CS: GO
    • Team Fortress 2
    • DOD: Source
    • L4D 1 & 2
    Ещё одно расширение для работы с HTTP, но заточенное под работу с JSON REST API. Оно поддерживает HTTPS и gzip, и представляет функционал в виде методмапов (methodmaps) для работы с JSON объектами и массивами.

    Если у Вас сервер в CS:GO / L4D2, и на Линуксе, рекомендую прочесть данный пост.

    Создание JSON-объекта
    PHP:
    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-объекта, что Вы освободили память от всех вложенных JSON-объектов и массивов.

    Создание JSON-массива
    PHP:
    JSONArray someArray = new JSONArray();

    someArray.PushBool(false);
    someArray.PushFloat(1.0);
    someArray.PushInt(2);
    someArray.PushString("three");
    someArray.PushNull();
    Вы так же можете использовать Set*() методы, если Вам надо установить для конкретных индексов значения.

    Вложение массива в JSON-объекте
    PHP:
    someObject.Set("someArray"someArray);

    JSONArray otherArray view_as<JSONArray>(someObject.Get("someArray"));
    Get() создаёт новый Handle, так что не забудьте закрыть его, когда закончите работать с ним.

    Экспорт, импорт из файлов или строк
    PHP:
    // Экспорт
    char json[256];
    someObject.ToString(jsonsizeof(json));

    // Импорт
    char path[PLATFORM_MAX_PATH 1];
    BuildPath(Path_SMpathsizeof(path), "data/array.json");

    JSONArray fileArray JSONArray.FromFile(path);
    Если Вы хотите отформатировать итоговый JSON, см. флаги экспорта в самом верху инклюды json.inc
    Установка заголовка запроса
    PHP:
    #include <sourcemod>
    #include <ripext>

    HTTPClient httpClient;

    public 
    void OnPluginStart()
    {
        
    httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");

        
    httpClient.SetHeader("Authorization""Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
    }
    Получение предмета
    PHP:
    #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 responseany 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"todoTitlesizeof(todoTitle));

        
    PrintToServer("Retrieved todo with title '%s'"todoTitle);
    }
    Получение коллекции предметов (массива)
    PHP:
    #include <sourcemod>
    #include <ripext>

    HTTPClient httpClient;

    public 
    void OnPluginStart()
    {
        
    httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");

        
    httpClient.Get("todos"OnTodosReceived);
    }

    public 
    void OnTodosReceived(HTTPResponse responseany 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 0numTodosi++) {
            
    todo view_as<JSONObject>(todos.Get(i));

            
    todo.GetString("title"todoTitlesizeof(todoTitle));

            
    PrintToServer("Retrieved todo with title '%s'"todoTitle);

            
    // Get() creates a new handle, so delete it when we are done with it
            
    delete todo;
        }
    }

    Создание предмета
    PHP:
    #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"todoOnTodoCreated);

        
    // JSON objects and arrays must be deleted when you are done with them
        
    delete todo;
    }

    public 
    void OnTodoCreated(HTTPResponse responseany 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);
    }
    Обновление предмета
    PHP:
    #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"todoOnTodoUpdated);

        
    delete todo;
    }

    public 
    void OnTodoUpdated(HTTPResponse responseany 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);
    }

    Удаление предмета
    PHP:
    #include <sourcemod>
    #include <ripext>

    HTTPClient httpClient;

    public 
    void OnPluginStart()
    {
        
    httpClient = new HTTPClient("https://jsonplaceholder.typicode.com");

        
    httpClient.Delete("todos/1"OnTodoDeleted1);
    }

    public 
    void OnTodoDeleted(HTTPResponse responseany value)
    {
        if (
    response.Status != HTTPStatus_OK) {
            
    // Failed to delete todo
            
    return;
        }

        
    PrintToServer("Deleted todo with ID %d"value);
    }
    Так же, Вы можете написать свой методмап, наследуясь от JSONObject. Это сделает Ваш код чище при чтении и установке значений в JSON.

    plugin.inc
    PHP:
    methodmap Todo JSONObject
    {
        
    // Constructor
        
    public Todo() { return view_as<Todo>(new JSONObject()); }

        public 
    void GetTitle(char[] bufferint maxlength)
        {
            
    this.GetString("title"buffermaxlength);
        }
        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
    PHP:
    #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"todoOnTodoCreated);

        
    delete todo;
    }

    public 
    void OnTodoCreated(HTTPResponse responseany 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 или выше
    Установка:
    1. Скачать архив с расширением.
    2. В зависимости от системы на сервере, распаковать архив (windows.zip, linux.tar.gz).
    3. Загрузить распакованные файлы на сервер, соблюдая структуру.
    san911 и CAH4E3 нравится это.

Последние обнoвления

  1. Установка заголовков запроса