C# में Capy Puzzle कैसे हल करें और तीनों फ़ील्ड कैसे सबमिट करें

solve capy puzzle in c# - How to Solve Capy Puzzle in C# and Submit All Three Fields

C# में Capy Puzzle हल करने के लिए, पेज से साइट की PUZZLE_ key पढ़ें, उस key और पेज URL के साथ CapyAsync को कॉल करें, फिर वह जो तीन वैल्यू लौटाता है, उन्हें capy_captchakey, capy_challengekey और capy_answer फॉर्म फ़ील्ड में एक साथ और तुरंत पोस्ट करें। पूरा इंटीग्रेशन बस इतना ही है, और लोग जिस हिस्से पर अटकते हैं, वह है जवाब का रूप। आपने जो ज़्यादातर टाइप हल किए होंगे, वे एक token लौटाते हैं। Capy तीन वैल्यू लौटाता है जो सिर्फ़ एक सेट के रूप में काम करती हैं, और उनमें से एक जल्दी expire हो जाती है। CapSkip ने Capy Puzzle को वर्ज़न 1.4.0 में जोड़ा। यह गाइड key, कॉल, जानबूझकर रखा गया दो सेकंड का ठहराव, और सबमिट कवर करती है।

आपको क्या चाहिए

  • किसी Windows मशीन पर चल रहा CapSkip 1.4.0 या उसके बाद का संस्करण। Capy सपोर्ट उसी रिलीज़ में आया था, CaptchaFox और Friendly Captcha के साथ।
  • CapSkip .NET पैकेज का 1.3.0 या उसके बाद का वर्ज़न, यही वह रिलीज़ है जिसमें CapyAsync जोड़ा गया। यह .NET Standard 2.0 को टारगेट करता है और System.Text.Json 8 पर निर्भर है, इसलिए यह .NET Framework 4.6.2 और उसके बाद के संस्करणों पर, तथा .NET 6 और उसके बाद के संस्करणों पर सपोर्टेड है। सैंपल top-level statements और .NET 6 कंसोल प्रोजेक्ट के implicit usings इस्तेमाल करते हैं, इसलिए उन्हें .NET 6 या उसके बाद के संस्करण पर चलाएँ।
  • टारगेट पेज से दो वैल्यू: Capy key, जो PUZZLE_ से शुरू होती है, और उस पेज का URL जिस पर widget चलता है। स्टेप 1 दिखाता है कि key कहाँ मिलती है, और वहीं से यह भी पता चलता है कि आपको तीसरी, वैकल्पिक वैल्यू की ज़रूरत है या नहीं।
  • सॉल्वर के लिए एक पता। Local मोड केवल उसी डिवाइस के लिए 127.0.0.1 पर जवाब देता है; Server मोड आपके नेटवर्क पते या पब्लिक IP पर सुनता है ताकि कोई दूसरी मशीन API के ज़रिए उसे कॉल कर सके। दोनों यहाँ मिलते हैं: कनेक्शन सेटिंग्स, और कब स्विच करना है, यह नीचे के एक सेक्शन में बताया गया है।
# dotnet add package CapSkip
dotnet add package CapSkip

स्टेप 1: PUZZLE_ key और Capy host खोजें

C# में Capy Puzzle हल करने के लिए जो कुछ चाहिए, वह सब टारगेट पेज से ही मिलता है। key सार्वजनिक होती है और हर विज़िटर के लिए एक जैसी होती है, और यह दो जगह मिलती है। widget script के URL का k पैरामीटर उस HTML में होता है जिसे सर्वर भेजता है, और यही HTML पेज के सोर्स में दिखता है और HttpClient को भी मिलता है। ब्राउज़र में widget चल जाने के बाद key एक hidden capy_captchakey input में भी होती है, जिसे widget फॉर्म में लिखता है, और DevTools का Elements पैनल इसे वहीं दिखाता है।

<!-- In the HTML the server sends: the k parameter of the widget script -->
<script src="https://jp.api.capy.me/puzzle/get_js/?k=PUZZLE_YOUR_KEY"></script>

<!-- Written into the form by the widget once it has run (DevTools only) -->
<input type="hidden" name="capy_captchakey" value="PUZZLE_YOUR_KEY" />

key को हूबहू कॉपी करें, prefix समेत। जब आप उस script टैग को देख रहे हों, तो उसका host भी नोट कर लें। script URL में /puzzle/get_js/ से पहले का पूरा हिस्सा वह Capy API है जिसके पीछे key रहती है, और CapSkip उसे api_server कहता है। इसका डिफ़ॉल्ट https://jp.api.capy.me है, जहाँ लाइव सर्विस चलती है, इसलिए इसे सिर्फ़ तब पास करें जब कोई पेज widget को कहीं और से लोड करे।

यहाँ एक जाल दूसरे सॉल्वरों के दस्तावेज़ों से आता है। उनमें से कई अब भी api.capy.me दिखाते हैं, बिना क्षेत्रीय prefix के, और वह host अब resolve नहीं होता। अगर आपने इसे किसी पुराने सैंपल से कॉपी किया है, तो यह ऑप्शन हटा दें और CapSkip को उसका डिफ़ॉल्ट इस्तेमाल करने दें।

स्टेप 2: CapyAsync कॉल

यह method key, पेज URL, और एक वैकल्पिक ऑप्शंस डिक्शनरी लेता है। डिफ़ॉल्ट host वाले पेज के लिए आपको पहले दो के अलावा कुछ नहीं चाहिए।

// dotnet add package CapSkip
using CapSkip;

var solver = new CapSkipClient(host: "127.0.0.1", port: 8080);

// The PUZZLE_ key, and the page the widget runs on.
var result = await solver.CapyAsync(
    "PUZZLE_YOUR_KEY",
    "https://example.com/login");

Console.WriteLine(result.CaptchaKey);    // capy_captchakey
Console.WriteLine(result.ChallengeKey);  // capy_challengekey
Console.WriteLine(result.Answer);        // capy_answer

तीनों नाम वाली प्रॉपर्टी पढ़ें। Code प्रॉपर्टी में वही जवाब raw JSON के रूप में होता है, जो logging के लिए काम का है, और RespKey खाली लौटती है क्योंकि वह सिर्फ़ दूसरी सर्विसों के साथ compatibility के लिए मौजूद है। Answer एक लंबी स्ट्रिंग है, जिसकी शुरुआत 0xax8ex0xax84x जैसी होती है। यह वह ड्रैग पाथ है जो टुकड़ा खिसकते समय widget रिकॉर्ड करता, कोई coordinate नहीं।

ऑप्शंस डिक्शनरी api_server, proxy, proxytype और useragent लेती है, साथ में सेकंड में हर कॉल का अपना timeout भी। user agent, अगर आप सेट करें, तो उस इकलौती रिक्वेस्ट पर भेजा जाता है जो CapSkip पज़ल लाने के लिए करता है, और इसकी ज़रूरत आपको शायद ही कभी पड़ेगी। एक version ऑप्शन भी है, लेकिन उसमें सिर्फ़ puzzle स्वीकार होता है: Capy का दूसरा परिवार, avatar, एक अलग endpoint के पीछे एक अलग challenge है, इसलिए SDK ऐसा जवाब लौटाने के बजाय, जिसे साइट ठुकरा देगी, उसे ValidationException के साथ मना कर देता है। कोई अनजान ऑप्शन नाम, खाली PUZZLE_ key, खाली पेज URL या असमर्थित proxytype, कुछ भी भेजे जाने से पहले यही exception उठाता है। जिस ऑप्शन की वैल्यू null हो, उसे बस हटा दिया जाता है, जिससे आप बिना if statement के एक वैकल्पिक host पास कर सकते हैं।

// The script tag's host. jp.api.capy.me is the default, so pass
// this only when the page loads the widget from somewhere else.
var result = await solver.CapyAsync(
    "PUZZLE_YOUR_KEY",
    "https://example.com/login",
    new Dictionary<string, object?>
    {
        ["api_server"] = "https://jp.api.capy.me/",
    });

Capy solve में लगभग दो सेकंड क्यों लगते हैं

पहचान अपने आप में तेज़ है। CapSkip पज़ल की तस्वीर लाता है, थोड़े से pixel गणित से तस्वीर में कटा खाँचा ढूँढता है, और ड्रैग पाथ बनाता है, यह सब बिना किसी ब्राउज़र या मॉडल के। फिर वह जानबूझकर इंतज़ार करता है।

Capy पज़ल जारी करने और जवाब मिलने के बीच का समय मापता है, और जो भी जवाब इतनी जल्दी आए कि कोई इंसान उतनी देर में टुकड़े को खींच ही न पाता, उसे ठुकरा देता है। Capy पर CapSkip के अपने माप के अनुसार निचली सीमा लगभग एक सेकंड है: आधे सेकंड पर आया जवाब ठुकराया गया, और एक से चार सेकंड तक के जवाब स्वीकार हुए (चार सेकंड परखी गई सबसे लंबी अवधि थी)। इनकार में वही संदेश आता है जो गलत जवाब पर आता है, इसलिए बहुत जल्दी पहुँचाया गया सही solve बिल्कुल खराब सॉल्वर जैसा दिखता है। इसलिए CapSkip हर Capy नतीजे को पज़ल लेने के दो सेकंड बाद तक रोके रखता है। यह इंतज़ार एक sleep है, इसलिए इसकी कीमत latency है, CPU नहीं, और क्योंकि CapyAsync आपके लिए पोलिंग करता है, आपको बस एक कॉल दिखती है जिसमें कुछ सेकंड लगते हैं।

दो नहीं, कुछ सेकंड क्यों: SDK के poll शुरू में चौथाई सेकंड के अंतर पर होते हैं और फिर धीमे पड़ते जाते हैं, हर बार अंतर को दोगुना करते हुए उसके pollingInterval तक, जो डिफ़ॉल्ट रूप से 5 सेकंड है। डिफ़ॉल्ट सेटिंग्स में जवाब आमतौर पर लगभग चौथे सेकंड पर उठाया जाता है। अगर कोई क्लाइंट ज़्यादातर Capy ही हल करता है, तो उसे pollingInterval: 0.5 के साथ बनाएँ, और कॉल दो सेकंड के काफ़ी क़रीब लौट आएगी।

इसके दो व्यावहारिक नतीजे हैं। सबमिट करने से पहले अपनी तरफ़ से कोई देरी न जोड़ें, क्योंकि ठहराव उसे पहले ही कवर कर चुका है। और यह समय घटाने की कोशिश न करें, क्योंकि यही ठहराव जवाब को पास करवाता है।

स्टेप 3: तीनों वैल्यू एक ही रिक्वेस्ट में सबमिट करें

तीनों वैल्यू उन्हीं फ़ील्ड में जाती हैं जिनमें widget उन्हें खुद फॉर्म में लिखता। उन्हें एक साथ भेजें, बाकी फॉर्म वाली उसी रिक्वेस्ट में।

// http is your HttpClient; result comes from Step 2.
var form = new FormUrlEncodedContent(new Dictionary<string, string>
{
    ["username"] = "someone",
    ["capy_captchakey"] = result.CaptchaKey!,
    ["capy_challengekey"] = result.ChallengeKey!,
    ["capy_answer"] = result.Answer!,
});

var response = await http.PostAsync("https://example.com/login", form);

जवाब को ठीक वैसे ही सबमिट करें जैसा वह लौटा है। यह ड्रैग पाथ है, और साइट का backend इसे उस पज़ल से मिलाकर जाँचता है जो जारी हुआ था, इसलिए इसे काटना, इसके हिस्सों से दोबारा बनाना या किसी भी तरह साफ़-सुथरा करना इसे अमान्य कर देता है। फॉर्म बॉडी के लिए इसे percent-encode करना ठीक है, क्योंकि वह सिर्फ़ ट्रांसपोर्ट है और सर्वर पहले उसे decode करता है।

फिर तुरंत सबमिट करें। CapSkip हर solve के लिए एक नई challenge key बनाता है और पज़ल उसी से बँधा होता है, इसलिए key एक ही बार इस्तेमाल होती है और कम समय तक टिकती है। एक solve से एक सबमिशन होता है। अगर फॉर्म अधूरा छोड़कर बाद में फिर शुरू किया जाए, तो रखी हुई वैल्यू इस्तेमाल करने के बजाय दोबारा हल करें।

असली फॉर्म जो भेजता है, वही दोहराएँ। ज़्यादातर पेजों में अपने hidden फ़ील्ड भी होते हैं, जैसे anti-forgery token, और कुछ पेज फॉर्म पोस्ट के बजाय script के ज़रिए JSON बॉडी के साथ सबमिट करते हैं। कई पेज बिना User-Agent header वाली रिक्वेस्ट भी ठुकरा देते हैं, और जब तक आप खुद न जोड़ें, HttpClient यह header नहीं भेजता। DevTools खोलकर एक बार हाथ से सबमिट करें और रिक्वेस्ट कॉपी करें, फिर तीनों Capy वैल्यू वहीं रखें जहाँ पेज उन्हें रखता है।

स्टेप 4: नाकामियाँ, दोबारा कोशिशें और एक साथ कई solve चलाना

जब आप C# में Capy Puzzle किसी भी मात्रा में हल करते हैं, तो कुछ solve फेल होंगे। फेल हुआ Capy solve एक ApiException के रूप में आता है, और SDK के ज़रिए दोनों अहम मामलों में वह unsolvable ही पढ़ा जाता है। दोनों मामलों में उल्टी प्रतिक्रिया चाहिए, और उन्हें अलग पहचानने का तरीका यह है कि वे कितनी बार होते हैं। दोनों जल्दी फेल होते हैं, दो सेकंड के ठहराव से पहले, क्योंकि CapSkip सिर्फ़ हल हो चुके जवाब को रोकता है।

क्या हुआकैसा दिखता हैक्या करें
खाँचा नहीं मिलाकभी-कभार, और अगली कोशिश आमतौर पर कामयाब होती हैदोबारा कोशिश करें। हर कोशिश में किसी दूसरी फ़ोटो पर बिल्कुल नया पज़ल आता है, इसलिए दोबारा कोशिश सचमुच एक स्वतंत्र प्रयास होती है
Capy API ने key मना कर दीउस एक key के लिए हर कोशिश में, और CapSkip की Capy task list में Invalid captcha key दिखता हैkey और api_server जाँचें। CapSkip मना की गई key को दोबारा नहीं आज़माता, क्योंकि वह बिल्कुल उसी तरह फिर मना हो जाती

चूक दुर्लभ होती है, इसलिए एक दोबारा कोशिश लगभग हर मामला सँभाल लेती है। आप अपने कोड में दोबारा कोशिश कर सकते हैं, जैसा पूरा उदाहरण करता है, या CapSkip की सेटिंग्स के Capy सेक्शन में Retries सेट कर सकते हैं, जो डिफ़ॉल्ट रूप से 0 है और हर task के लिए तीन तक की अनुमति देता है।

CapyAsync, defaultTimeout पर पोलिंग करता है, जो 120 सेकंड है, क्योंकि Capy solve कोई ब्राउज़र session नहीं, बल्कि एक fetch और थोड़ा हिसाब भर है। यह एक सामान्य solve के लिए कई गुना काफ़ी है। अगर आप Retries बढ़ाते हैं, या CapSkip जितने solve एक साथ चलाता है उससे कहीं ज़्यादा queue में डालते हैं, तो इसे constructor में बढ़ा दें। Capy सेक्शन की Max. Threads सेटिंग डिफ़ॉल्ट रूप से 10 है, जिसे आप बढ़ा सकते हैं, और अतिरिक्त tasks किसी खाली thread का इंतज़ार करते हैं।

जब आप कई solve parallel में चलाते हैं, तो हर solve को उसके सबमिट के साथ जोड़े रखें। Task.WhenAll से सौ CapyAsync कॉल शुरू करना और नतीजे बाद में पोस्ट करना, सबसे पहली challenge keys को तब तक पुराना होने देता है जब तक आख़िरी solve पूरे होते हैं। solve और सबमिट को एक ही task में साथ लपेटें, और एक साथ चल रहे कामों की संख्या को thread count के बराबर साइज़ वाले SemaphoreSlim से सीमित करें। और बड़ी मात्रा में, प्रॉक्सी जोड़ें। हर solve, Capy API से एक नया पज़ल लेता है, और एक ही पते से ऐसे पज़ल की लगातार धारा ठीक वही पैटर्न है जिसे पकड़ने के लिए rate limiting बनी है। CapSkip में एक प्रॉक्सी पूल कॉन्फ़िगर करें, या हर रिक्वेस्ट के साथ अलग प्रॉक्सी पास करें। यह सिर्फ़ पज़ल fetch को छूता है, जो Capy solve की इकलौती रिक्वेस्ट है।

solver को कहीं और चलाना

सैंपल 127.0.0.1 इस्तेमाल करते हैं, क्योंकि जब तक आपका कोड और CapSkip एक ही मशीन पर हों, यही सही है। जैसे ही .NET ऐप कहीं और चलने लगता है, जैसे किसी कंटेनर, बिल्ड एजेंट, VPS या ऐप सर्विस पर, loopback गलत मशीन की ओर इशारा करता है और पहला ही solve एक NetworkException फेंक देता है। CapSkip को Server मोड पर कर दें और वह आपके नेटवर्क पते या पब्लिक IP पर सुनने लगता है, ताकि इनमें से कोई भी API के ज़रिए उस तक पहुँच सके। अगर रास्ता इंटरनेट से होकर जाता है तो स्टैटिक पब्लिक IP इस्तेमाल करें, API key validation चालू करें, और Windows Firewall नियम से पोर्ट को सिर्फ़ अपेक्षित पतों तक सीमित रखें। यह अब भी आपकी अपनी Windows मशीन है, और हल करना अब भी बिना मीटर वाला है।

क्लाइंट एनवायरनमेंट वेरिएबल खुद नहीं पढ़ता। CAPSKIP_HOST और CAPSKIP_API_KEY को अपने कोड में पढ़ें और उन्हें constructor को पास करें, जैसा पूरा उदाहरण करता है, ताकि वही build आपकी डेस्क पर भी चले और सर्वर पर भी।

पूरा चलने वाला उदाहरण

// dotnet add package CapSkip
using System.Text.RegularExpressions;
using CapSkip;

var pageUrl = "https://example.com/login";
var http = new HttpClient();
var solver = new CapSkipClient(
    apiKey: Environment.GetEnvironmentVariable("CAPSKIP_API_KEY") ?? "capskip",
    host: Environment.GetEnvironmentVariable("CAPSKIP_HOST") ?? "127.0.0.1",
    port: 8080,
    // Capy answers after a two second hold; poll often enough to catch it.
    pollingInterval: 0.5);

// The widget script's k parameter. The capy_captchakey input only
// exists once the widget has run in a browser.
var html = await http.GetStringAsync(pageUrl);
var key = Regex.Match(html, "PUZZLE_[A-Za-z0-9_-]+").Value;
if (key.Length == 0)
    throw new InvalidOperationException("No PUZZLE_ key in the HTML; check DevTools.");

// The script URL up to /puzzle/get_js/, when there is one; a null value is dropped.
var host = Regex.Match(html, @"(https://[^""'\s<>]+?)/puzzle/get_js/").Groups[1].Value;
var options = new Dictionary<string, object?>
{
    ["api_server"] = host.Length > 0 ? host : null,
};

try
{
    // A missed hole comes back unsolvable; a retry draws a new puzzle.
    SolveResult? result = null;
    for (var attempt = 1; result is null; attempt++)
    {
        try
        {
            result = await solver.CapyAsync(key, pageUrl, options);
        }
        catch (ApiException ex) when (attempt < 3 && ex.Message.Contains("UNSOLVABLE"))
        {
            Console.WriteLine($"attempt {attempt}: {ex.Message}");
        }
    }

    // All three together, straight away: the challenge key is single-use.
    var form = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        ["username"] = "someone",
        ["capy_captchakey"] = result.CaptchaKey!,
        ["capy_challengekey"] = result.ChallengeKey!,
        ["capy_answer"] = result.Answer!,
    });

    // Post wherever the form's action attribute points.
    var response = await http.PostAsync(pageUrl, form);
    Console.WriteLine((int)response.StatusCode);
}
catch (CapSkip.ValidationException ex)
{
    // An empty key or URL, avatar as the version, or an unknown option.
    Console.WriteLine($"not sent: {ex.Message}");
}
catch (CapSkip.TimeoutException)
{
    Console.WriteLine("gave up waiting; defaultTimeout is 120 seconds");
}
catch (CapSkipError ex)
{
    // The third miss, a refused key, or CapSkip unreachable.
    Console.WriteLine($"gave up: {ex.Message}");
}

key वाला regex पूरे HTML में कहीं भी PUZZLE_ prefix ढूँढता है, इसलिए वह script टैग को parse किए बिना ही key को widget script के URL से निकाल लेता है। capy_captchakey input डाउनलोड किए गए HTML में होता ही नहीं, क्योंकि widget उसे सिर्फ़ तब लिखता है जब वह ब्राउज़र में चलता है। host वाला regex किसी https script URL में /puzzle/get_js/ से पहले का पूरा हिस्सा रखता है, path समेत, और जब उसे कुछ नहीं मिलता तो null वैल्यू हटा दी जाती है और CapSkip अपना डिफ़ॉल्ट इस्तेमाल करता है। अगर तीनों कोशिशें फेल हों, तो सबसे पहले key देखें, क्योंकि मना की गई key हर बार एक ही तरह फेल होती है, जबकि चूक लगभग कभी लगातार तीन बार नहीं होती। जब पेज widget को किसी bundled script से बनाता है और कोई भी regex मैच नहीं करता, तो Network टैब खोलें और दोनों वैल्यू widget की अपनी रिक्वेस्ट से कॉपी करें। इस method के पीछे का raw endpoint यहाँ दर्ज है: API रेफ़रेंस, और पैकेज जो बाकी सभी कैप्चा टाइप हल करता है, वे सब यहाँ हैं: C# कैप्चा सॉल्वर पेज.

आम errors और उनका मतलब

आप जो देखते हैंकारणफिक्स
CapSkip के तीनों वैल्यू लौटाने के बावजूद साइट सबमिट ठुकरा देती हैजवाब बदल दिया गया, या वैल्यू में से सिर्फ़ एक या दो ही फॉर्म तक पहुँचींresult.Answer को हूबहू, बाकी दो वैल्यू के साथ, एक ही रिक्वेस्ट में पोस्ट करें
एक बार चल चुका सबमिट दूसरी कोशिश में फेल हो जाता हैchallenge key एक ही बार इस्तेमाल होती है और कम समय तक टिकती हैहर सबमिशन के लिए दोबारा हल करें, और तुरंत सबमिट करें
एक ही key के लिए हर कोशिश पर एक ApiExceptionCapy API ने key मना कर दी, या api_server गलत host की ओर इशारा करता हैkey को prefix समेत दोबारा कॉपी करें, और script टैग का host जाँचें
कभी-कभार आने वाला ApiException, जो कहता है कि कैप्चा unsolvable हैCapSkip उस पज़ल में खाँचा नहीं ढूँढ पायादोबारा कोशिश करें; अगली कोशिश में दूसरा पज़ल आता है
किसी दूसरी सर्विस से सैंपल कॉपी करने के बाद हर solve फेल होता हैसैंपल api_server को api.capy.me पर सेट करता है, जो अब resolve नहीं होतायह ऑप्शन हटा दें और डिफ़ॉल्ट host इस्तेमाल करें
कुछ भी भेजे जाने से पहले ही ValidationExceptionखाली key या पेज URL, version के रूप में avatar, या ऐसा ऑप्शन जो यह method नहीं लेताजाँचें कि regex को key मिली, और संदेश में बताया गया ऑप्शन हटा दें
लंबा रन आगे बढ़ने के साथ ज़्यादा नाकामियाँहर पज़ल एक ही पते से लिया जाता हैsolve को CapSkip में कॉन्फ़िगर किए गए प्रॉक्सी पूल में बाँटें
भारी parallel लोड में TimeoutExceptionqueue में उससे ज़्यादा tasks हैं जितने Max. Threads 120 सेकंड के भीतर निपटा सकता हैSemaphoreSlim से concurrency सीमित करें, या defaultTimeout बढ़ाएँ
पहले solve पर एक NetworkExceptionCapSkip चल नहीं रहा, या host और port गलत हैंCapSkip शुरू करें, फिर देखें कि उसे Local मोड में होना चाहिए या Server मोड में
build किसी अस्पष्ट TimeoutException पर फ़ेल हो जाता हैCapSkip और System, दोनों उस छोटे नाम को परिभाषित करते हैंपूरा CapSkip.TimeoutException लिखें, या CapSkipError कैच करें

FAQ

Capy हल एक token के बजाय तीन values क्यों लौटाता है?

क्योंकि Capy फॉर्म यही पोस्ट करता है। किसी भी मोड़ पर कोई सर्वर token जारी नहीं करता। widget खुद एक challenge key बनाता है, उससे जुड़ा पज़ल लाता है, और ड्रैग रिकॉर्ड करता है, और फिर साइट challenge key और जवाब को अपनी private key के साथ Capy को भेजती है ताकि उनकी जाँच हो सके। CapSkip widget की भूमिका निभाता है, इसलिए वह वही लौटाता है जो widget फॉर्म में लिखता।

क्या किसी होस्टेड प्लेटफ़ॉर्म पर चल रहा .NET ऐप solver तक पहुँच सकता है?

हाँ। कनेक्शन सेटिंग्स में CapSkip को Server मोड पर कर दें ताकि वह loopback के बजाय किसी नेटवर्क पते पर सुने, वह पता अपने कोड में CAPSKIP_HOST से पढ़ें, और उसे क्लाइंट को पास करें। कंटेनर होस्ट, VPS, CI एजेंट और मैनेज्ड ऐप सर्विस, सब उसी तरह जुड़ते हैं, उसी HTTP API के ज़रिए। अगर रास्ता इंटरनेट से होकर जाता है तो फ़ायरवॉल नियम के साथ स्टैटिक पब्लिक IP इस्तेमाल करें। सॉल्वर आपके अपने हार्डवेयर पर ही रहता है, इसलिए लाइसेंस या हल की गिनती में कुछ नहीं बदलता।

यह C# में GeeTest v3 हल करने से कैसे अलग है?

दोनों slide पज़ल हैं जो कई वैल्यू लौटाते हैं और वे वैल्यू एक साथ पोस्ट होती हैं, लेकिन दोनों की शुरुआत अलग जगह से होती है। GeeTest v3 साइट के जारी किए गए challenge से शुरू होता है, जिसे आपको हल करने से ठीक पहले fetch करना होता है, क्योंकि वह लगभग एक मिनट के भीतर expire हो जाता है। Capy सिर्फ़ key से शुरू होता है, क्योंकि challenge key, solve के समय बनती है, इसलिए पहले fetch करने को कुछ नहीं होता और जो इकलौती घड़ी मायने रखती है, वह solve के बाद चलती है। GeeTest वाला पहलू यहाँ कवर किया गया है: C# GeeTest v3 गाइड.

क्या CaptchaFox की तरह मुझे सबमिट के साथ user agent भेजना होगा?

नहीं। CaptchaFox का token उस ब्राउज़र से बँधा होता है जिसने उसे बनाया, इसलिए सबमिट के साथ उसी ब्राउज़र का user agent जाना चाहिए, जैसा C# CaptchaFox गाइड में बताया गया है। Capy का जवाब किसी ब्राउज़र से बिल्कुल नहीं बँधा होता। CapSkip इसके लिए कोई user agent नहीं लौटाता, और जो वैकल्पिक user agent आप पास कर सकते हैं, वह सिर्फ़ पज़ल लाने वाली रिक्वेस्ट को बदलता है।

संक्षेप में

C# में Capy Puzzle हल करने के लिए, PUZZLE_ key को widget script के URL या capy_captchakey input से कॉपी करें, और script का host नोट कर लें, कहीं वह डिफ़ॉल्ट न हो। CapyAsync को key और असली पेज URL के साथ कॉल करें और उसे अपने कुछ सेकंड लेने दें। CaptchaKey, ChallengeKey और Answer को capy_captchakey, capy_challengekey और capy_answer में पोस्ट करें, हूबहू, एक साथ और तुरंत, और हर सबमिशन के लिए दोबारा हल करें। कभी-कभार की चूक पर दोबारा कोशिश करें, volume बढ़ने के साथ प्रॉक्सी जोड़ें, और जैसे ही कॉल करने वाला कोड सॉल्वर की मशीन से बाहर जाए, Server मोड पर चले जाएँ।

उस दोबारा कोशिश के बारे में एक आख़िरी बात। क्योंकि हर कोशिश में एक अलग पज़ल आता है, इसलिए चूक का सही इलाज दोबारा कोशिश करना ही है, और अपनी ही मशीन पर चलने वाले लोकल captcha सॉल्वर के साथ दूसरी कोशिश में बस कुछ सेकंड लगते हैं, किसी और बिल किए गए solve का ख़र्च नहीं।