void dointeractive() { LOG("Runid: " + Inttostring(bott->Getrunid()) + " Type: Interactive"); retbott.Settype(RESULT_REPORT); retbott.Setrunid(bott->Getrunid()); Interactive * usrprogram = new Interactive; usrprogram->Setlanguage(bott->Getlanguage()); usrprogram->Setsource(bott->Getsrc()); problem = new PConfig(bott->Getpid(), "interactive"); usrprogram->SetValidator_source( Loadallfromfile(problem->Getvalidator_filename())); usrprogram->SetValidator_language(problem->Getvalidator_language()); usrprogram->Setcase_time_limit(bott->Getcase_limit()); usrprogram->Settotal_time_limit(bott->Gettime_limit()); usrprogram->Setmemory_limit(bott->Getmemory_limit()); usrprogram->Setout_filename(CONFIG->GetTmpfile_path() + tmpnam()); usrprogram->Run(); retbott.Setce_info(usrprogram->Getce_info()); retbott.Settime_used(usrprogram->Gettime_used()); retbott.Setmemory_used(usrprogram->Getmemory_used()); retbott.Setresult(usrprogram->Getresult()); retbott.Setout_filename("results/" + Inttostring(retbott.Getrunid())); retbott.toFile(); delete usrprogram; delete problem; send_result(retbott.Getout_filename()); }
/** * Start virtual judger */ void VirtualJudger::run() { log("Judger started"); initHandShake(); while (true) { socket->receiveFile(tmpfilename); Bott * bott = new Bott(tmpfilename); log((string) "Received a new task, problem: " + bott->Getvid() + "."); string result_filename = Bott::RESULTS_DIRECTORY + intToString(bott->Getrunid()); if (bott->Gettype() == NEED_JUDGE) { // Currently for vjudge, only NEED_JUDGE is supported try { if (bott->Getsrc().length() < MIN_SOURCE_LENGTH) { // source code too short, may cause problem in remote OJ, such as PKU bott->Setout_filename(result_filename); generateSpecialResult(bott, "Compile Error"); bott->Setce_info("Source code too short, minimum length: " + intToString(MIN_SOURCE_LENGTH)); bott->save(); } else { judge(bott, result_filename); } } catch (Exception & e) { // Exception occurs, set to Judge Error log((string) "Judge error! Reason: " + e.what()); // reuse bott file bott->Setout_filename(result_filename); generateSpecialResult(bott, "Judge Error"); bott->save(); } catch (exception & e) { // Exception occurs, set to Judge Error log((string) "Judge error! Reason: " + e.what()); // reuse bott file bott->Setout_filename(result_filename); generateSpecialResult(bott, "Judge Error"); bott->save(); } delete bott; } else { delete bott; throw Exception("Type not supported."); } socket->sendFile(result_filename); } }
void dojudge(int type) { LOG("Runid: " + Inttostring(bott->Getrunid()) + " Type: " + Inttostring(type)); vector <string> in_files; if (!getalldata(bott->Getpid(), in_files, type) || in_files.size() == 0) { retbott.Settype(RESULT_REPORT); retbott.Setrunid(bott->Getrunid()); retbott.Settime_used(0); retbott.Setmemory_used(0); retbott.Setresult("Judge Error (No Data)"); retbott.Setout_filename("results/" + Inttostring(retbott.Getrunid())); retbott.toFile(); send_result(retbott.Getout_filename()); return; } string inpfile = CONFIG->GetTmpfile_path() + tmpnam(); string stdout_file = CONFIG->GetTmpfile_path() + tmpnam(); retbott.Settype(RESULT_REPORT); retbott.Setrunid(bott->Getrunid()); usrprogram = new Program; usrprogram->Setlanguage(bott->Getlanguage()); usrprogram->Setsource(bott->Getsrc()); usrprogram->Sethas_input(true); usrprogram->Setin_filename(inpfile); usrprogram->Setout_filename(CONFIG->GetTmpfile_path() + tmpnam()); usrprogram->Seterr_filename(CONFIG->GetTmpfile_path() + tmpnam()); if (type == NEED_JUDGE) usrprogram->Settotal_time_limit(bott->Gettime_limit()); else usrprogram->Settotal_time_limit(bott->Getcase_limit() * in_files.size()); usrprogram->Setcase_time_limit(bott->Getcase_limit()); usrprogram->Setmemory_limit(bott->Getmemory_limit()); bool aced, peed, jeed = false, has = false; aced = peed = true; cmp = new Comparator; cmp->Setin_filename(inpfile); cmp->Setout_filename(usrprogram->Getout_filename()); cmp->Setisspj(bott->Getspj()); cmp->Setpid(bott->Getpid()); for (unsigned int i = 0; i < in_files.size(); i++) { system(((string) "cp " + in_files[i] + ".in " + inpfile).c_str()); LOG((string) "Do " + in_files[i]); usrprogram->Run(); if (usrprogram->Getresult() != "Normal") { retbott.Setresult(usrprogram->Getresult()); has = true; break; } else { system(((string) "cp " + in_files[i] + ".out " + stdout_file).c_str()); system(((string) "chmod 755 " + stdout_file).c_str()); system(((string) "chmod 755 " + inpfile).c_str()); cmp->Setstdout_filename(stdout_file); cmp->Setsrc_filename(usrprogram->Getsrc_filename()); int cres = cmp->Compare(); system(((string) "rm " + stdout_file).c_str()); system(((string) "chmod 600 " + inpfile).c_str()); if (cres == PE_STATUS) aced = false; else if (cres == JE_STATUS) { jeed = false; break; } else if (cres != AC_STATUS) { aced = peed = false; break; } } } retbott.Setce_info(usrprogram->Getce_info()); retbott.Settime_used(usrprogram->Gettime_used()); retbott.Setmemory_used(usrprogram->Getmemory_used()); if (has) retbott.Setresult(usrprogram->Getresult()); else if (jeed) retbott.Setresult("Judge Error (No SPJ)"); else if (aced) { if (type == DO_PRETEST) retbott.Setresult("Pretest Passed"); else retbott.Setresult("Accepted"); } else if (peed) retbott.Setresult("Presentation Error"); else retbott.Setresult("Wrong Answer"); retbott.Setout_filename("results/" + Inttostring(retbott.Getrunid())); retbott.toFile(); delete cmp; delete usrprogram; send_result(retbott.Getout_filename()); }
void dochallenge() { string inpfile = CONFIG->GetTmpfile_path() + tmpnam(); retbott.Settype(CHALLENGE_REPORT); datagen = NULL; retbott.Setcha_id(bott->Getcha_id()); if (set_data(inpfile)) { //failtogen retbott.Setcha_result("Challenge Error"); retbott.Setcha_detail("Generator Failed: " + datagen->Getresult()); if (datagen != NULL) delete datagen; } else { string check_result_filename = CONFIG->GetTmpfile_path() + tmpnam(); int check_stat = check_data(bott->Getpid(), inpfile, check_result_filename); if (check_stat == 1) { retbott.Setcha_result("Challenge Error"); retbott.Setcha_detail("Data Check Failed: " + checker->Getresult() + "\nChecker Output Detail:\n--------------------------\n" + Loadallfromfile(check_result_filename) + "\n--------------------------\nInvalid Data!!"); } else if (check_stat == -1) { retbott.Setcha_result("Challenge Error"); retbott.Setcha_detail("No Config File For Problem: " + Inttostring(bott->Getpid())); } else { stdprogram = new Program; int stdres = run_program(stdprogram, inpfile, Loadallfromfile(problem->Getsolution_filename()), problem->Getsolution_language()); while (stdprogram->Getresult() == "Compile Error") { stdprogram->Setcompiled(false); stdprogram->Run(); if (stdprogram->Getresult() != "Normal") stdres = 1; else stdres = 0; } usrprogram = new Program; int usrres = run_program(usrprogram, inpfile, bott->Getsrc(), bott->Getlanguage()); while (usrprogram->Getresult() == "Compile Error") { usrprogram->Setcompiled(false); usrprogram->Run(); if (usrprogram->Getresult() != "Normal") usrres = 1; else usrres = 0; } if (stdres != 0) { retbott.Setcha_result("Challenge Error"); retbott.Setcha_detail( "Standard Program Failed: " + stdprogram->Getresult()); } else if (usrres != 0) { retbott.Setcha_result("Challenge Success"); string newf = "cha_" + tmpnam(); copyfile( stdprogram->Getin_filename(), "testdata/" + Inttostring(bott->Getpid()) + "/" + newf + ".in"); copyfile( stdprogram->Getout_filename(), "testdata/" + Inttostring(bott->Getpid()) + "/" + newf + ".out"); retbott.Setcha_detail("Standard: " + stdprogram->Getresult() + " User: "******"Challenge Failed"); retbott.Setcha_detail("Same Result."); } else if (cres == PE_STATUS) { retbott.Setcha_result("Challenge Success"); retbott.Setcha_detail( "Presentation Error.\nComparator Output Detail:" "\n--------------------------\n" + cmp->Getdetail() + "\n--------------------------"); string newf = "cha_" + tmpnam(); copyfile( stdprogram->Getin_filename(), "testdata/" + Inttostring(bott->Getpid()) + "/" + newf + ".in"); copyfile( stdprogram->Getout_filename(), "testdata/" + Inttostring(bott->Getpid()) + "/" + newf + ".out"); } else if (cres == JE_STATUS) { retbott.Setcha_result("Challenge Failed"); retbott.Setcha_detail("No SPJ."); } else { retbott.Setcha_result("Challenge Success"); string newf = "cha_" + tmpnam(); copyfile( stdprogram->Getin_filename(), "testdata/" + Inttostring(bott->Getpid()) + "/" + newf + ".in"); copyfile( stdprogram->Getout_filename(), "testdata/" + Inttostring(bott->Getpid()) + "/" + newf + ".out"); retbott.Setcha_detail( "Wrong Answer.\nComparator Output Detail:" "\n--------------------------\n" + cmp->Getdetail() + "\n--------------------------"); } delete cmp; } delete stdprogram; delete usrprogram; } delete problem; delete checker; if (datagen != NULL) delete datagen; } retbott.Setout_filename("cha_results/" + Inttostring(retbott.Getcha_id())); retbott.toFile(); send_result(retbott.Getout_filename()); }
/** * Send a submit to remote, and store the judge result * @param bott Submit info * @param filename File store the result */ void VirtualJudger::judge(Bott * bott, string filename) { // login if (!logged_in) { // Not logged in, try login clearCookies(); login(); log("Logged in."); logged_in = true; } // submit int submit_status = submit(bott); if (submit_status == SUBMIT_OTHER_ERROR) { // first time fail, blame login status... log((string) "Submit error. Assume not logged in."); logged_in = false; clearCookies(); login(); log("Logged in."); logged_in = true; submit_status = submit(bott); if (submit_status == SUBMIT_OTHER_ERROR) { // second time fail, blame frequency if (info->GetOj() == "CodeChef") { // CodeChef's restriction is harsh... 30 seconds cool down required log("Submit error. Assume should sleep for a while, " "sleeping 30 seconds."); sleep(30); } else { log("Submit error. Assume should sleep for a while, sleeping " + intToString(VirtualJudger::SLEEP_INTERVAL) + " seconds."); sleep(VirtualJudger::SLEEP_INTERVAL); } submit_status = submit(bott); } } else if (submit_status == SUBMIT_INVALID_LANGUAGE && (info->GetOj() == "SPOJ" || info->GetOj() == "CodeChef") && convertLanguage(bott->Getlanguage()) == "41") { // Special HACK for Invalid Language on SPOJ/CodeChef, since they have two // C++ types and each covers a certain subset of problems log((string) "Try another C++ for SPOJ/CodeChef"); bott->Setlanguage(1); submit_status = submit(bott); } if (submit_status != SUBMIT_OTHER_ERROR) log("Submitted."); // check submit status sleep(1); // sleep 1 second, just in case remote status table is not refreshed Bott * result; if (submit_status == SUBMIT_NORMAL) { // get status result = getStatus(bott); result->Setrunid(bott->Getrunid()); if (result->Getresult() == "Compile Error") { try { result->Setce_info(getCEinfo(result)); } catch (...) { log("Failed to get CE info, use empty one instead."); result->Setce_info(""); } } } else { result = new Bott; result->Setrunid(bott->Getrunid()); switch (submit_status) { case SUBMIT_SAME_CODE: generateSpecialResult(result, "Judge Error (Same Code)"); break; case SUBMIT_INVALID_LANGUAGE: generateSpecialResult(result, "Judge Error (Invalid Language)"); break; case SUBMIT_COMPILE_ERROR: generateSpecialResult(result, "Compile Error"); break; default: log("Submit Error."); generateSpecialResult(result, "Judge Error"); } } result->Setout_filename(filename); result->save(); log("Done judging. Result: " + result->Getresult() + ", remote runid: " + result->Getremote_runid()); delete result; }