Jump to content

Recommended Posts

Extension to make http requests, currently supporting:

  • GET
  • POST
  • PATCH
  • DELETE
  • PUT

 

First parameter is the mode.

Second is the method.

Third is the url.

Fourth is the authorization, if no authorization needed just pass null

Fifth is the request body, only used by POST, PATCH and PUT, if no body needed just pass {}

 

GET request example:

"ArmaRequests" callExtension "0|GET|http://headers.jsontest.com/|null";

waitUntil {sleep 1; "ArmaRequests" callExtension "2" == "OK"};

_response = "ArmaRequests" callExtension "1";

_parsedResponse = parseSimpleArray _response;

_code = _parsedResponse select 0;

_data = _parsedResponse select 1;

//Response => [["X-Cloud-Trace-Context","47e3637379c2b3d638285b973e0e4f96/4228286279360018440"],["Host","headers.jsontest.com"]]

 

POST request example:

"ArmaRequests" callExtension '0|POST|url|Bot ksZc83aS|{"Number": 4, "String": "String"}';

waitUntil {sleep 1; "ArmaRequests" callExtension "2" == "OK"};

_response = "ArmaRequests" callExtension "1";

_parsedResponse = parseSimpleArray _response;

_code = _parsedResponse select 0;

_data = _parsedResponse select 1;

 

 

Every response comes with a status code

0: All data received
1: There's still data to receive
9: Error

The codes you can use are

0: New request
1: Receive data
2: Get extension status
3: Parse JSON //Example: "ArmaRequests" callExtensions '3|{"age": 80}';

Due to string length limitations, if the response exceeds that limit it will be sent in chunks with status code 1, to receive the chunk use

_fullResponse = "";

//
_chunkResponse = "ArmaRequests" callExtension "1";
_parsedChunkResponse = parseSimpleArray _chunkResponse;
_code = _chunkResponse select 0;
_data = _chunkResponse select 1;
_fullResponse = _fullResponse + _data;

//You must repeat the receiving process until it responds with a code 0

When there's no more data left, it will respond with a code 0.

JSON responses are automatically parsed into arrays, all common variables type are supported.

 

Example code 

_fullResponse = "";
  "ArmaRequests" callExtension "0|GET|http://headers.jsontest.com/|null"; //Send request
  waitUntil {sleep 1; "ArmaRequests" callExtension "2" == "OK"};

  _response = "ArmaRequests" callExtension "1";
  _parsedResponse = parseSimpleArray _response; //Parse response

  _code = _parsedResponse select 0; //Save code and data
  _data = _parsedResponse select 1;

  if (_code != 9) then { //Check if is a error
  _fullResponse = _data; //Assign the data in the full response

  while {_code == 1} do { //if there's more data receive it
    _chunkResponse = "ArmaRequests" callExtension "1"; //Receive next chunk data
    _parsedChunkResponse = parseSimpleArray _chunkResponse; //Parse the chunk data
    _code = _parsedChunkResponse select 0; //Update the status code
    _data = _parsedChunkResponse select 1; //Save the data
    if (_code == 9) exitWith {hint "Error : " + _data;}; //Check if is a error
    _fullResponse = _fullResponse + _data; //Append the chunk to the full response
  };

  hint str _fullResponse;
} else {
  hint "Error during request " + _data;
};

There's also a callback version

"ArmaRequestsCallback" callExtension "callbackFunction|Method|url|authorization?|body?";

Example using callback version and normal version

TAG_fnc_DiscordMessageSent = {
  params["_data"];
  //[["id","651314298001424405"],["type",0],["content","Hello"],["channel_id","649607925760786442"],["author",[["id","629121190182780929"],["username","Fantasia"],["avatar",null],["discriminator","2964"],["bot",true]]],["attachments",[]],["embeds",[]],["mentions",[]],["mention_roles",[]],["pinned",false],["mention_everyone",false],["tts",false],["timestamp","2019-12-03T06:50:29.478000+00:00"],["edited_timestamp",null],["flags",0],["nonce",null]]
  _content = (_data select 2) select 1;
  _username = (((_data select 4) select 1) select 1) select 1;
  _channelId = (_data select 3) select 1;
  "ArmaRequests" callExtension format["0|GET|https://discordapp.com/api/v6/channels/%1|Bot TOKEN|{}", _channelId];
  waitUntil {sleep 1; "ArmaRequests" callExtension "2" == "OK"};
  _channelData = (parseSimpleArray ("ArmaRequests" callExtension "1")) select 1;
  _channelName = (_channelData select 3) select 1;
  _guildId = (_channelData select 7) select 1;
  "ArmaRequests" callExtension format["0|GET|https://discordapp.com/api/v6/guilds/%1|Bot TOKEN|{}", _guildId];
  waitUntil {sleep 1; "ArmaRequests" callExtension "2" == "OK"};
  _guildData = (parseSimpleArray ("ArmaRequests" callExtension "1")) select 1;
  _guildName = (_guildData select 1) select 1;
  hint format["Sent %1 as %2 in the channel %3 of the guild %4", _content, _username, _channelName, _guildName];


};



addMissionEventHandler ["ExtensionCallback", {
  params["_name", "_function", "_data"];


  if (_name == "ArmaRequestsCallback_JSON") then {
      [parseSimpleArray _data] spawn (missionNamespace getVariable [_function, {
        diag_log format["ArmaRequestsCallback: Tried to call %1, but isn't defined", _function];
        }]);
  };

  if (_name == "ArmaRequestsCallback_Error") then {
    hint "Request error: " + _data;
  };

  if (_name == "ArmaRequestsCallback_TEXT") then {
    systemChat _data;
  };

}];

"ArmaRequestsCallback" callExtension "TAG_fnc_DiscordMessageSent|POST|https://discordapp.com/api/v6/channels/649607925760786442/messages|Bot BOT|{""content"": ""Hello"", ""tts"": false}";

Download link: https://drive.google.com/file/d/1-9oW3PhArHbs15AS4c6R5UQuuk6usInC/view

 

 

Edited by MechSlayer
Update
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
14 hours ago, MechSlayer said:

!!WARNING!! Game will freeze during the request

Why not use extension callback to get the result asynchronously without a freeze?

 

Would also get rid of the

14 hours ago, MechSlayer said:

Due to string length limitations, if the response exceeds that limit it will be sent in chunks with status code 1

problem

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, Dedmen said:

Why not use extension callback to get the result asynchronously without a freeze?

 

Would also get rid of the

problem

Now I feel stupid for not thinking about callbacks, the problem is that I have no idea about changing the output size limit

Share this post


Link to post
Share on other sites
1 minute ago, MechSlayer said:

the problem is that I have no idea about changing the output size limit 

Afaik callbacks have no limit. Besides the 10MB string limit I assume.

  • Like 1

Share this post


Link to post
Share on other sites

Strange, when I try sending more characters than the output size it throws me buffer overrun

Share this post


Link to post
Share on other sites
12 hours ago, Dedmen said:

Why not use extension callback to get the result asynchronously without a freeze?

Would also get rid of the problem.

Okey, no more freezing, also the json responses are parsed to arrays (The downside is that only works with numbers, strings, booleans and null values). It looks like the output max size is set by the engine so i can't get rid of it.

  • Thanks 1

Share this post


Link to post
Share on other sites
On 11/29/2019 at 2:11 PM, MechSlayer said:

Strange, when I try sending more characters than the output size it throws me buffer overrun

I'm talking about callbacks, not the normal callExtension stuff.

Share this post


Link to post
Share on other sites
On 11/28/2019 at 6:57 PM, MechSlayer said:

"ArmaRequests" callExtension "0|GET|http://headers.jsontest.com/|null";

 

Come on, the alternative syntax was available for ages

Share this post


Link to post
Share on other sites
On 11/30/2019 at 10:48 PM, killzone_kid said:

 

Come on, the alternative syntax was available for ages

I tried it first, but the game or c#, converts the parameters to strings even if they already are. Making "string" to """string"""

Share this post


Link to post
Share on other sites

yes, it makes it easy to test what type of argument you passed, if 1st char is " - it is a string. It is better than do manual parsing looking for those delimiters

Share this post


Link to post
Share on other sites

Hey MechSlayer,

 

today i was trying to implement your module into my recent project, and with static routes it works fine, but when im trying to call dynamic routes i can't receive valid data.

 

Here's my get request: "ArmaRequests" callExtension "0|GET|https://jsonplaceholder.typicode.com/posts/1/|null"

it seems to have a problem with routing, the request with the following url, https://jsonplaceholder.typicode.com/posts, works just fine.

 

Best Regards,

 

Luke

Share this post


Link to post
Share on other sites
4 minutes ago, -JpS-RaptorMan said:

Is this thing around?  Where hosted?

 

It's linked in the first post.  

Share this post


Link to post
Share on other sites

Hello everyone, I am doing a project where I need to get some in-game data and then import it into a local MySQL server. My problem right now is that the extension could not be found, this is what I saw in the log files. I just downloaded the ArmaRequests folder and put it here: C:\Program Files (x86)\Steam\steamapps\common\Arma 3. What is wrong with that?

Share this post


Link to post
Share on other sites

Fixed the issue I had, my problem now is the following. In the SQF script, I get the message that data was sent successfully. However I do not see to get the data into my local server. I use MySQL local server with XAMPP and was wondering whether the url in the SQF script could look like this: 

"http://localhost/armaproject/storeData.php"

 

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×