diff --git a/cf.go b/cf.go index 44290328..5c319838 100644 --- a/cf.go +++ b/cf.go @@ -15,7 +15,7 @@ import ( docopt "github.com/docopt/docopt-go" ) -const version = "v1.0.0" +const version = "v1.0.1" const configPath = "~/.cf/config" const sessionPath = "~/.cf/session" @@ -63,7 +63,7 @@ Examples: cf submit cf will detect what you want to submit automatically. cf submit -f a.cpp cf submit https://codeforces.com/contest/100/A - cf submit -f a.cpp 100A + cf submit -f a.cpp 100A cf submit -f a.cpp 100 a cf submit contest 100 a cf submit gym 100001 a diff --git a/client/langs.go b/client/langs.go index b09c69fd..6253e696 100644 --- a/client/langs.go +++ b/client/langs.go @@ -9,6 +9,7 @@ var Langs = map[string]string{ "42": "GNU G++11 5.1.0", "50": "GNU G++14 6.4.0", "54": "GNU G++17 7.3.0", + "73": "GNU G++20 11.2.0 (64 bit, winlibs)", "2": "Microsoft Visual C++ 2010", "59": "Microsoft Visual C++ 2017", "9": "C# Mono 5.18", @@ -60,6 +61,7 @@ var LangsExt = map[string]string{ "GNU C++11": "cpp", "GNU C++14": "cpp", "GNU C++17": "cpp", + "GNU G++20": "cpp", "MS C++": "cpp", "MS C++ 2017": "cpp", "Mono C#": "cs", diff --git a/client/parse.go b/client/parse.go index 382b7345..0792d045 100644 --- a/client/parse.go +++ b/client/parse.go @@ -26,9 +26,11 @@ func findSample(body []byte) (input [][]byte, output [][]byte, err error) { if a == nil || b == nil || len(a) != len(b) { return nil, nil, fmt.Errorf("Cannot parse sample with input %v and output %v", len(a), len(b)) } - newline := regexp.MustCompile(`<[\s/br]+?>`) + startline := regexp.MustCompile(`<[\s\S.]+?>`) + endline := regexp.MustCompile(``) filter := func(src []byte) []byte { - src = newline.ReplaceAll(src, []byte("\n")) + src = endline.ReplaceAll(src, []byte("\n")) + src = startline.ReplaceAll(src, []byte("")) s := html.UnescapeString(string(src)) return []byte(strings.TrimSpace(s) + "\n") } diff --git a/util/util.go b/util/util.go index e8e0210f..6ec7ef56 100644 --- a/util/util.go +++ b/util/util.go @@ -2,6 +2,7 @@ package util import ( "bufio" + "encoding/hex" "encoding/json" "fmt" "io/ioutil" @@ -11,7 +12,10 @@ import ( "net/url" "os" "strconv" + "regexp" "strings" + "crypto/aes" + "crypto/cipher" "github.com/fatih/color" ) @@ -72,6 +76,35 @@ func YesOrNo(note string) bool { } } +// GetBody read body +func SetRCPC(client *http.Client, body []byte, URL string) ([]byte, error) { + reg := regexp.MustCompile(`toNumbers\("(.+?)"\)`) + res := reg.FindAllStringSubmatch(string(body), -1) + text, _ := hex.DecodeString( res[2][1] ) + key, _ := hex.DecodeString( res[0][1] ) + iv, _ := hex.DecodeString( res[1][1] ) + + block, _ := aes.NewCipher(key) + mode := cipher.NewCBCDecrypter(block, iv) + + mode.CryptBlocks([]byte(text), []byte(text)) + + var cookies []*http.Cookie + cookie := &http.Cookie{ + Name: "RCPC", + Value: hex.EncodeToString(text), + Path: "/", + Domain: ".codeforces.com", + } + cookies = append(cookies, cookie) + u, _ := url.Parse("https://codeforces.com/") + client.Jar.SetCookies(u, cookies) + + reg = regexp.MustCompile(`href="(.+?)"`) + link := reg.FindSubmatch(body)[1] + return GetBody( client, string(link) ) +} + // GetBody read body func GetBody(client *http.Client, URL string) ([]byte, error) { resp, err := client.Get(URL) @@ -79,7 +112,14 @@ func GetBody(client *http.Client, URL string) ([]byte, error) { return nil, err } defer resp.Body.Close() - return ioutil.ReadAll(resp.Body) + body, err := ioutil.ReadAll(resp.Body); + reg := regexp.MustCompile(`Redirecting...`) + is_redirected := ( len( reg.FindSubmatch(body) ) > 0 ); + + if is_redirected { + return SetRCPC(client, body, URL) + } + return body, err } // PostBody read post body