從代碼上HUSTOJ分為兩大部分,core和web,分別對應判題和數據管理兩大功能。
兩者之間數據交換有兩種方式:1、通過數據庫,輪詢。2、通過w3m實現的http請求。
兩種方式的選擇在判題端的配置文件/home/judge/etc/judge.conf中,HTTP_JUDGE=1則啟用后者,默認為前者。
core分3部分,judged、judge_client、sim
其中judged為服務進程,d即daemon。負責輪詢數據庫或web端,提取判題隊列。
當發現新任務時產生judge_client進程。
judge_client進程為實際判題程序,負責准備運行環境、數據,運行並監控目標程序的系統調用,采集運行指標,判斷運行結果。
當配置為啟用抄襲檢查時,judge_client將調用sim,判斷相似性結果,並寫回數據庫或web端。
sim為第三方應用程序,可進行語法分析判斷文本相似度,通過檢驗的程序將由judge_client復制進題目數據的ac目錄,成為新的參考樣本。
w3m是linux下一個開源web文本瀏覽器,提供了基於命令行的http交互功能,這里用做http客戶端,用curl-lib應該也可以實現,本人熟悉w3m不熟悉curl,因此偷懶。
web分兩大部分,前端和admin目錄下的管理程序。
前端無非是數據庫的CRUD操作,關鍵功能是將用戶提交的程序源碼加入數據庫的任務隊列(solution表、souce_code表)。
管理程序提供具有administrator等高級權限的賬號管理試題、賬號等方面的功能。
其中FPS導入導出程序主要為XML格式的數據處理。
特別的,judged可以多重啟動,通過增加基准目錄參數指定啟動位置(默認/home/judge),從而確定judge.conf的位置,並確定其他參數。
因此不但可以一個web服務器下掛多個判題服務器,也可以一台物理機器上同時啟動任意多個相互獨立的OJ系統。
實際使用中,使用開源的ispcp虛擬主機管理系統搭建多Web環境與hustoj協同工作取得了良好效果。
LiveCD的實現,通過uck工具解壓出ubuntulivecd的chroot環境,並在其中刪除oo、gnome等大型程序釋放空間,然后用apt工具安裝基礎環境,安裝配置lxde和hustoj。再使用uck重新打包形成iso。
升級方式:利用googlecode的svn服務,用svn客戶端分別升級core和web,再編譯core,並通過web提供可能的數據庫升級。
livecd中的升級腳本為updagte-hustoj,可以用which命令查找其實際位置
------------------------------------------------------------
0、 准備知識
a) 最新系統源碼可以用svn取得,或在下述地址直接瀏覽
i. http://code.google.com/p/hustoj/source/browse/ 牆外老版
ii. https://github.com/zhblue/hustoj 無牆新版
b) 系統分為Web和Core兩個部分
c) 簡化ER圖
d) Web與core的連接方式有兩種,實際運行可選其中一種
i. 數據庫連接【默認】
1. Web插入Solution表
2. core輪詢solution表,發現新紀錄
3. core更新solution表result等字段
4. Web端輪詢soltuion顯示result等字段。
ii. HTTP方式
1. Web插入Solution表
2. core訪問Web端admin/problem_judge.php,發現新紀錄
3. core向Web端admin/problem_judge.php提交數據,problem_judge.php更新solution表result等字段
4. Web端輪詢soltuion顯示result等字段。
1、 Web部分
a) 閱讀配置文件,弄清各設置含義
i. 參考
static $DB_HOST="localhost"; 數據庫的服務器地址
static $DB_NAME="jol"; 數據庫名
static $DB_USER="root"; 數據庫用戶名
static $DB_PASS="root"; 數據庫密碼
// connect db
static $OJ_NAME="HUSTOJ"; OJ的名字,將取代頁面標題等位置HUSTOJ字樣。
static $OJ_HOME="./"; OJ的首頁地址
static $OJ_ADMIN="root@localhost"; 管理員email
static $OJ_DATA="/home/judge/data"; 測試數據所在目錄,實際位置。
static $OJ_BBS="discuss";//"bbs" 論壇的形式,discuss為自帶的簡單論壇,bbs為外掛論壇,參考bbs.php代碼。
static $OJ_ONLINE=false; 是否使用在線監控,需要消耗一定的內存和計算,因此如果並發大建議關閉
static $OJ_LANG="en"; 默認的語言,中文為cn
static $OJ_SIM=true; 是否顯示相似度檢測的結果。
static $OJ_DICT=true; 是否啟用在線英字典
static $OJ_LANGMASK=1008; //1mC 2mCPP 4mPascal 8mJava 16mRuby 32mBash 1008 for security reason to mask all other language 用掩碼表示的OJ接受的提交語言,可以被比賽設定覆蓋。
static $OJ_EDITE_AREA=true;// 是否啟用高亮語法顯示的提交界面,可以在線編程,無須IDE。
static $OJ_AUTO_SHARE=false;//true: 自動分享代碼,啟用的話,做出一道題就可以在該題的Status中看其他人的答案。
static $OJ_CSS="hoj.css"; 默認的css,可以選擇dark.css和gcode.css,具有有限的界面制定效果。
static $OJ_SAE=false; //是否是在新浪的雲平台運行web部分
static $OJ_VCODE=true; 是否啟用圖形登錄、注冊驗證碼。
static $OJ_APPENDCODE=false; 是否啟用自動添加代碼,啟用的話,提交時會參考$OJ_DATA對應目錄里是否有append.c一類的文件,有的話會把其中代碼附加到對應語言的答案之后,巧妙使用可以指定main函數而要求學生編寫main部分調用的函數。
static $OJ_MEMCACHE=false;是否使用memcache作為頁面緩存,如果不啟用則用/cache目錄
static $OJ_MEMSERVER="127.0.0.1"; memcached的服務器地址
static $OJ_MEMPORT=11211; memcached的端口
static $OJ_RANK_LOCK_PERCENT=0; //比賽封榜時間的比率,如5小時比賽設為0.2則最后1小時封榜。
static $OJ_SHOW_DIFF=false; //顯示WrongAnswer時的對比
b) 制定自己的前台模板(即改變頁面效果)
i. 復制template/bs3目錄,放置在template目錄中,並改為新模板名。
ii. 在db_info.inc.php中修改$OJ_TEMPLATE變量為新模板名
iii. 瀏覽前台,打開要修改的頁面,根據地址欄修改新目錄中對應的php、css、images等文件,保存后刷新頁面看修改效果。
c) 模板制定成功以后應該有足夠的知識開始修改template目錄以外的部分了
d) 論壇
i. 建議集成GPL的phpbb,參考。
ii. 集成Discuz
1. 建議購買商業許可。
2. 參考/web/include/login-discuz.php
e) 比賽根據數據通過率排名,而不只看AC數量
i. 數據庫solution表pass_rate字段表示改條通過率。
ii. 把contestrank.php中的solved字段變成浮點對待。
iii. 這里,修改積分方式,按照希望的方式積分。可能需要給TM增加字段$p_wa_best_rate記錄每題最大通過率。
f) 對有志於重寫整個前台的勇士
i. 希望你選擇一種魔法師編程語言(node.js/ror/python/go)。
ii. 如果做不到前面那條,請做好長時間開發的心理准備。
iii. 理論上任何現存web編程模型都可以,推薦JSP/SSH(前方高能坑……)。
iv. 建議實現admin/problem_judge.php的仿真,方便直接集成原版core。(get/post/ servlet-mapping)
2、 Core部分
a) 閱讀配置文件,弄清各設置含義
i. 參考
judge.conf 不要復制下面的注釋進入實際文件,judged和judge_client不能識別#注釋。
OJ_HOST_NAME=127.0.0.1 #mysql host ip
OJ_USER_NAME=root #mysql host username
OJ_PASSWORD=root #mysql host password
OJ_DB_NAME=jol #mysql DB name
OJ_PORT_NUMBER=3306 #mysql port
OJ_RUNNING=4 #max concurrent threads number of judge_client
OJ_SLEEP_TIME=5 #judged work interval
OJ_TOTAL=1 #Deprecated: total number of judged (hosts/processes)
OJ_MOD=0 #Deprecated: the number of this judged(host)
OJ_JAVA_TIME_BONUS=2 #java's extral time
OJ_JAVA_MEMORY_BONUS=512 #java's extral memory
OJ_SIM_ENABLE=0 #using sim
OJ_HTTP_JUDGE=0 #using http link to database(if enabled,mysql is not used anymore)
OJ_HTTP_BASEURL=http://127.0.0.1/JudgeOnline #http link basedir
OJ_HTTP_USERNAME=admin #account in db that has http_judge privilege
OJ_HTTP_PASSWORD=admin #password of this account
OJ_OI_MODE=0 #using oi (Olympiad in Informatics) mode
OJ_SHM_RUN=0 #using /dev/shm for fast running & low harddisk wear
OJ_USE_MAX_TIME=0 #use the max time of all testcase rather than total time
OJ_LANG_SET=0,1,2,3,4 #selective judge solution of languagesOJ_HOST_NAME=127.0.0.1 如果用mysql連接讀取數據庫,數據庫的主機地址
OJ_USER_NAME=root 數據庫帳號
OJ_PASSWORD=root 數據庫密碼
OJ_DB_NAME=jol 數據庫名稱
OJ_PORT_NUMBER=3306 數據庫端口
OJ_RUNNING=4 judged會啟動judge_client判題,這里規定最多同時運行幾個judge_client
OJ_SLEEP_TIME=5 judged通過輪詢數據庫發現新任務,輪詢間隔的休息時間,單位秒
OJ_TOTAL=1 老式並發處理中總的judged數量
OJ_MOD=0 老式並發處理中,本judged負責處理solution_id按照TOTAL取模后余數為幾的任務。
OJ_JAVA_TIME_BONUS=2 Java等虛擬機語言獲得的額外運行時間。
OJ_JAVA_MEMORY_BONUS=512 Java等虛擬機語言獲得的額外內存。
OJ_SIM_ENABLE=0 是否使用sim進行代碼相似度的檢測
OJ_HTTP_JUDGE=0 是否使用HTTP方式連接數據庫,如果啟用,則前面的HOST_NAME等設置忽略。
OJ_HTTP_BASEURL=http://127.0.0.1/JudgeOnline 使用HTTP方式連接數據庫的基礎地址,就是OJ的首頁地址。
OJ_HTTP_USERNAME=admin 使用HTTP方式所用的用戶帳號(HTTP_JUDGE權限),該帳號登錄時不能啟用VCODE圖形驗證碼,但可以登錄成功后啟用。
OJ_HTTP_PASSWORD=admin 密碼
OJ_OI_MODE=0 是否啟用OI模式,即無論是否出錯都繼續判剩余的數據,在ACM比賽中一旦出錯就停止運行。
OJ_SHM_RUN=0 是否使用/dev/shm的共享內存虛擬磁盤來運行答案,如果啟用能提高判題速度,但需要較多內存。
OJ_USE_MAX_TIME=1 是否使用所有測試數據中最大的運行時間作為最后運行時間,如果不啟用則以所有測試數據的總時間作為超時判斷依據。
OJ_LANG_SET=0,1,2,3,4 #判哪些語言的題目
OJ_COMPILE_CHROOT=0 是否在編譯時使用chroot環境,避免某些編譯期攻擊。
OJ_TURBO_MODE=0 是否放棄用戶表和問題表的數據一致性,以在大型比賽中添加更多的判題機來提高判題速度。
ii. 源碼https://github.com/zhblue/hustoj/blob/master/trunk/core/judge_client/
b) 查閱Linux文檔中關於下述關鍵詞的內容
i. Ptrace
ii. Chroot
iii. Setuid
iv. Proc
v. shm
c) 所有API限定在okcalls.h
d) 代碼查重工具sim
i. https://github.com/zhblue/hustoj/tree/master/trunk/core/sim
e) 對於計划改造Core來適應你自己的OJ前台的朋友
i. 參考1.c.iv
ii. 在judge_client.cc中搜索關鍵詞wget
f) HUSTOJ的沙箱模型
i. 相對openjudge.net的sandbox libraries而言並不嚴謹
ii. 對於OJ而言,基本滿足需求
iii. 容易理解、容易實現、容易修改
f) 莫名其妙的Runtime Error,請點擊RuntimeError打開詳細信息,並做英譯漢。
對於okcalls23/64.h進行修改,請只修改符合你的操作系統架構(32位/64位)的那個,0只能在首位,末尾必須為0。非0callid請加在中間任意位置。
CSDN網友的源碼注釋
http://blog.csdn.net/legan/article/details/40746829
http://blog.csdn.net/legan/article/details/40789939
result對應狀態
0: "等待"
1: "等待重判"
2: "編譯中"
3: "運行並評判"
4: "正確"
5: "格式錯誤"
6: "答案錯誤"
7: "時間超限"
8: "內存超限"
9: "輸出超限"
10: "運行錯誤"
11: "編譯錯誤"
12: "編譯成功"
13: "運行完成"
文檔
https://github.com/zhblue/hustoj/blob/master/wiki/hustoj%E6%96%87%E6%A1%A3%E5%A4%A7%E5%85%A8.pdf