webapi.sp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #pragma newdecls optional
  2. #include <steamtools>
  3. #pragma newdecls required
  4. #include <newdecl-handles/smjansson>
  5. #define SOURCECBL_REQUEST_BAN_ENDPOINT "https://sourcecbl.com/api/steam/"
  6. #define SOURCECBL_API_TIMEOUT 5
  7. typedef BanStatusCallback = function void(const char[] steamid64, bool bBanned, any data);
  8. /**
  9. * Status codes.
  10. */
  11. enum APIResponse {
  12. Response_Success = 0,
  13. Response_NotAuthorized
  14. };
  15. /**
  16. * Queries the SourceCBL API for a ban on the specified SteamID64.
  17. * User-facing function.
  18. */
  19. void QueryBanList(const char[] steamid64, BanStatusCallback callback, any data = 0) {
  20. // we need to use the steamid64 later on down the line to verify the request even if the
  21. // player disconnects
  22. DataPack pack = new DataPack();
  23. pack.WriteCell(data);
  24. pack.WriteString(steamid64);
  25. pack.WriteFunction(callback);
  26. HTTPRequestHandle request = Steam_CreateHTTPRequest(HTTPMethod_GET,
  27. SOURCECBL_REQUEST_BAN_ENDPOINT);
  28. Steam_SetHTTPRequestNetworkActivityTimeout(request, SOURCECBL_API_TIMEOUT);
  29. Steam_SetHTTPRequestGetOrPostParameter(request, "steamid", steamid64);
  30. Steam_SendHTTPRequest(request, OnAccountStatusReceived, pack);
  31. }
  32. /**
  33. * Called when the response to the API request is received.
  34. */
  35. public int OnAccountStatusReceived(HTTPRequestHandle request, bool bSuccess,
  36. HTTPStatusCode status, DataPack pack) {
  37. if (!bSuccess || status != HTTPStatusCode_OK) {
  38. return;
  39. }
  40. int maxlen = Steam_GetHTTPResponseBodySize(request) + 1;
  41. char[] buffer = new char[maxlen];
  42. Steam_GetHTTPResponseBodyData(request, buffer, maxlen);
  43. Steam_ReleaseHTTPRequest(request);
  44. // they should've just gone with outputting VDF so I could just slap that shit into a buffer and call it a day
  45. // also would've preferred SteamID3 so I wouldn't have to use strings
  46. pack.Reset();
  47. any data = pack.ReadCell();
  48. char steamid64[64];
  49. pack.ReadString(steamid64, sizeof(steamid64));
  50. Function callback = pack.ReadFunction();
  51. delete pack;
  52. /**
  53. * The API response (currently) has SteamID64 strings as keys for players that are banned.
  54. * It's going to be a painus in the anus if they change the API again.
  55. */
  56. JSONObject accountStatus = view_as<JSONObject>(json_load(buffer));
  57. if (accountStatus) {
  58. JSONInteger response = view_as<JSONInteger>(accountStatus.Get("response"));
  59. APIResponse apiStatus = response?
  60. view_as<APIResponse>(response.Value) : Response_Success;
  61. delete response;
  62. JSONObjectIterator iterator;
  63. if (apiStatus == Response_Success &&
  64. (iterator = JSONObjectIterator.From(accountStatus))) {
  65. char steamid64Key[64];
  66. bool bBanned;
  67. do {
  68. iterator.GetKey(steamid64Key, sizeof(steamid64Key));
  69. if (StrEqual(steamid64Key, steamid64)) {
  70. bBanned = true;
  71. }
  72. } while ((iterator.Next(accountStatus)));
  73. CallBanStatusCallback(callback, steamid64, bBanned, data);
  74. // iterator auto-closes
  75. } else if (apiStatus == Response_NotAuthorized) {
  76. // TODO shut down everything
  77. }
  78. delete accountStatus;
  79. }
  80. }
  81. /**
  82. * Wrapper to isolate the callback function.
  83. */
  84. static void CallBanStatusCallback(Function callback, const char[] steamid64, bool bBanned,
  85. any data) {
  86. Call_StartFunction(INVALID_HANDLE, callback);
  87. Call_PushString(steamid64);
  88. Call_PushCell(bBanned);
  89. Call_PushCell(data);
  90. Call_Finish();
  91. }