/
godbc.go
151 lines (135 loc) · 4.08 KB
/
godbc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package godbc
import (
"bytes"
"io/ioutil"
"net/http"
"strconv"
"errors"
"net/url"
"mime/multipart"
"encoding/json"
)
const (
dbcAPIURL = "http://api.dbcapi.me/api/"
uploadURL = "http://api.dbcapi.me/api/captcha"
reportURL = "http://api.dbcapi.me/api/captcha/%CAPTCHA_ID%/report"
statusURL = "http://api.dbcapi.me/api/captcha/%CAPTCHA_ID%"
userURL = "http://api.dbcapi.me/api/user"
dbcstatURL = "http://api.dbcapi.me/api/status"
)
//CaptchaClient is used to send captcha to DBC servers
type CaptchaClient struct {
Username string
Password string
SiteKey string
SiteURL string
Proxy string
ProxyType string
JSONString string
Timeout uint8 //180 is the max
PollRate int8 //5 seconds
LastStatus CaptchaStatus
}
//Decode sends the captcha to dbc servers
func (c *CaptchaClient)Decode(timeout uint8) (int, error) {
c.Timeout = timeout
c.ParamToString()
buffer := new(bytes.Buffer)
writer := multipart.NewWriter(buffer)
_ = writer.WriteField("type", "4")
_ = writer.WriteField("password", c.Password)
_ = writer.WriteField("token_params", c.JSONString)
_ = writer.WriteField("username", c.Username)
_ = writer.WriteField("swid", "0") //seems hardcoded to 0
req, err := http.NewRequest(http.MethodPost, uploadURL, buffer)
if err != nil {
return 0, err
}
req.Header.Add("Accept", "application/json")
req.Header.Add("User-Agent", "DBC/.NET v4.5") //not sure if using something else will trigger their systems
req.Header.Add("Connection", "close")
req.Header.Add("Content-Type", "multipart/form-data; boundary="+writer.Boundary())
req.Header.Add("Content-Length", string(req.ContentLength))
req.Header.Add("Host", "api.dbcapi.me")
cli := new(http.Client)
resp, err := cli.Do(req)
if err != nil {
return 0, err
}
actualResponse := CaptchaStatusReal{}
json.NewDecoder(resp.Body).Decode(&actualResponse)
return actualResponse.CaptchaID, nil
}
//ParamToString turns variables into hardcoded json string. DBC hires cheap coders, gets cheap programs... and it's a pain to accomodate
func (c *CaptchaClient)ParamToString() {
if c.Proxy != "" {
c.JSONString = `{ "proxy": "`+c.Proxy+`", "proxytype": "`+c.ProxyType+`", "googlekey": "`+c.SiteKey+`", "pageurl": "`+c.SiteURL+`" }`
} else {
c.JSONString = `{ "googlekey": "`+c.SiteKey+`", "pageurl": "`+c.SiteURL+`" }`
}
}
//PollCaptcha keeps sending a get request to dbc for updated captcha results
func (c *CaptchaClient)PollCaptcha(id int) error {
realID := strconv.Itoa(id)
fullURL := uploadURL + "/" + realID
//username and password are not required
cli := new(http.Client)
resp, err := cli.Get(fullURL)
if err != nil {
return err
}
defer resp.Body.Close()
bod, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
vals, err := url.ParseQuery(string(bod))
if err != nil {
return err
}
if len(vals) != 2 {
cap := CaptchaStatus{}
cap.CaptchaID = vals.Get("captcha")
cap.Status = vals.Get("status")
cap.IsCorrect = vals.Get("is_correct")
cap.Text = vals.Get("text")
c.LastStatus = cap
} else {
return errors.New("Dead captcha")
}
return nil
}
//GetText returns the text from the captcha
func (c *CaptchaClient)GetText() string {
return c.LastStatus.Text
}
//UpdateURL is used for registration pages that may have account-based parameters in their fields
func (c *CaptchaClient)UpdateURL(url string) {
c.SiteURL = url
}
//UpdateProxy updates the currently set proxy in the captcha client
func (c *CaptchaClient)UpdateProxy(proxy string) {
c.Proxy = proxy
}
//UpdatePollRate updates the polling rate
func (c *CaptchaClient)UpdatePollRate(rate int8) error {
if rate < 5 {
return errors.New("using a pollrate lower than 5 can potentially get you banned from DBC. Pollrate not adjusted")
}
c.PollRate = rate
return nil
}
//CaptchaStatus is the struct returned when polling a captchas status
type CaptchaStatus struct {
Status string
CaptchaID string
IsCorrect string
Text string
}
//CaptchaStatusReal is the actual json response when uploading captchas
type CaptchaStatusReal struct {
Status int `json:"status"`
CaptchaID int `json:"captcha"`
IsCorrect bool `json:"is_correct"`
Text string `json:"text"`
}