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; } } }