// gdoj-vjudge.cpp : Defines the entry point for the console application.///*
#include <io.h>#include "curl/curl.h"#include <iostream>#include <cstdio>#include <string>#include <fstream>#include <stdio.h>
using namespace std;
#pragma comment(lib, "curllib.lib")#pragma comment(lib, "openldap.lib")#pragma comment(lib, "ssleay32.lib")
CURL *curl;CURLcode res;char tmps[1000000];
char username[1000]="username";char password[1000]="password";char tfilename[1000]="tmpfile.txt";char domain[255]="acm.guet.edu.cn"; //acm.guet.edu.cnstruct curl_slist *headerlist=NULL;
#define DEBUG_PRINT(X) X
#define UCHAR unsigned char#define ULONG unsigned long#define CHAR char
#define BOOL_TRUE 0#define BOOL_FALSE 1
#define MAX_LANG_SIZE 255
UCHAR gaucLanguageName[][MAX_LANG_SIZE] = {"All","MS C++","MS C","GNU C++","GNU C","Java","C#","F#","Pascal","Python","Ruby","Perl","Lua","Tcl","Pike","Haskell","PHP","BrainFuck","Befunge","GO","Scala","JavaScript","Groovy"};
ULONG getLanguageNameByID(ULONG id, UCHAR *ucLanguageName){if (id < 0 || id >= sizeof(gaucLanguageName)/MAX_LANG_SIZE){return BOOL_FALSE;}
strcpy((char *)ucLanguageName, (char *)gaucLanguageName[id]);return BOOL_TRUE;}
ULONG getLanguageIDByName(UCHAR *ucLanguageName, ULONG *id){USHORT usLoop = 0;
for (usLoop = 0; usLoop <= sizeof(gaucLanguageName)/MAX_LANG_SIZE; ++usLoop){if (strcmp((CHAR*)ucLanguageName, (CHAR*)gaucLanguageName[usLoop]) == 0){*id = usLoop;return BOOL_TRUE;}}return BOOL_FALSE;}
void DEBUG_OUTPUT(const char *ucInfo){printf("DEBUG_INFO: ");printf("%s\n",ucInfo);}
bool isSpace(char c){if(c==' '||c=='\n'||c=='\t'){return true;}return false;}
char dec2hexChar(short int n){if ( 0 <= n && n <= 9 ) return char( short('0') + n );else if ( 10 <= n && n <= 15 )return char( short('A') + n - 10 );else return char(0);}short int hexChar2dec(char c){if ( '0'<=c && c<='9' ) return short(c-'0');else if ( 'a'<=c && c<='f' ) return ( short(c-'a') + 10 );else if ( 'A'<=c && c<='F' ) return ( short(c-'A') + 10 );else return -1;}
string escapeURL(const string &URL){string result = "";for ( unsigned int i=0; i<URL.size(); i++ ){char c = URL[i];if (( '0'<=c && c<='9' ) ||( 'a'<=c && c<='z' ) ||( 'A'<=c && c<='Z' ) ||c=='/' || c=='.') result += c;else {int j = (short int)c;if ( j < 0 ) j += 256;int i1, i0;i1 = j / 16;i0 = j - i1*16;result += '%';result += dec2hexChar(i1);result += dec2hexChar(i0);}}return result;}
string deescapeURL(const string &URL){string result = "";for ( unsigned int i=0; i<URL.size(); i++ ){char c = URL[i];if ( c != '%' ) result += c;else {char c1 = URL[++i];char c0 = URL[++i];int num = 0;num += hexChar2dec(c1) * 16 + hexChar2dec(c0);result += char(num);}}return result;}
string getAllFromFile(char *filename) {string res="";FILE * fp=fopen(filename,"r");while (fgets(tmps,1000000,fp)) res+=tmps;fclose(fp);return res;}
size_t process_data(void *buffer, size_t size, size_t nmemb, void *user_p){FILE *fp = (FILE *)user_p;size_t return_size = fwrite(buffer, size, nmemb, fp);//cout << (char *)buffer << endl;return return_size;}
bool login(){FILE * fp=fopen(tfilename,"w+");curl = curl_easy_init();if(curl) {curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &process_data);curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "gdoj.cookie");char url[255] = {0};sprintf(url, "http://%s/gdoj/login", domain);
curl_easy_setopt(curl, CURLOPT_URL, url);string post=(string)"handle="+username+"&password="+password;curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post.c_str());res = curl_easy_perform(curl);
curl_easy_cleanup(curl);}
fclose(fp);if (res) return false;string ts=getAllFromFile(tfilename);if (ts.find("username is not exist.")!=string::npos){puts("Login failed.");return false;}return true;}
ULONG getSubmitError(char *filename, string &res){string ts;res = "";FILE * fp=fopen(filename,"r");int begin_ = 0;int end_ = 0;while (fgets(tmps,1000000,fp)){ts=tmps;if (ts.find("<form id=\"submit\" name=\"submit\"")!=string::npos){while (fgets(tmps,1000000,fp)){ts=tmps;begin_ = ts.find("<span>");if (begin_!=string::npos){//cout<<"Sorry! FOUND SUBMIT_INFO"<<endl;end_ = ts.find("</span>");if (end_ !=string::npos){begin_ += 6;res = ts.substr(begin_,end_ - begin_);//cout<<res<<endl;fclose(fp);return BOOL_TRUE;}while (fgets(tmps,1000000,fp)){ts=tmps;end_ = ts.find("</span>");if (end_ !=string::npos){begin_ += 6;res = ts.substr(begin_,end_ - begin_);//cout<<res<<endl;fclose(fp);return BOOL_TRUE;}else{res=res+ts;}}break;}}break;}}fclose(fp);return BOOL_FALSE;}
ULONG submit(string pid,string lang,string source){FILE * fp=fopen(tfilename,"w+");curl = curl_easy_init();if(curl) {curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &process_data);curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "gdoj.cookie");char url[255] = {0};sprintf(url, "http://%s/gdoj/problemset/submited", domain);curl_easy_setopt(curl, CURLOPT_URL, url);
string post=(string)"problemId="+pid+"&language="+lang+"&source="+escapeURL(source);curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post.c_str());res = curl_easy_perform(curl);curl_easy_cleanup(curl);}fclose(fp);if (res) return BOOL_FALSE;string tss;if (BOOL_TRUE == getSubmitError(tfilename, tss)){DEBUG_OUTPUT("submit error, say follow info.!");DEBUG_OUTPUT(tss.c_str());return BOOL_FALSE;}
DEBUG_OUTPUT("Submit success...");
return BOOL_TRUE;}
ULONG getResult(string s, string &res){int pos=s.find("verdict ");if (-1 == pos){return BOOL_FALSE;}
if (s.find("verdict_ce")!=string::npos){res = "Compilation Error";return BOOL_TRUE;}
while (s[pos]!='>') pos++;pos++;while (isSpace(s[pos])) pos++;int st=pos;while (s[pos]!='<') pos++;
res = s.substr(st,pos-st);int l = res.length();
//cout<<res;
while (isSpace(res[l-1])){
res[l-1]='\0';l--;}
return BOOL_TRUE;}
ULONG getRunid(string s, string &rid){int pos=s.find("id=\"status_");if (-1 == pos){return BOOL_FALSE;}
while (s[pos]!='_') pos++;pos++;
int st=pos;while (s[pos]!='\"') pos++;
rid = s.substr(st,pos-st);
return BOOL_TRUE;}
string getCEinfo_brief(char *filename){string res="",ts;FILE * fp=fopen(filename,"r");
while (fgets(tmps,1000000,fp)){ts=tmps;if (ts.find("<div id=\"body\">")!=string::npos){while (fgets(tmps,1000000,fp)){ts=tmps;if (ts.find("<pre class=\"code\">")!=string::npos){while (fgets(tmps,1000000,fp)){ts=tmps;if (ts.find("</pre>")!=string::npos){cout<<"FOUND CE_INFO"<<endl;;break;}else{res=res+ts;}}break;}}break;}}fclose(fp);return res;}
string getCEinfo(string runid){FILE *fp = fopen(tfilename, "ab+");curl = curl_easy_init();if(curl){curl_easy_setopt( curl, CURLOPT_VERBOSE, 0L );curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "gdoj.cookie");char url[255] = {0};sprintf(url, "http://%s/view-compileinfo/%s",domain ,runid.c_str());curl_easy_setopt( curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &process_data);curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);curl_easy_cleanup(curl);}fclose(fp);
string info = getCEinfo_brief(tfilename);return info;}
ULONG getUsedTime(string s, string &timeuse){int pos=s.find(" ms");if (-1 == pos){return BOOL_FALSE;}
int st=pos;pos--;
while (s[pos]!='>') pos--;pos++;
timeuse = s.substr(pos,st-pos);return BOOL_TRUE;}
ULONG getUsedMem(string s, string &memuse){int pos=s.find(" kb");if (-1 == pos){return BOOL_FALSE;}
int st=pos;pos--;
while (s[pos]!='>') pos--;pos++;
memuse = s.substr(pos,st-pos);return BOOL_TRUE;}
ULONG getProblemID(string s, string &pid){int pos=s.find("problemset/problem/");if (-1 == pos){return BOOL_FALSE;}
while (!isdigit(s[pos])) pos++;
int st=pos;while (s[pos]!='\"') pos++;
pid = s.substr(st,pos-st);
return BOOL_TRUE;}
ULONG getLanguage(string s, string &lang){int pos=s.find("class=\"language\"");if (-1 == pos){return BOOL_FALSE;}while (s[pos]!='>') pos++;pos++;
int st=pos;while (s[pos]!='<') pos++;lang = s.substr(st,pos-st);return BOOL_TRUE;}
#if 0string convertResult(string res) {if (res.find("Compilation error")!=string::npos) return "Compile Error";if (res.find("Wrong answer")!=string::npos) return "Wrong Answer";if (res.find("Runtime error")!=string::npos) return "Runtime Error";if (res.find("Time limit exceeded")!=string::npos) return "Time Limit Exceed";if (res.find("Idleness")!=string::npos||res.find("Memory limit exceeded")!=string::npos) return "Memory Limit Exceed";if (res.find("Denial of")!=string::npos) return "Judge Error";if (res.find("Judgement failed")!=string::npos) return "Judge Error";return res;}#endif
string getResFromFile(char *filename){string res="",ts;FILE * fp=fopen(filename,"r");
while (fgets(tmps,1000000,fp)){ts=tmps;if (ts.find("<table class=\"status\">")!=string::npos){res=tmps;while (fgets(tmps,1000000,fp)){ts=tmps;if (ts.find("<tr class=\"dark\">")!=string::npos){while (fgets(tmps,1000000,fp)){ts=tmps;if (ts.find("</tr>")!=string::npos){cout<<"FOUND JUDGE RESULT"<<endl;;break;}else{res=res+ts;}}break;}}break;}}fclose(fp);return res;}
ULONG getStatus(string pid,string lang,string &result,string& ce_info,string &tu,string &mu){ULONG ulRet = BOOL_TRUE;string runid;tu=mu="0";string ts;
CURL *curl;CURLcode res;curl = curl_easy_init();if ( curl ) {FILE *fp = fopen(tfilename, "ab+");curl_easy_setopt( curl, CURLOPT_VERBOSE, 0L );curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "gdoj.cookie");char url[255] = {0};sprintf(url, "http://%s/gdoj/problemset/status/with/%s/page/1", domain, username);
curl_easy_setopt( curl, CURLOPT_URL, url);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &process_data);curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform( curl );curl_easy_cleanup(curl);}
ts = getResFromFile(tfilename);string problemID;if(BOOL_FALSE == getProblemID(ts, problemID)){DEBUG_OUTPUT("getProblemID failed.");}
string language;if(BOOL_FALSE == getLanguage(ts, language)){DEBUG_OUTPUT("getLanguage failed.");}
if (problemID != pid || language != lang){printf("problem or language is not match. (problemID=%s, language=%s, pid=%s, lang=%s)",problemID.c_str(), language.c_str(), pid.c_str(), lang.c_str());return BOOL_FALSE;}
if(BOOL_FALSE == getUsedTime(ts, tu)){++ulRet;DEBUG_OUTPUT("getUsedTime failed.");}
if(BOOL_FALSE == getUsedMem(ts, mu)){++ulRet;DEBUG_OUTPUT("getUsedMem failed.");}
if(BOOL_FALSE == getRunid(ts, runid)){++ulRet;DEBUG_OUTPUT("getRunid failed.");}
if(BOOL_FALSE == getResult(ts, result)){++ulRet;DEBUG_OUTPUT("getResult failed.");}
if (BOOL_TRUE != ulRet){DEBUG_OUTPUT("get record failed.");return BOOL_FALSE;}
printf("\r\nGet Result From GDOJ:\r\nproblem:%s, language:%s, verdict:%s, submissionID:%s, time:%s ms, memory:%s kb\r\n", problemID.c_str(), language.c_str(), result.c_str(), runid.c_str(), tu.c_str(), mu.c_str());
if (result.find("Compilation Error")!=string::npos){//????????string CE_Info = getCEinfo(runid);cout<<CE_Info<<endl;}
return BOOL_TRUE;}
int main(int argc, char *argv[]){if (access(tfilename, 0) == 0){DeleteFile(tfilename);}
curl_global_init(CURL_GLOBAL_ALL);
//test loginif (true != login()){cout<<"Login error"<<endl;}else{cout<<"Login success"<<endl;}
//test submitstring code = "#include <iostream>\n using namespace std;int main(){int a,b;cin>>a>>b;cout<<a+b<<endl;}";string pid = "1001";string l = "1";if (BOOL_TRUE != submit(pid,l, code)){cout<<"Submit error"<<endl;return 0;}else{cout<<"Submit success"<<endl;}//??10000 msSleep(5000);
//test statusstring result,ce_info,tu,mu;int langId = atoi(l.c_str());UCHAR *lang_str=NULL;lang_str = (UCHAR *)malloc(sizeof(UCHAR)*MAX_LANG_SIZE);getLanguageNameByID((ULONG)langId, lang_str);
string lang_string = (char*)lang_str;if (BOOL_TRUE != getStatus(pid, lang_string, result, ce_info, tu, mu)){cout<<"getStatus error"<<endl;}else{cout<<"Verdict:"<<result<<endl;}free(lang_str);
return 0;}
////////////////////////////?????Login successDEBUG_INFO: Submit success...Submit successFOUND JUDGE RESULT
Get Result From GDOJ:problem:1001, language:MS C++, verdict:Wrong Answer, submissionID:4019, time:0 ms, memory:936 kbVerdict:Wrong AnswerPress any key to continue
????
全是看不懂的类型和看不懂的函数,这是要闹哪样?!
一笔一划都把原理话了。这是要闹哪样?!