using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace RuriLib.CaptchaServices
{
///
/// Represent a captcha-solving service.
///
public abstract class CaptchaService
{
///
/// The busy status of the service.
///
public enum CaptchaStatus
{
/// No captcha is being solved.
Idle,
/// A captcha is being solved.
Processing,
/// A captcha was solved.
Completed
}
/// The API key to access the captcha service.
public string ApiKey { get; set; }
/// The username to access the captcha service.
public string User { get; set; }
/// The password to access the captcha service.
public string Pass { get; set; }
/// The maximum time to wait for captcha completion.
public int Timeout { get; set; }
/// The id of the captcha-solving task being performed on the remote server, used to periodically query the status of the task.
public dynamic TaskId { get; set; }
/// The status of the captcha service.
public CaptchaStatus Status { get; set; }
///
/// Creates a captcha service that authenticates via API key.
///
/// The API key of the account
/// The maximum time to wait for captcha completion
public CaptchaService(string apiKey, int timeout)
{
ApiKey = apiKey;
Timeout = timeout;
Status = CaptchaStatus.Idle;
}
///
/// Creates a captcha service that authenticates via username and password.
///
/// The username of the account
/// The password of the account
/// The maximum time to wait for captcha completion
public CaptchaService(string user, string pass, int timeout)
{
User = user;
Pass = pass;
Timeout = timeout;
Status = CaptchaStatus.Idle;
}
///
/// Gets the remaining balance in the account.
///
/// The balance of the account
public virtual double GetBalance()
{
return 0;
}
///
/// Solves a reCaptcha challenge for a given site.
///
/// The SiteKey found in the page's source code
/// The URL of the site to solve a reCaptcha for
/// The g-recaptcha-response of the challenge
public virtual string SolveRecaptcha(string siteKey, string siteUrl)
{
return string.Empty;
}
///
/// Solves an image captcha challenge.
///
/// The bitmap image of the challenge
/// The text written in the image
public virtual string SolveCaptcha(Bitmap image)
{
return string.Empty;
}
///
/// Gets the base64-encoded string from an image.
///
/// The bitmap image
/// The format of the bitmap image
/// The base64-encoded string
protected string GetBase64(Bitmap image, ImageFormat format)
{
MemoryStream stream = new MemoryStream();
image.Save(stream, format);
byte[] imageBytes = stream.ToArray();
return Convert.ToBase64String(imageBytes);
}
///
/// Gets a memory stream from an image.
///
/// The bitmap image
/// The format of the bitmap image
/// The memory stream
protected Stream GetStream(Bitmap image, ImageFormat format)
{
Stream stream = new MemoryStream();
image.Save(stream, format);
return stream;
}
///
/// Gets the bytes from an image.
///
/// The bitmap image
/// The bytes of the image
protected byte[] GetBytes(Bitmap image)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(image, typeof(byte[]));
}
///
/// Performs a synchronous POST request that returns a string.
///
/// The HttpClient that performs the async request
/// The URL to call
/// The content that needs to be posted
/// The response as a string
protected string PostSync(HttpClient client, string url, HttpContent content)
{
return Task.Run(() =>
Task.Run(() =>
client.PostAsync(url, content))
.Result.Content.ReadAsStringAsync())
.Result;
}
///
/// Performs a synchronous POST request that returns a byte array.
///
/// The HttpClient that performs the async request
/// The URL to call
/// The content that needs to be posted
/// The response as a byte array
protected byte[] PostSync2(HttpClient client, string url, HttpContent content)
{
return Task.Run(() =>
Task.Run(() =>
client.PostAsync(url, content))
.Result.Content.ReadAsByteArrayAsync())
.Result;
}
///
/// Performs a synchronous POST request that returns a stream.
///
/// The HttpClient that performs the async request
/// The URL to call
/// The content that needs to be posted
/// The response as a stream
protected Stream PostSync3(HttpClient client, string url, HttpContent content)
{
return Task.Run(() =>
Task.Run(() =>
client.PostAsync(url, content))
.Result.Content.ReadAsStreamAsync())
.Result;
}
///
/// URL encodes a long string.
///
/// The string to encode
/// The encoded string
protected string EscapeLongString(string longString)
{
var escaped = "";
int maxChunkSize = 200;
for (int i = 0; i < longString.Length; i += maxChunkSize)
escaped += Uri.EscapeDataString(longString.Substring(i, Math.Min(maxChunkSize, longString.Length - i)));
return escaped;
}
}
}