【OJ源码分享】gdoj-vjudge 虚拟判题C++实现

ACSolo  发布于 11 年前 2678 2 0


// 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.cn
struct 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 0
string 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 login
if (true != login())
{
cout<<"Login error"<<endl;
}
else
{
cout<<"Login success"<<endl;
}

//test submit
string 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 ms
Sleep(5000);

//test status
string 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 success
DEBUG_INFO: Submit success...
Submit success
FOUND JUDGE RESULT

Get Result From GDOJ:
problem:1001, language:MS C++, verdict:Wrong Answer, submissionID:4019, time:0 ms, memory:936 kb
Verdict:Wrong Answer
Press any key to continue

????

 
 
ID. ???? ??? ?? ?? ???? ?? ??
4019 2013-01-13 23:18:50 ACSolo 1001.???? MS C++ Wrong Answer on test 1 0 ms 936 kb


话题评论 ( 2 )

  • kjyixw  发布于11 年前 Vote: I like it   0   Vote: I do not like it

    全是看不懂的类型和看不懂的函数,这是要闹哪样?!

  • ACSolo  发布于11 年前 Vote: I like it   0   Vote: I do not like it

    一笔一划都把原理话了。这是要闹哪样?!