欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

Virtual Judge 系统开发二:提交模块

程序员文章站 2022-06-13 18:59:25
...
这次我们谈谈提交模块。

在写这篇文章之前浏览网络的过程中,我有看到有人讨论过vj这种东西的合法性和道德性;不过在这篇文章里我不会谈这些,我们只关心技术。

我们是用php实现的提交,那么我们不得不使用一种东西:curl。不过php默认是不启用curl支持的,不管你用何种方式,总之让他工作起来就是了,不多说,直接贴代码:

public function POJ_DataPoster_Worker($user = "skvj01", $pass =

"forskvj", $id = "1000", $lang = "0", $code = "", $rid = "") {

if (DEBUG)

echo "[D] => $user, $pass, $id, $lang, $rid\n"; //MySQL $this->db = new dMySQL(); //Infomation $cookie_file =

tempnam("./cookie", "cookie"); $login_url = "http://poj.org/login";

$post_fields = "user_id1=".$user."&password1=".$pass."&url=/";

$this->rid = $rid; $this->pid = $id; $this->lang = $lang;

$this->user = $user; $this->pass = $pass;

//Login $curl = curl_init($login_url);

curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_COOKIEJAR,

$cookie_file); curl_setopt($curl, CURLOPT_POST, 1);

curl_setopt($curl, CURLOPT_POSTFIELDS, $post_fields);

$this->data = curl_exec($curl); curl_close($curl);

//Submit $hint_code = /"// ".$rid."\n"./$code; $post_fields =

'problem_id='.$id.'&language='

.$lang.'&encoded=1&source='.urlencode($hint_code);

//print_r(base64_encode($code)); $curl =

curl_init("http://poj.org/submit");

curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_COOKIEFILE,

$cookie_file); curl_setopt($curl, CURLOPT_POST, 1);

curl_setopt($curl, CURLOPT_POSTFIELDS, $post_fields);

$this->data = curl_exec($curl); curl_close($curl);

@unlink($cookie_file);

//Record Information $this->info = array(

'id' => $rid,

'user' => $user

);

}

这里还是用POJ为例子,POJ提交以后立刻会有记录产生,而HDOJ等则不然,这里就是利用curl模拟提交了一下。

$pdw = new POJ_DataPoster_Worker($oo_u, $oo_p, $list[$i]['tid'],

$list[$i]['lang'], $list[$i]['code'], $list[$i]['id']); $rrid =

$pdw->getRunID()

这里创建实例并且提交代码,然后获取RunID,就是远程的纪录ID。上面提到提交后就会产生纪录,这点比较好,迅速的直接抓取就好。当然,抓取不到那就是提交错误,就没有下文了。当然,抓取到,就是一个死循环了,不断的查询状态,然后更新本地纪录就可以了。

上面提到的抓取,有一个问题,就是如何判断哪个纪录是你当前提交的纪录,这个有方案如下:

1.一个账号是一个单独的队列,每次提交一个;

2.每次查询只查询本账号提交的纪录而非所有;

3.给代码加注释,内含一个绝对的ID,用于抓取所有源码并匹配。

这里3对于前两个来说理论上是多余的,只要抓第一个就好了。不过因为每次都是抓取一页,所以顺便就添加了这个机制,保险最重要。

文章发布时间为: May 4th , 2016 at 01:31 pm

最后编辑时间为: May 4th , 2016 at 01:55 pm

本文由SpringHack 创作,采用 知识共享署名 4.0国际许可协议进行许可

可*转载、引用,但需署名作者且注明文章出处