mirror of
https://github.com/openbullet/openbullet.git
synced 2023-10-21 07:33:42 -05:00
218 lines
8.6 KiB
C#
218 lines
8.6 KiB
C#
using Extreme.Net;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace RuriLib.CaptchaServices
|
|
{
|
|
/// <summary>
|
|
/// Implements the API of https://www.deathbycaptcha.com/
|
|
/// </summary>
|
|
public class DeathByCaptcha : CaptchaService
|
|
{
|
|
/// <summary>
|
|
/// Creates a DeathByCaptcha client.
|
|
/// </summary>
|
|
/// <param name="user">The DeathByCaptcha username</param>
|
|
/// <param name="pass">The DeathByCaptcha password</param>
|
|
/// <param name="timeout">The maximum time to wait for the challenge to be solved</param>
|
|
public DeathByCaptcha(string user, string pass, int timeout) : base(user, pass, timeout) { }
|
|
|
|
/// <inheritdoc />
|
|
public override double GetBalance()
|
|
{
|
|
using (CWebClient client = new CWebClient())
|
|
{
|
|
if (Timeout > 0) client.Timeout = Timeout;
|
|
client.Headers.Add(HttpRequestHeader.Accept, "application/json");
|
|
client.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
|
|
var response = client.UploadString("http://api.dbcapi.me/api/user", $"username={User}&password={Pass}");
|
|
GetBalanceResponse gbr = JsonConvert.DeserializeObject<GetBalanceResponse>(response);
|
|
if (gbr.status != 0) throw new Exception("Invalid Credentials");
|
|
return gbr.balance / 100;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string SolveRecaptcha(string siteKey, string siteUrl)
|
|
{
|
|
// Create task
|
|
HttpRequest request = new HttpRequest();
|
|
request.AddHeader(HttpHeader.Accept, "application/json");
|
|
var content = new Extreme.Net.MultipartContent(BlockRequest.GenerateMultipartBoundary());
|
|
content.Add(new Extreme.Net.StringContent(User), "username");
|
|
content.Add(new Extreme.Net.StringContent(Pass), "password");
|
|
content.Add(new Extreme.Net.StringContent("4"), "type");
|
|
content.Add(new Extreme.Net.StringContent(JsonConvert.SerializeObject(new CreateRecaptchaTaskRequest(siteUrl, siteKey))), "token_params");
|
|
var response = request.Post("http://api.dbcapi.me/api/captcha", content).ToString();
|
|
|
|
// Sometimes the DBC API replies without JSON even when the Accept header is set correctly, so we must perform a check
|
|
if (response.Trim().StartsWith("{"))
|
|
{
|
|
var taskResponse = JsonConvert.DeserializeObject<CreateTaskResponse>(response);
|
|
if (taskResponse.status == 255) throw new Exception(taskResponse.error);
|
|
TaskId = taskResponse.captcha;
|
|
}
|
|
else // Not JSON
|
|
{
|
|
var split = response.Split('&');
|
|
var status = int.Parse(split[0].Split('=')[1]);
|
|
var id = split[1].Split('=')[1];
|
|
if (status == 255) throw new Exception(response);
|
|
TaskId = id;
|
|
}
|
|
Status = CaptchaStatus.Processing;
|
|
|
|
// Check if task has been completed
|
|
DateTime start = DateTime.Now;
|
|
while (Status == CaptchaStatus.Processing && (DateTime.Now - start).TotalSeconds < Timeout)
|
|
{
|
|
Thread.Sleep(5000);
|
|
HttpRequest gRequest = new HttpRequest();
|
|
gRequest.AddHeader(HttpHeader.Accept, "application/json");
|
|
HttpResponse gResponse = gRequest.Get($"http://api.dbcapi.me/api/captcha/{TaskId}");
|
|
var resp = gResponse.ToString();
|
|
CreateTaskResponse gtrr = JsonConvert.DeserializeObject<CreateTaskResponse>(resp);
|
|
if (gtrr == null) continue;
|
|
if (!gtrr.is_correct) throw new Exception("No answer could be found");
|
|
if (gtrr.text != "")
|
|
{
|
|
Status = CaptchaStatus.Completed;
|
|
return gtrr.text;
|
|
}
|
|
}
|
|
throw new TimeoutException();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string SolveCaptcha(Bitmap bitmap)
|
|
{
|
|
// Create task
|
|
HttpRequest request = new HttpRequest();
|
|
request.AddHeader(HttpHeader.Accept, "application/json");
|
|
Extreme.Net.MultipartContent content = new Extreme.Net.MultipartContent(BlockRequest.GenerateMultipartBoundary());
|
|
content.Add(new Extreme.Net.StringContent(User), "username");
|
|
content.Add(new Extreme.Net.StringContent(Pass), "password");
|
|
content.Add(new Extreme.Net.StringContent($"base64:{GetBase64(bitmap, ImageFormat.Jpeg)}"), "captchafile");
|
|
var response = request.Post("http://api.dbcapi.me/api/captcha", content).ToString();
|
|
|
|
// Sometimes the DBC API replies without JSON even when the Accept header is set correctly, so we must perform a check
|
|
if (response.Trim().StartsWith("{"))
|
|
{
|
|
var taskResponse = JsonConvert.DeserializeObject<CreateTaskResponse>(response);
|
|
if (taskResponse.status == 255) throw new Exception(taskResponse.error);
|
|
TaskId = taskResponse.captcha;
|
|
}
|
|
else // Not JSON
|
|
{
|
|
var split = response.Split('&');
|
|
var status = int.Parse(split[0].Split('=')[1]);
|
|
var id = split[1].Split('=')[1];
|
|
if (status == 255) throw new Exception(response);
|
|
TaskId = id;
|
|
}
|
|
Status = CaptchaStatus.Processing;
|
|
|
|
// Check if task has been completed
|
|
DateTime start = DateTime.Now;
|
|
while (Status == CaptchaStatus.Processing && (DateTime.Now - start).TotalSeconds < Timeout)
|
|
{
|
|
Thread.Sleep(5000);
|
|
HttpRequest gRequest = new HttpRequest();
|
|
gRequest.AddHeader(HttpHeader.Accept, "application/json");
|
|
HttpResponse gResponse = gRequest.Get($"http://api.dbcapi.me/api/captcha/{TaskId}");
|
|
var resp = gResponse.ToString();
|
|
CreateTaskResponse gtrr = JsonConvert.DeserializeObject<CreateTaskResponse>(resp);
|
|
if (gtrr == null) continue;
|
|
if (!gtrr.is_correct) throw new Exception("No answer could be found");
|
|
if (gtrr.text != "")
|
|
{
|
|
Status = CaptchaStatus.Completed;
|
|
return gtrr.text;
|
|
}
|
|
}
|
|
throw new TimeoutException();
|
|
}
|
|
#pragma warning disable 0649
|
|
#pragma warning disable 0414
|
|
class GetBalanceResponse
|
|
{
|
|
public int status;
|
|
public double balance;
|
|
}
|
|
|
|
class CreateRecaptchaTaskRequest
|
|
{
|
|
public string googlekey;
|
|
public string pageurl;
|
|
public CreateRecaptchaTaskRequest(string url, string key) { pageurl = url; googlekey = key; }
|
|
}
|
|
|
|
class CreateCaptchaTaskRequest
|
|
{
|
|
public string clientKey;
|
|
public CaptchaTask task;
|
|
public CreateCaptchaTaskRequest(string apiKey, string base64) { clientKey = apiKey; task = new CaptchaTask(base64); }
|
|
}
|
|
|
|
class CaptchaTask
|
|
{
|
|
public string type = "ImageToTextTask";
|
|
public string body;
|
|
public CaptchaTask(string base64) { body = base64; }
|
|
}
|
|
|
|
class CreateTaskResponse
|
|
{
|
|
public int captcha;
|
|
public int status;
|
|
public bool is_correct;
|
|
public string text;
|
|
public string error;
|
|
}
|
|
|
|
class GetTaskResultRequest
|
|
{
|
|
public string clientKey;
|
|
public int taskId;
|
|
public GetTaskResultRequest(string apiKey, int id) { clientKey = apiKey; taskId = id; }
|
|
}
|
|
|
|
class GetTaskResultCaptchaResponse
|
|
{
|
|
public int errorId;
|
|
public string errorCode;
|
|
public string status;
|
|
public CaptchaSolution solution;
|
|
}
|
|
|
|
class GetTaskResultRecaptchaResponse
|
|
{
|
|
public int errorId;
|
|
public string errorCode;
|
|
public string status;
|
|
public RecaptchaSolution solution;
|
|
}
|
|
|
|
class RecaptchaSolution
|
|
{
|
|
public string gRecaptchaResponse;
|
|
}
|
|
|
|
class CaptchaSolution
|
|
{
|
|
public string text;
|
|
}
|
|
|
|
#pragma warning restore 0414
|
|
#pragma warning restore 0649
|
|
}
|
|
}
|