├── .gitignore ├── DEPLOY.md ├── LICENSE ├── README.md ├── README_cn.md ├── assets ├── commons.js ├── css │ ├── docs.css │ ├── docs_dark.css │ └── site.css ├── img │ ├── loginbg.png │ └── loginbg_dark.png ├── js │ ├── codemirror-basic.js │ └── nightMode.js ├── pages │ ├── general.js │ ├── problempage.js │ └── sourcecode.js └── snippets │ └── hljs.js ├── composer.json ├── composer.lock ├── doc ├── cwoj.sql ├── example.htaccess └── spj_example.c ├── package.json ├── web ├── config │ ├── config_example.php │ └── eula.php ├── public │ ├── about.php │ ├── admin.php │ ├── admin_auth.php │ ├── api │ │ ├── a.php │ │ ├── ajax_admin.php │ │ ├── ajax_contest.php │ │ ├── ajax_editcontest.php │ │ ├── ajax_editproblem.php │ │ ├── ajax_editwiki.php │ │ ├── ajax_getnews.php │ │ ├── ajax_login.php │ │ ├── ajax_logoff.php │ │ ├── ajax_mailfunc.php │ │ ├── ajax_mark.php │ │ ├── ajax_message.php │ │ ├── ajax_preferences.php │ │ ├── ajax_profile.php │ │ ├── ajax_resetpwd.php │ │ ├── ajax_sourcecode.php │ │ ├── ajax_submit.php │ │ ├── ajax_testcase.php │ │ ├── ajax_usage.php │ │ ├── ajax_user.php │ │ └── ajax_usernote.php │ ├── assets │ │ ├── Mathjax │ │ ├── css │ │ │ ├── docs.css │ │ │ ├── docs_dark.css │ │ │ ├── images │ │ │ │ ├── animated-overlay.gif │ │ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ │ │ ├── ui-bg_highlight-soft_75_ffe45c_1x100.png │ │ │ │ ├── ui-icons_222222_256x240.png │ │ │ │ ├── ui-icons_228ef1_256x240.png │ │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ │ ├── ui-icons_454545_256x240.png │ │ │ │ ├── ui-icons_888888_256x240.png │ │ │ │ ├── ui-icons_cd0a0a_256x240.png │ │ │ │ ├── ui-icons_ef8c08_256x240.png │ │ │ │ ├── ui-icons_ffd27a_256x240.png │ │ │ │ └── ui-icons_ffffff_256x240.png │ │ │ ├── jquery-ui.min.css │ │ │ ├── jquery.plupload.queue.css │ │ │ ├── jquery.ui.plupload.css │ │ │ └── simplemde.min.css │ │ ├── img │ │ │ ├── backgrounds.gif │ │ │ ├── buttons-disabled.png │ │ │ ├── buttons.png │ │ │ ├── delete.gif │ │ │ ├── done.gif │ │ │ ├── error.gif │ │ │ ├── glyphicons-halflings-white.png │ │ │ ├── glyphicons-halflings.png │ │ │ ├── loading.gif │ │ │ ├── logo.jpg │ │ │ ├── logomid.jpg │ │ │ ├── logosmall.jpg │ │ │ ├── ok-icon.png │ │ │ ├── plupload.png │ │ │ ├── rotate.gif │ │ │ ├── throbber.gif │ │ │ ├── transp50.png │ │ │ └── wrong-icon.png │ │ ├── js │ │ │ ├── bbcode.js │ │ │ ├── bootstrap.min.js │ │ │ ├── clipboard.min.js │ │ │ ├── common.js │ │ │ ├── html5.js │ │ │ ├── jquery-ui.min.js │ │ │ ├── jquery.min.js │ │ │ ├── jquery.placeholder.min.js │ │ │ ├── jquery.plupload.queue.min.js │ │ │ ├── jquery.ui.plupload.min.js │ │ │ ├── plupload.full.min.js │ │ │ ├── plupload.zh_CN.js │ │ │ ├── respond.js │ │ │ └── simplemde.min.js │ │ └── res │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── apple-touch-icon-120x120.png │ │ │ ├── apple-touch-icon-152x152.png │ │ │ ├── apple-touch-icon-180x180.png │ │ │ ├── apple-touch-icon-60x60.png │ │ │ ├── apple-touch-icon-76x76.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── browserconfig.xml │ │ │ ├── chrome.png │ │ │ ├── codgic.png │ │ │ ├── edge.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon.ico │ │ │ ├── firefox.png │ │ │ ├── ie.png │ │ │ ├── manifest.json │ │ │ ├── mstile-150x150.png │ │ │ ├── mstile-310x150.png │ │ │ ├── mstile-310x310.png │ │ │ ├── mstile-70x70.png │ │ │ ├── ojlogo-alt.png │ │ │ ├── ojlogo.png │ │ │ ├── opera.png │ │ │ └── safari-pinned-tab.svg │ ├── backupcode.php │ ├── board.php │ ├── conf │ │ └── ojsettings.php │ ├── contest.php │ ├── contestpage.php │ ├── editcontest.php │ ├── editproblem.php │ ├── editwiki.php │ ├── fuckie.php │ ├── func │ │ ├── checklogin.php │ │ ├── checkpwd.php │ │ ├── contest.php │ │ ├── cookie.php │ │ ├── preferences.php │ │ ├── privilege.php │ │ ├── sourcecode.php │ │ ├── text.php │ │ └── userlogin.php │ ├── inc │ │ ├── 403.php │ │ ├── 404.php │ │ ├── footer.php │ │ ├── head.php │ │ ├── init.php │ │ └── navbar.php │ ├── index.php │ ├── lib │ │ ├── class.phpmailer.php │ │ ├── class.smtp.php │ │ ├── lang.php │ │ ├── mail_flags.php │ │ ├── mathjax_head.php │ │ ├── mutex.php │ │ ├── problem_flags.php │ │ ├── result_type.php │ │ └── tgz.lib.php │ ├── locale │ │ └── zh_CN │ │ │ └── LC_MESSAGES │ │ │ ├── main.mo │ │ │ └── main.po │ ├── login.php │ ├── mail.php │ ├── marked.php │ ├── news.php │ ├── preferences.php │ ├── problempage.php │ ├── problemset.php │ ├── profile.php │ ├── proxy.php │ ├── ranklist.php │ ├── record.php │ ├── resetpwd.php │ ├── search.php │ ├── signup.php │ ├── sourcecode.php │ ├── testcase.php │ ├── upload.php │ ├── wait.php │ ├── wiki.php │ └── wikipage.php └── src │ ├── database.php │ ├── mail.php │ ├── mathjax.php │ ├── textparser.php │ └── userinfo.php ├── webpack.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | # 3 | logs 4 | *.log 5 | npm-debug.log* 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | *.pid.lock 12 | 13 | # swap 14 | [._]*.s[a-v][a-z] 15 | [._]*.sw[a-p] 16 | [._]s[a-v][a-z] 17 | [._]sw[a-p] 18 | # session 19 | Session.vim 20 | # temporary 21 | .netrwhist 22 | *~ 23 | # auto-generated tag files 24 | tags 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | 32 | # nyc test coverage 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 36 | .grunt 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (http://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules 46 | jspm_packages 47 | 48 | # Optional npm cache directory 49 | .npm 50 | 51 | # Optional eslint cache 52 | .eslintcache 53 | 54 | # Optional REPL history 55 | .node_repl_history 56 | 57 | # Output of 'npm pack' 58 | *.tgz 59 | 60 | # Yarn Integrity file 61 | .yarn-integrity 62 | 63 | # Generated asset file 64 | /web/public/assets_webpack/* 65 | 66 | # Config file 67 | /web/config/config.php 68 | 69 | /web/vendor/* 70 | -------------------------------------------------------------------------------- /DEPLOY.md: -------------------------------------------------------------------------------- 1 | # 部署 CWOJ 2 | 3 | ## 安装依赖项 4 | CWOJ 需要你安装以下项目来完成依赖项的构建: 5 | * node.js ( >= 6.0 ) 6 | * webpack ( >= 2.0 ) 7 | * composer ( >= 1.3 ) 8 | 9 | 其中,composer 用于安装 Mathjax。 10 | 11 | 如果你使用 Ubuntu,你可以使用如下操作来完成安装: 12 | ```bash 13 | curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - # 这会将 node.js 的软件库添加至你的系统 14 | 15 | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - 16 | echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list # 这会将 yarn 的软件仓库添加至系统。 17 | 18 | sudo apt update 19 | sudo apt install -y nodejs yarn 20 | sudo npm install webpack -g 21 | 22 | php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" 23 | php composer-setup.php 24 | php -r "unlink('composer-setup.php');" 25 | ``` 26 | 27 | ## 下载并安装程序包 28 | 你需要快速、稳定的 **国际** 互联网连接。 29 | 30 | ``` 31 | # 在项目根目录 32 | yarn # 下载依赖项 33 | webpack # 发布脚本到 web 目录 34 | 35 | # 假设你的 composer 可执行文件名为 `composer.phar` 36 | composer.phar install 37 | ``` 38 | 39 | ## 部署 40 | 复制 web 文件夹内的所有内容至 `/var/www/codgic`,然后将公共目录设为 `/var/www/codgic/public`。 41 | 将 web/config/config_example.php 复制到 web/config/config.php,然后编辑配置文件内容。 42 | 无需拷贝 web 文件夹以外的内容。 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Codgic Laverne (1.0) 2 | 3 | ![Codgic](https://raw.githubusercontent.com/Codgic/codgic-web-legacy/master/web/public/assets/res/codgic.png) 4 | 5 | **Notes: We are currently planning to rewrite Codgic so this repo is to be deprecated. We will continue to fix bugs but no new features will be added.** 6 | 7 | Codgic (previously CWOJ) is a free, open-source Online Judge Solution designed for OI trainings. Ever since 11/20/2015, we have kept seeking a better OJ solution for individuals, schools and other educational organizations. 8 | 9 | Laverne, the middle name of Judy Hopps from the movie "Zootopia", represents the spirit of trying everything and not fearing failures. That drives me through everything that seemed difficult or even impossible. 10 | ​ 11 | Notes: 1.x is still in early development stage, meaning it contains loads of half-done codes and is for evaluation purpose only. 12 | 13 | ## Branches 14 | - master: Current development branch (1.0-Laverne). 15 | - stable: Latest stable version (0.x). 16 | 17 | ## Deployment 18 | - The local daemon can be found [HERE](https://github.com/CDFLS/cwoj_daemon). 19 | - Please check out [DEPLOY.md](DEPLOY.md). 20 | 21 | ## Credits 22 | - Codgic is primarily based on [Bashu OnlineJudge](https://github.com/593141477/bashu-onlinejudge). 23 | - Codgic profits from other projects, most of them are licensed under the MIT license. 24 | 25 | ## Features 26 | Compared with the original Bashu OnlineJudge, we've made loads of improvements: 27 | - [x] PHP7 Ready 28 | - [x] Mullti-Languages Support + Improvements on UX. 29 | - [x] Optimized for mobile devices + Upgraded to Bootstrap 3. 30 | - [x] Day / Night Mode with auto switching. 31 | - [x] CodeMirror code editor & Prism syntax highlighter. 32 | - [x] Reset password. 33 | - [x] News Center. 34 | - [x] Gravatar. 35 | - [x] User online/offline status. 36 | - [x] Rewritten user privilege system. 37 | - [x] Contest (Beta). 38 | - [ ] Wiki (Unfinished). 39 | -------------------------------------------------------------------------------- /README_cn.md: -------------------------------------------------------------------------------- 1 | # Codgic Laverne (1.0) 2 | 3 | ![Codgic](https://raw.githubusercontent.com/Codgic/codgic-web-legacy/master/web/public/assets/res/codgic.png) 4 | 5 | **注:我们正在计划重写Codgic,故当前的Codgic将在未来被放弃。我们会继续对Codgic中的bug进行修复,但不会再增加新功能。** 6 | 7 | Codgic(原名CWOJ)是一个免费、开源并且专为信息竞赛训练设计的在线评测系统解决方案。 自2015年11月20日以来,我们一直致力于寻求一个适合于个人、学校及其它教育机构的在线评测系统解决方案。 8 | 9 | Laverne,电影《疯狂动物城》中主人公Judy Hopps的中间名,代表着一种尝试一切不畏失败的精神。 它给予了我在困难甚至不可能中取得突破的动力。 10 | 11 | 注: 1.x仍然处于早期开发阶段,意味着它包含大量只写了不到一半的代码并且只适用于测试用途。 12 | ​ 13 | ## 分支 14 | - master: 当前开发分支 (1.0-Laverne)。 15 | - stable-0.x: 稳定版本分支 (0.x)。 16 | 17 | ## 部署 18 | - 评测端在[这里](https://github.com/CDFLS/cwoj_daemon)。 19 | - 请参见 DEPLOY.md。 20 | 21 | ## 许可 22 | - Codgic主要基于[Bashu OnlineJudge](https://github.com/593141477/bashu-onlinejudge). 23 | - Codgic也引用了一下其它的开源项目, 其中大部分都基于MIT协议。 24 | 25 | ## 特性 26 | 相比原始的 Bashu Online Judge, 我们做了如下提升: 27 | - [x] 完全兼容PHP7 28 | - [x] 多语言支持 (Alpha) + UX细节升级 29 | - [x] 针对移动设备优化 + 升级到Bootstrap 3。 30 | - [x] 日间/夜间模式 + 自动切换 31 | - [x] CodeMirror代码编辑器 + Prism代码语法高亮。 32 | - [x] 密码找回 33 | - [x] 新闻中心 34 | - [x] Gravatar头像 35 | - [x] 用户在线/离线状态 36 | - [x] 重写的用户权限管理 37 | - [x] 比赛 (Beta) 38 | - [ ] 百科 (未完成) 39 | -------------------------------------------------------------------------------- /assets/commons.js: -------------------------------------------------------------------------------- 1 | // Cannot lazy load jQuery because of legacy script. 2 | window.$ = window.jQuery = require('jquery'); 3 | 4 | require.ensure(["bootstrap"], function() { 5 | require('bootstrap'); 6 | }); 7 | 8 | require.ensure(["font-awesome/css/font-awesome.css"], function() { 9 | require('font-awesome/css/font-awesome.css'); 10 | }); 11 | // require('bootstrap/less/bootstrap.less'); 12 | 13 | require('./css/site.css'); 14 | import loadNightMode from './js/nightMode'; 15 | loadNightMode(); 16 | -------------------------------------------------------------------------------- /assets/css/site.css: -------------------------------------------------------------------------------- 1 | .preserve-whitespace { 2 | white-space: pre-wrap; 3 | } 4 | -------------------------------------------------------------------------------- /assets/img/loginbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/assets/img/loginbg.png -------------------------------------------------------------------------------- /assets/img/loginbg_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/assets/img/loginbg_dark.png -------------------------------------------------------------------------------- /assets/js/nightMode.js: -------------------------------------------------------------------------------- 1 | export default function() { 2 | const resPath = '../'; 3 | let hour = new Date().getHours(), 4 | config = window.nightModeConfig, 5 | nightMode; 6 | 7 | if (config.mode == 'on') 8 | nightMode = true; 9 | else if (config.mode == 'off') 10 | nightMode = false; 11 | else if (hour < config.dayStart || hour > config.nightStart) 12 | nightMode = true; 13 | else 14 | nightMode = false; 15 | 16 | window.nightMode = nightMode; 17 | 18 | if (nightMode) 19 | { 20 | require('bootswatch/slate/bootstrap.css'); 21 | require('../css/docs_dark.css'); 22 | require('codemirror/theme/midnight.css'); 23 | } 24 | else 25 | { 26 | require('bootswatch/cerulean/bootstrap.css'); 27 | require('../css/docs.css'); 28 | require('codemirror/theme/eclipse.css'); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /assets/pages/general.js: -------------------------------------------------------------------------------- 1 | require("../commons.js"); 2 | -------------------------------------------------------------------------------- /assets/pages/problempage.js: -------------------------------------------------------------------------------- 1 | let codeTheme = nightMode ? 'midnight' : 'eclipse', 2 | cmConfig = window.editorConfig; 3 | $('.btn-submit').click(function() { 4 | if (!window.user) 5 | { 6 | $('#alert_error').html(' Please login first...').fadeIn(); 7 | setTimeout(function() { $('#alert_error').fadeOut(); }, 2000); 8 | return; 9 | } 10 | let emptyFunction = () => { }; 11 | let focusEditor, clearEditor, changeMode; 12 | if (!window.editorLoaded) 13 | { 14 | if (cmConfig.enabled) 15 | { 16 | require.ensure([], function () { 17 | require('codemirror/lib/codemirror.css'); 18 | require('codemirror/theme/' + codeTheme + '.css'); 19 | require('codemirror/addon/display/fullscreen.css'); 20 | require('codemirror/addon/display/placeholder'); 21 | require('codemirror/addon/display/fullscreen'); 22 | require('codemirror/mode/clike/clike'); 23 | require('codemirror/mode/pascal/pascal'); 24 | require('../js/codemirror-basic'); 25 | if (cmConfig.mode != 'default') 26 | require('codemirror/keymap/' + cmConfig.mode); 27 | 28 | let editorParameter = { 29 | theme: codeTheme, 30 | lineNumbers: true, 31 | extraKeys: { 32 | "F11": function (cm) { 33 | if(cm.getOption("fullScreen")) { 34 | toggle_fullscreen(1); 35 | cm.setOption("fullScreen",false); 36 | } else { 37 | toggle_fullscreen(0); 38 | cm.setOption("fullScreen", !cm.getOption("fullScreen")); 39 | } 40 | }, 41 | }, 42 | }; 43 | if (cmConfig.mode != 'default') 44 | { 45 | editorParameter.keyMap = cmConfig.mode; 46 | editorParameter.showCursorWhenSelecting = true; 47 | } 48 | 49 | let codeMirror = require('codemirror'); 50 | let editor = window.editor = codeMirror.fromTextArea(document.getElementById('detail_input'), editorParameter); 51 | 52 | clearEditor = function() { 53 | editor.getDoc().setValue(''); 54 | }; 55 | changeMode = function () { 56 | var m = $('#slt_lang').val(); 57 | if(m == 1) 58 | editor.setOption("mode", "text/x-csrc"); 59 | else if(m == 2) 60 | editor.setOption("mode", "text/x-pascal"); 61 | else if (m == 6) 62 | editor.setOption("mode", "text/x-basic"); 63 | else 64 | editor.setOption("mode", "text/x-c++src"); 65 | }; 66 | $('#slt_lang').change(() => changeMode()); 67 | focusEditor = () => { editor.refresh(); editor.focus(); }; 68 | setTimeout(() => { focusEditor(); changeMode(); }, 100); 69 | }); 70 | } 71 | else 72 | { 73 | let input = $('#detail_input'); 74 | focusEditor = function() { input.focus(); }; 75 | clearEditor = function () { 76 | input.val(''); 77 | }; 78 | changeMode = function () { }; 79 | } 80 | 81 | $('#btn_clear').click(function() { 82 | clearEditor(); 83 | focusEditor(); 84 | }); 85 | window.editorLoaded = true; 86 | } 87 | 88 | let modal = $('#SubmitModal'); 89 | modal.modal('show'); 90 | }); 91 | -------------------------------------------------------------------------------- /assets/pages/sourcecode.js: -------------------------------------------------------------------------------- 1 | let codeTheme = nightMode ? 'midnight' : 'eclipse', 2 | cmConfig = window.editorConfig; 3 | $(document).ready(function() { 4 | let emptyFunction = () => { }; 5 | let focusEditor, clearEditor, changeMode; 6 | if (cmConfig.enabled) 7 | { 8 | require.ensure([], function () { 9 | require('codemirror/addon/display/fullscreen'); 10 | require('codemirror/lib/codemirror.css'); 11 | require('codemirror/addon/display/fullscreen.css'); 12 | require('codemirror/theme/' + codeTheme + '.css'); 13 | require('codemirror/mode/clike/clike'); 14 | require('codemirror/mode/pascal/pascal'); 15 | require('../js/codemirror-basic'); 16 | 17 | let editorParameter = { 18 | theme: codeTheme, 19 | lineNumbers: true, 20 | readOnly: 'nocursor', 21 | viewportMargin: Infinity, 22 | mode: textMode 23 | }; 24 | 25 | let codeMirror = require('codemirror'); 26 | let editor = window.editor = codeMirror.fromTextArea(document.getElementById('text_code'), editorParameter); 27 | 28 | let toggleFullScreen = function() { 29 | editor.setOption("fullScreen", !editor.getOption("fullScreen")); 30 | }; 31 | $("#btn_fullscreen").click(toggleFullScreen); 32 | editor.setOption("extraKeys", { "F11": toggleFullScreen }); 33 | }); 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /assets/snippets/hljs.js: -------------------------------------------------------------------------------- 1 | if (nightMode) 2 | require('highlightjs/styles/androidstudio.css'); 3 | else 4 | require('highlightjs/styles/xcode.css'); 5 | 6 | let hljs = require('highlightjs'); 7 | hljs.initHighlightingOnLoad(); 8 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codgic/web", 3 | "description": "Web part for Codgic.", 4 | "type": "project", 5 | "license": "GPLv3", 6 | "authors": [ 7 | { 8 | "name": "Tian Yunhao", 9 | "email": "t123yh@outlook.com" 10 | } 11 | ], 12 | "require": { 13 | "mathjax/mathjax": "^2.7", 14 | "ezyang/htmlpurifier": "^4.8", 15 | "erusev/parsedown": "^1.6", 16 | "erusev/parsedown-extra": "^0.7.1", 17 | "phpmailer/phpmailer": "^5.2" 18 | }, 19 | "config": { 20 | "vendor-dir": "web/vendor" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /doc/example.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | 3 | RewriteCond %{SERVER_PORT} 80 4 | RewriteRule ^(.*)$ https://www.cwoj.tk/$1 [R=301,L] 5 | 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteRule ^([^\.]+)$ $1.php [NC,L] 8 | 9 | ErrorDocument 404 /404.php 10 | ErrorDocument 403 /403.php 11 | -------------------------------------------------------------------------------- /doc/spj_example.c: -------------------------------------------------------------------------------- 1 | //Linux平台下保存为spj.cpp放到题目的数据目录下 2 | //Windows平台编译为spj.exe放到题目的数据目录下 3 | #include 4 | 5 | FILE *fscore,*freport,*fstd,*fin,*fout; 6 | int score; 7 | int main(int argc,char *argv[]) 8 | { 9 | fscore=fopen("score.log","w");//打开得分文件,写入一个数字表示测试点得分 10 | freport=fopen("report.log","w");//打开报告文件,用于反馈信息给选手 11 | fstd=fopen(argv[2],"r");//打开测试点标准输出文件 12 | score=atoi(argv[1]);//取得测试点的满分 13 | 14 | fin=fopen("user.in","r");//测试数据的输入 15 | fout=fopen("user.out","r");//选手的输出 16 | 17 | //评测 18 | 19 | if (/*完全正确*/) 20 | { 21 | fprintf(fscore,"%d",score);//返回满分 22 | fprintf(freport,"right");//报告用户结果,内容任意 23 | } 24 | else if (/*部分正确*/) 25 | { 26 | fprintf(fscore,"%d",/*部分分*/); 27 | fprintf(freport,/*输出错误信息*/); 28 | } 29 | else 30 | { 31 | fprintf(fscore,"%d",0);//返回0分 32 | fprintf(freport,"wrong");//报告用户结果,内容任意 33 | } 34 | 35 | fclose(fscore);//关闭得分文件 36 | fclose(freport);//关闭报告文件 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cwoj", 3 | "version": "1.0.0", 4 | "description": "Web part for CWOJ.", 5 | "directories": { 6 | "doc": "doc" 7 | }, 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/CDFLS/CWOJ.git" 14 | }, 15 | "author": "", 16 | "license": "GPL-3.0", 17 | "bugs": { 18 | "url": "https://github.com/CDFLS/CWOJ/issues" 19 | }, 20 | "homepage": "https://github.com/CDFLS/CWOJ#readme", 21 | "dependencies": { 22 | "bootstrap": "^3.4.1", 23 | "bootswatch": "^3.3.7", 24 | "codemirror": "^5.22.0", 25 | "font-awesome": "^4.7.0", 26 | "highlightjs": "^9.8.0", 27 | "jquery": "^3.4.0", 28 | "mathjax": "^2.7.4" 29 | }, 30 | "devDependencies": { 31 | "babel-core": "^6.21.0", 32 | "babel-loader": "^6.2.10", 33 | "babel-preset-es2015": "^6.18.0", 34 | "css-loader": "^0.26.1", 35 | "file-loader": "^0.9.0", 36 | "less": "^2.7.2", 37 | "less-loader": "^2.2.3", 38 | "path": "^0.12.7", 39 | "style-loader": "^0.13.1", 40 | "url-loader": "^0.5.7", 41 | "webpack": "^2.1.0-beta.28" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /web/config/config_example.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 不得利用本站进行下列行为:
4 | (1) 煽动抗拒、破坏宪法和法律、行政法规实施;
5 | (2) 公然侮辱他人或者捏造事实诽谤他人的,或者进行其他恶意攻击;
6 | (3) 恶意尝试攻击、损伤任意服务器的(但是欢迎并鼓励以报告漏洞为目的善意行为);
7 | (4) 捏造或者歪曲事实,散布谣言,扰乱社会秩序;
8 | (5) 宣扬封建迷信、淫秽、色情、赌博、暴力、凶杀、恐怖、教唆犯罪;
9 | (6) 其他违反宪法和法律行政法规的行为;
10 |
11 | 本站中任何言论纯属发表者个人意见,与本站立场无关。如果您违反了上述事项的任何一项,您将承担一切因您的行为而直接或间接导致的民事或刑事法律责任。本站可向有关部门举报,同时禁止您登陆或封IP地址。
12 |
13 | CODGIC_EULA_201701
-------------------------------------------------------------------------------- /web/public/admin_auth.php: -------------------------------------------------------------------------------- 1 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 | 42 | 43 | 44 |
45 |
46 |
47 |
48 |
49 | 50 |
51 | 52 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /web/public/api/a.php: -------------------------------------------------------------------------------- 1 | 29990){ 78 | echo _('Code too long...'); 79 | exit(); 80 | } 81 | 82 | require __DIR__.'/../lib/problem_flags.php'; 83 | require __DIR__.'/../func/privilege.php'; 84 | 85 | $forbidden=false; 86 | if($row[4]=='Y' && !check_priv(PRIV_PROBLEM)) 87 | $forbidden=true; 88 | else if($row[5]&PROB_IS_HIDE && !check_priv(PRIV_INSIDER)) 89 | $forbidden=true; 90 | if($forbidden){ 91 | echo _('Permission Denied...'); 92 | exit(); 93 | } 94 | 95 | $_SESSION['lang']=$lang; 96 | mysqli_query($con,"update users set language=$lang where user_id='".$_SESSION['user']."'"); 97 | mysqli_query($con,"update problem set in_date=NOW() where problem_id=$prob"); 98 | 99 | $key=md5('key'.time().rand()); 100 | $share_code=(isset($_POST['public']) ? 1 : 0); 101 | 102 | $data=array( 103 | 'a'=>$prob, 104 | 'b'=>$lang, 105 | 'c'=>$row[0], 106 | 'd'=>$row[1], 107 | 'e'=>$row[2], 108 | 'f'=>$code, 109 | 'g'=>$_SESSION['user'], 110 | 'h'=>$key, 111 | 'i'=>$share_code, 112 | 'j'=>$row[3] 113 | ); 114 | ignore_user_abort(TRUE); 115 | $result = posttodaemon($data); 116 | if(strstr($result,'OK')) 117 | echo 'success_'.$key; 118 | else 119 | die($result); 120 | }else if($_POST['op']=='rejudge'){ 121 | $data=array( 122 | 'a'=>$prob, 123 | 'c'=>$row[0], 124 | 'd'=>$row[1], 125 | 'e'=>$row[2], 126 | 'h'=>"rejudge".$prob, 127 | 'j'=>$row[3], 128 | 'k'=>1 //TYPE_rejudge 129 | ); 130 | ignore_user_abort(TRUE); 131 | $result = posttodaemon($data); 132 | 133 | if(strstr($result,"OK")) 134 | echo 'success'; 135 | else if(strstr($result,"another")) 136 | echo _('Another rejudge thread is running, try again later...'); 137 | else 138 | echo $result; 139 | } 140 | -------------------------------------------------------------------------------- /web/public/api/ajax_editproblem.php: -------------------------------------------------------------------------------- 1 | false, 'message' => _('Permission Denied...'))); 20 | exit(); 21 | } 22 | else if(!isset($_POST['op'])){ 23 | echo json_encode(array('success' => false, 'message' => _('Invalid Argument...'))); 24 | exit(); 25 | } 26 | 27 | require __DIR__.'/../../src/database.php'; 28 | 29 | if($_POST['op']=='del'){ 30 | if(!isset($_POST['problem_id'])){ 31 | echo json_encode(array('success' => false, 'message' => _('No such problem...'))); 32 | exit(); 33 | } 34 | $id=intval($_POST['problem_id']); 35 | if(mysqli_query($con,"update problem set defunct=(!defunct) where problem_id=$id")) 36 | echo json_encode(array('success' => true)); 37 | else 38 | echo json_encode(array('success' => false, 'message' => _('Database operation failed...'))); 39 | }else{ 40 | if(isset($_POST['time'])&&!empty($_POST['time'])){ 41 | $time=intval($_POST['time']); 42 | }else{ 43 | echo json_encode(array('success' => false, 'message' => _('Please enter time limit...'))); 44 | exit(); 45 | } 46 | if($time<0){ 47 | echo json_encode(array('success' => false, 'message' => _('Invalid time limit...'))); 48 | exit(); 49 | } 50 | if(isset($_POST['memory'])&&!empty($_POST['memory'])){ 51 | $memory=intval($_POST['memory']); 52 | }else{ 53 | echo json_encode(array('success' => false, 'message' => _('Please enter memory limit...'))); 54 | exit(); 55 | } 56 | if($memory<0){ 57 | echo json_encode(array('success' => false, 'message' => _('Invalid memory limit...'))); 58 | exit(); 59 | } 60 | if(isset($_POST['score'])&&!empty($_POST['score'])){ 61 | $score=intval($_POST['score']); 62 | }else{ 63 | echo json_encode(array('success' => false, 'message' => _('Please enter case score...'))); 64 | exit(); 65 | } 66 | if($score<0){ 67 | echo json_encode(array('success' => false, 'message' => _('Invalid case score...'))); 68 | exit(); 69 | } 70 | $compare_way=isset($_POST['compare']) ? CMP_TYPE($_POST['compare'], intval($_POST['precision'])) : 0; 71 | if(isset($_POST['title'])&&!empty($_POST['title'])){ 72 | $title=mysqli_real_escape_string($con,$_POST['title']); 73 | }else{ 74 | echo json_encode(array('success' => false, 'message' => _('Please enter title...'))); 75 | exit(); 76 | } 77 | $des=isset($_POST['description']) ? mysqli_real_escape_string($con,$_POST['description']) : ''; 78 | $input=isset($_POST['input']) ? mysqli_real_escape_string($con,$_POST['input']) : ''; 79 | $output=isset($_POST['output']) ? mysqli_real_escape_string($con,$_POST['output']) : ''; 80 | $samp_in=isset($_POST['sample_input']) ? mysqli_real_escape_string($con,$_POST['sample_input']) : ''; 81 | $samp_out=isset($_POST['sample_output']) ? mysqli_real_escape_string($con,$_POST['sample_output']) : ''; 82 | $hint=isset($_POST['hint']) ? mysqli_real_escape_string($con,$_POST['hint']) : ''; 83 | $source=isset($_POST['source']) ? mysqli_real_escape_string($con,$_POST['source']) : ''; 84 | 85 | require __DIR__.'/../lib/problem_flags.php'; 86 | $has_tex=0; 87 | if(isset($_POST['option_osc'])){ 88 | switch(intval($_POST['option_osc'])){ 89 | case 0: 90 | break; 91 | case 1: 92 | $has_tex|=PROB_SOLVED_OPENSOURCE; 93 | break; 94 | case 2: 95 | $has_tex|=PROB_DISABLE_OPENSOURCE; 96 | break; 97 | } 98 | } 99 | if(isset($_POST['option_level'])){ 100 | $l=intval($_POST['option_level']); 101 | $level_max=(PROB_LEVEL_MASK>>PROB_LEVEL_SHIFT); 102 | if($l>=0 && $l<=$level_max){ 103 | $has_tex|=($l< false, 'message' => _('Invalid Argument...'))); 119 | exit(); 120 | } 121 | $id=intval($_POST['problem_id']); 122 | if ($id == -1){ 123 | $prob_id = 1000; 124 | $result = mysqli_query($con, 'select max(problem_id) from problem'); 125 | if (($row = mysqli_fetch_row($result)) && intval($row[0])) 126 | $prob_id = intval($row[0]) + 1; 127 | $id = $prob_id; 128 | } 129 | $result=mysqli_query($con,"update problem set title='$title',case_time_limit=$time,memory_limit=$memory,case_score=$score,description='$des',input='$input',output='$output',sample_input='$samp_in',sample_output='$samp_out',hint='$hint',source='$source',has_tex=$has_tex,compare_way=$compare_way where problem_id=$id"); 130 | }else if($_POST['op']=='add'){ 131 | $id=1000; 132 | $result=mysqli_query($con,'select max(problem_id) from problem'); 133 | if(($row=mysqli_fetch_row($result)) && intval($row[0])) 134 | $id=intval($row[0])+1; 135 | $result=mysqli_query($con,"insert into problem (problem_id,title,description,input,output,sample_input,sample_output,hint,source,in_date,memory_limit,case_time_limit,case_score,has_tex,compare_way) values ($id,'$title','$des','$input','$output','$samp_in','$samp_out','$hint','$source',NOW(),$memory,$time,$score,$has_tex,$compare_way)"); 136 | }else{ 137 | echo json_encode(array('success' => false, 'message' => _('Invalid Argument...'))); 138 | exit(); 139 | } 140 | 141 | if($result) 142 | echo json_encode(array('success' => true, 'problemID' => $id)); 143 | else 144 | echo json_encode(array('success' => false, 'message' => _('Unknown Error...'))); 145 | } -------------------------------------------------------------------------------- /web/public/api/ajax_editwiki.php: -------------------------------------------------------------------------------- 1 | false, 'message' => _('Permission Denied...'))); 8 | exit(); 9 | }else if(!isset($_POST['op'])){ 10 | echo json_encode(array('success' => false, 'message' => _('Invalid Argument...'))); 11 | exit(); 12 | } 13 | 14 | require __DIR__.'/../../src/database.php'; 15 | 16 | if($_POST['op']=='del'){ 17 | if(!check_priv(PRIV_PROBLEM)){ 18 | echo json_encode(array('success' => false, 'message' => _('Permission Denied...'))); 19 | exit(); 20 | } 21 | if(!isset($_POST['wiki_id'])){ 22 | echo json_encode(array('success' => false, 'message' => _('No such wiki...'))); 23 | exit(); 24 | } 25 | $id=intval($_POST['wiki_id']); 26 | if(mysqli_query($con,"update wiki set defunct=(!defunct) where wiki_id=$id")) 27 | echo json_encode(array('success' => true)); 28 | else 29 | echo json_encode(array('success' => false, 'message' => _('Database operation failed...'))); 30 | }else{ 31 | if(isset($_POST['title'])&&!empty($_POST['title'])){ 32 | $title=mysqli_real_escape_string($con,$_POST['title']); 33 | }else{ 34 | echo json_encode(array('success' => false, 'message' => _('Please enter Title...'))); 35 | exit(); 36 | } 37 | $content=isset($_POST['content']) ? mysqli_real_escape_string($con,$_POST['content']) : ''; 38 | $tags=isset($_POST['tags']) ? mysqli_real_escape_string($con,$_POST['tags']) : ''; 39 | $author=$_SESSION['user']; 40 | 41 | $priv=0; 42 | if(isset($_POST['hide_cont'])){ 43 | $priv=1; //This is temporary! Unfinished! 44 | } 45 | 46 | if($_POST['op']=='edit'){ 47 | if(!isset($_POST['wiki_id'])){ 48 | echo json_encode(array('success' => false, 'message' => _('Invalid Argument...'))); 49 | exit(); 50 | } 51 | $id=intval($_POST['wiki_id']); 52 | //Get current newest revision. 53 | $row=mysqli_fetch_row(mysqli_query($con,"select revision from wiki where wiki_id=$id and is_max=1")); 54 | //revision++. 55 | if(isset($row[0])){ 56 | $revision=$row[0]+1; 57 | //Mark the current revision as not the newest. 58 | $result=mysqli_query($con,"update wiki set is_max=0 where wiki_id=$id and is_max=1"); 59 | if($result) 60 | //Create a new revision and mark it as the newest. 61 | $result=mysqli_query($con,"insert into wiki (wiki_id,title,content,tags,author,revision,is_max,in_date,privilege,defunct) values ($id,'$title','$content','$tags','$author','$revision',1,NOW(),$priv,0)"); 62 | }else 63 | //If getting current newest revision failed. 64 | $result=false; 65 | }else if($_POST['op']=='add'){ 66 | $id=1; 67 | $result=mysqli_query($con,'select max(wiki_id) from wiki'); 68 | if(($row=mysqli_fetch_row($result)) && intval($row[0])) 69 | $id=intval($row[0])+1; 70 | //Create a new revision and mark it as the newest. 71 | $result=mysqli_query($con,"insert into wiki (wiki_id,title,content,tags,author,revision,is_max,in_date,privilege,defunct) values ($id,'$title','$content','$tags','$author',0,1,NOW(),$priv,0)"); 72 | }else{ 73 | echo json_encode(array('success' => false, 'message' => _('Invalid Argument...'))); 74 | exit(); 75 | } 76 | 77 | if($result) 78 | echo json_encode(array('success' => true, 'wikiID' => $id)); 79 | else 80 | echo json_encode(array('success' => false, 'message' => _('Unknown Error...'))); 81 | } -------------------------------------------------------------------------------- /web/public/api/ajax_getnews.php: -------------------------------------------------------------------------------- 1 | false,'title'=>'','content'=>'','time'=>'','priv'=>''); 10 | 11 | if(!isset($_POST['newsid'])){ 12 | $arr['content']=_('Invalid Argument...'); 13 | die(json_encode($arr)); 14 | } 15 | 16 | $newsid = intval($_POST['newsid']); 17 | 18 | $res=mysqli_query($con,"select title,content,time,privilege from news where news_id=$newsid"); 19 | $row=mysqli_fetch_row($res); 20 | 21 | if(($require_auth==1 || $row[3]!=0) && !isset($_SESSION['user'])){ 22 | $arr['content']=_('Permission Denied...'); 23 | die(json_encode($arr)); 24 | } 25 | 26 | if($row[3]!=0){ 27 | if(!($_SESSION['priv'] & $row[3])){ 28 | $arr['content']=_('Permission Denied...'); 29 | die(json_encode($arr)); 30 | } 31 | } 32 | 33 | if(empty($row[1])) 34 | $row[1]=_('This piece of news is empty...'); 35 | 36 | $arr=array('success' => true, 'title' => $row[0], 'content' => parse_markdown($row[1]), 'time' => $row[2],'priv' => list_priv($row[3])); 37 | echo json_encode($arr); 38 | -------------------------------------------------------------------------------- /web/public/api/ajax_login.php: -------------------------------------------------------------------------------- 1 | 500){ 65 | echo _('Post too long...'); 66 | exit(); 67 | } 68 | $content=mysqli_real_escape_string($con,$_POST['detail']); 69 | $mutex=new php_mutex("$temp_dir"); 70 | $new_msg_id=getNextMsgID(); 71 | if(isset($_POST['message_id']) 72 | && ($tmp=intval($_POST['message_id'])) 73 | && ($row=mysqli_fetch_row(mysqli_query($con,'select orderNum,depth,thread_id,problem_id from message where message_id='.$tmp)))){ //Reply message 74 | $msg_id=$tmp; 75 | $order_num=$row[0]; 76 | $depth=$row[1]; 77 | $thread_id=$row[2]; 78 | $prob_id=$row[3]; 79 | $res=mysqli_query($con,"select depth,orderNum from message where thread_id=$thread_id and orderNum>$order_num order by orderNum"); 80 | while($row=mysqli_fetch_row($res)){ 81 | if($row[0]<=$depth) 82 | break; 83 | $order_num=$row[1]; 84 | } 85 | mysqli_query($con,"update message set orderNum=orderNum+1 where thread_id=$thread_id and orderNum>$order_num"); 86 | mysqli_query($con,"update message set thread_id=$new_msg_id where thread_id=$thread_id"); 87 | $depth++; 88 | $order_num++; 89 | }else{ //New message, check problem_id 90 | if(isset($_POST['problem_id'])){ 91 | $tmp=intval($_POST['problem_id']); 92 | if(mysqli_num_rows(mysqli_query($con,'select problem_id from problem where problem_id='.$tmp))) 93 | $prob_id=$tmp; 94 | } 95 | } 96 | if(mysqli_query($con,"insert into message (thread_id,message_id,parent_id,orderNum,problem_id,depth,user_id,title,content,in_date) values($new_msg_id,$new_msg_id,$msg_id,$order_num,$prob_id,$depth,'$user_id','$title','$content',NOW())")) 97 | echo 'success'; 98 | else 99 | echo _('Something went wrong...'); 100 | $mutex->release_mutex(); 101 | } 102 | 103 | else if($op=='msg_edit'){ 104 | $prob_id=0; 105 | if(!isset($_POST['message']) || !isset($_POST['detail'])||!isset($_POST['message_id'])){ 106 | echo _('Invalid Argument...'); 107 | exit(); 108 | } 109 | $title=mysqli_real_escape_string($con,trim($_POST['message'])); 110 | $title_len=strlen($title); 111 | $message_id=intval($_POST['message_id']); 112 | $row=mysqli_fetch_row(mysqli_query($con, "select user_id from message where message_id=$message_id")); 113 | if($title_len==0){ 114 | echo _('Post can\'t be empty...'); 115 | exit(); 116 | } 117 | if($title_len>500){ 118 | echo _('Post too long...'); 119 | exit(); 120 | } 121 | $content=mysqli_real_escape_string($con,$_POST['detail']); 122 | if($row[0]==$_SESSION['user']) 123 | if(mysqli_query($con, "update message set title='$title',content='$content' where message_id=$message_id")) 124 | echo 'success'; 125 | else 126 | echo _('Something went wrong...'); 127 | } 128 | 129 | else 130 | echo _('Invalid Argument...'); 131 | -------------------------------------------------------------------------------- /web/public/api/ajax_preferences.php: -------------------------------------------------------------------------------- 1 | $name=$tmp; 21 | mysqli_query($con,"insert into preferences(user_id,property,value) values ('$user','$name','$tmp') ON DUPLICATE KEY UPDATE value='$tmp'"); 22 | } 23 | 24 | processOption('night'); 25 | processOption('edrmode'); 26 | processOption('sharecode'); 27 | 28 | $_SESSION['pref']=serialize($pref); 29 | -------------------------------------------------------------------------------- /web/public/api/ajax_profile.php: -------------------------------------------------------------------------------- 1 | 40){ 9 | echo _('Nickname too long...'); 10 | exit(); 11 | } 12 | if(strlen($_POST['school'])>60){ 13 | echo _('School name too long...'); 14 | exit(); 15 | } 16 | if(strlen($_POST['email'])>60){ 17 | echo _('Email too long...'); 18 | exit(); 19 | } 20 | if(!preg_match("/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i",$_POST['email'])){ 21 | echo _('Invalid Email...'); 22 | exit(); 23 | } 24 | 25 | if($_POST['type']=='profile'){ 26 | if(!isset($_SESSION['user'])){ 27 | echo _('Please login first...'); 28 | }else 29 | $user=$_SESSION['user']; 30 | if(!isset($_POST['oldpwd'])){ 31 | echo _('Invalid Argument...'); 32 | exit(); 33 | } 34 | 35 | require __DIR__.'/../../src/database.php'; 36 | 37 | if(!function_exists('my_rsa')) 38 | require __DIR__.'/../conf/ojsettings.php'; 39 | require __DIR__.'/../func/checkpwd.php'; 40 | 41 | if(!password_right($user, $_POST['oldpwd'])){ 42 | echo _('Wrong Password...'); 43 | exit(); 44 | } 45 | if(strlen($_POST['motto'])>200){ 46 | echo _('Motto too long...'); 47 | exit(); 48 | } 49 | $query='update users set email=\''.mysqli_real_escape_string($con,$_POST['email']).'\',school=\''.mysqli_real_escape_string($con,$_POST['school']).'\',nick=\''.mysqli_real_escape_string($con,$_POST['nick']).'\',motto=\''.mysqli_real_escape_string($con,$_POST['motto']).'\''; 50 | if(isset($_POST['newpwd']) && $_POST['newpwd']!=''){ 51 | $len=strlen($_POST['newpwd']); 52 | if($len<6||$len>50){ 53 | echo _('Password too long or too short (6~50)...'); 54 | exit(); 55 | } 56 | $query.=',password=\''.mysqli_real_escape_string($con,my_rsa($_POST['newpwd'])).'\''; 57 | } 58 | $query.=" where user_id='$user'"; 59 | mysqli_query($con,$query); 60 | $_SESSION['email']=mysqli_real_escape_string($con,$_POST['email']); 61 | echo 'success'; 62 | } 63 | 64 | else if($_POST['type']=='reg'){ 65 | if(!isset($_POST['userid'],$_POST['newpwd'])){ 66 | echo _('Invalid Argument...'); 67 | exit(); 68 | } 69 | if(!isset($_POST['lic'])){ 70 | echo _('Please agree the license agreement first...'); 71 | exit(); 72 | } 73 | 74 | require __DIR__.'/../../src/database.php'; 75 | 76 | $user=mysqli_real_escape_string($con,trim($_POST['userid'])); 77 | $len=strlen($user); 78 | if($len==0){ 79 | echo _('Username can\'t be empty...'); 80 | exit(); 81 | } 82 | if($len>20){ 83 | echo _('Username too long...'); 84 | exit(); 85 | } 86 | if(preg_match('/\W/',$user)){ 87 | echo _('Username can only contain alphabets, digits or "_"'); 88 | exit(); 89 | } 90 | $len=strlen($_POST['newpwd']); 91 | if($len<6||$len>50){ 92 | echo _('Password too long or too short (6~50)...'); 93 | exit(); 94 | } 95 | $pwd=mysqli_real_escape_string($con,$_POST['newpwd']); 96 | 97 | //If new regs need to be reviewed by administrators. 98 | if($require_confirm) 99 | $priv=0; 100 | else 101 | $priv=1; 102 | 103 | mysqli_query($con,"insert into users (user_id,email,password,reg_time,nick,school,motto,privilege) values ('$user','".mysqli_real_escape_string($con,$_POST['email'])."','$pwd',NOW(),'".mysqli_real_escape_string($con,$_POST['nick'])."','".mysqli_real_escape_string($con,$_POST['school'])."','',$priv)"); 104 | $code=mysqli_errno($con); 105 | if($code==0) 106 | echo 'success'; 107 | else if($code==1062) 108 | echo _('Username/Email already exists...'); 109 | else 110 | echo _('Something went wrong...'); 111 | }else 112 | echo _('Invalid Argument...'); -------------------------------------------------------------------------------- /web/public/api/ajax_resetpwd.php: -------------------------------------------------------------------------------- 1 | = 3) 67 | echo 'fuckyou'; 68 | else 69 | echo 'fail'; 70 | } 71 | } 72 | 73 | else if($_POST['type'] == 'update'){ 74 | if(!isset($_POST['newpwd'])){ 75 | echo _('Invalid Argument...'); 76 | exit(); 77 | } 78 | if(!isset($_SESSION['resetpwd_user']) || empty($_SESSION['resetpwd_user']) || !isset($_SESSION['resetpwd_flag']) || $_SESSION['resetpwd_flag']!=1) 79 | die('timeout'); 80 | if(!function_exists('my_rsa')) 81 | require __DIR__.'/../func/checkpwd.php'; 82 | 83 | $user = $_SESSION['resetpwd_user']; 84 | $len=strlen($_POST['newpwd']); 85 | if($len<6||$len>50){ 86 | echo _('Password too long or too short (6~50)...'); 87 | exit(); 88 | } 89 | $query='update users set password=\''.mysqli_real_escape_string($con,my_rsa($_POST['newpwd'])).'\''; 90 | $query.=" where user_id='$user'"; 91 | //Cleaning up 92 | unset($_SESSION['resetpwd_code']); 93 | unset($_SESSION['resetpwd_user']); 94 | unset($_SESSION['resetpwd_email']); 95 | unset($_SESSION['resetpwd_wrongnum']); 96 | unset($_SESSION['resetpwd_flag']); 97 | unset($_SESSION['last_send_time']); 98 | session_destroy(); 99 | 100 | if(mysqli_query($con,$query)) 101 | echo 'success'; 102 | else 103 | echo _('Something went wrong...'); 104 | } 105 | 106 | else 107 | echo _('Invalid Argument...'); 108 | -------------------------------------------------------------------------------- /web/public/api/ajax_sourcecode.php: -------------------------------------------------------------------------------- 1 | 29990){ 78 | echo _('Code too long...'); 79 | exit(); 80 | } 81 | 82 | require __DIR__.'/../lib/problem_flags.php'; 83 | require __DIR__.'/../func/privilege.php'; 84 | 85 | $forbidden=false; 86 | if($row[4]=='Y' && !check_priv(PRIV_PROBLEM)) 87 | $forbidden=true; 88 | else if($row[5]&PROB_IS_HIDE && !check_priv(PRIV_INSIDER)) 89 | $forbidden=true; 90 | if($forbidden){ 91 | echo _('Permission Denied...'); 92 | exit(); 93 | } 94 | 95 | $_SESSION['lang']=$lang; 96 | mysqli_query($con,"update users set language=$lang where user_id='".$_SESSION['user']."'"); 97 | mysqli_query($con,"update problem set in_date=NOW() where problem_id=$prob"); 98 | 99 | $key=md5('key'.time().rand()); 100 | $share_code=(isset($_POST['public']) ? 1 : 0); 101 | 102 | $data=array( 103 | 'a'=>$prob, 104 | 'b'=>$lang, 105 | 'c'=>$row[0], 106 | 'd'=>$row[1], 107 | 'e'=>$row[2], 108 | 'f'=>$code, 109 | 'g'=>$_SESSION['user'], 110 | 'h'=>$key, 111 | 'i'=>$share_code, 112 | 'j'=>$row[3] 113 | ); 114 | ignore_user_abort(TRUE); 115 | $result = posttodaemon($data); 116 | if(strstr($result,'OK')) 117 | echo 'success_'.$key; 118 | else 119 | die($result); 120 | }else if($_POST['op']=='rejudge'){ 121 | $data=array( 122 | 'a'=>$prob, 123 | 'c'=>$row[0], 124 | 'd'=>$row[1], 125 | 'e'=>$row[2], 126 | 'h'=>"rejudge".$prob, 127 | 'j'=>$row[3], 128 | 'k'=>1 //TYPE_rejudge 129 | ); 130 | ignore_user_abort(TRUE); 131 | $result = posttodaemon($data); 132 | 133 | if(strstr($result,"OK")) 134 | echo 'success'; 135 | else if(strstr($result,"another")) 136 | echo _('Another rejudge thread is running, try again later...'); 137 | else 138 | echo $result; 139 | } 140 | -------------------------------------------------------------------------------- /web/public/api/ajax_testcase.php: -------------------------------------------------------------------------------- 1 | =experience_titles.experience GROUP BY user_id)t1 LEFT JOIN experience_titles ON t1.m=experience_titles.experience where user_id='$user'"; 18 | $row=mysqli_fetch_row(mysqli_query($con,$query)); 19 | 20 | if($row[10] & PRIV_USER){ 21 | if(time()-strtotime($row[3])<=300){ 22 | $status_text = _('Online'); 23 | $status_col = 'label-ac'; 24 | }else{ 25 | $status_text = _('Offline'); 26 | $status_col = 'label-wa'; 27 | } 28 | }else{ 29 | $status_text = _('Disabled'); 30 | $status_col = 'label-ce'; 31 | } 32 | 33 | if(isset($_GET['type'])&&$_GET['type']=='json'){ 34 | if(!$row) 35 | echo '{"nobody":0}'; 36 | else{ 37 | $failed=$solved="{"; 38 | $res=mysqli_query($con,"select problem_id,min(result) from solution where user_id='$user' group by problem_id"); 39 | while($row=mysqli_fetch_row($res)){ 40 | $id=$row[0]; 41 | if($row[1]==0) 42 | $solved.="\"$id\":0,"; 43 | else 44 | $failed.="\"$id\":0,"; 45 | } 46 | echo '{"solved":',rtrim($solved,','),'},"failed":',rtrim($failed,','),'}}'; 47 | } 48 | }else{ 49 | if(!$row){ 50 | echo _('There\'s no such user...'); 51 | exit(); 52 | } 53 | header('Content-Type: text/html; charset=utf-8'); 54 | ?> 55 |
56 | 57 | 58 | 59 |
60 |

61 |

62 | 65 |
66 |
67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 0"); 88 | $number=mysqli_num_rows($failed); 89 | echo ''; 93 | $solved=mysqli_query($con,"select problem_id from solution where result=0 and user_id='$user' group by problem_id"); 94 | $number=mysqli_num_rows($solved); 95 | echo ''; 99 | ?> 100 | 101 |
',_('Failed'),"($number)",''; 90 | while($row=mysqli_fetch_row($failed)) 91 | echo '',$row[0],' '; 92 | echo '
',_('Solved'),"($number)",''; 96 | while($row=mysqli_fetch_row($solved)) 97 | echo '',$row[0],' '; 98 | echo '
102 | 103 | -------------------------------------------------------------------------------- /web/public/api/ajax_usernote.php: -------------------------------------------------------------------------------- 1 | \[\]]{1,256}))?\])|(?:\[\/([a-z]{1,16})\])/ig; 23 | 24 | // stack frame object 25 | function taginfo_t(bbtag, etag) 26 | { 27 | this.bbtag = bbtag; 28 | this.etag = etag; 29 | } 30 | 31 | // check if it's a valid BBCode tag 32 | function isValidTag(str) 33 | { 34 | if(!str || !str.length) 35 | return false; 36 | 37 | return tagname_re.test(str); 38 | } 39 | 40 | // 41 | // m1 - CR or LF 42 | // m2 - the tag of the [tag=option] expression 43 | // m3 - the option of the [tag=option] expression 44 | // m4 - the end tag of the [/tag] expression 45 | // 46 | function textToHtmlCB(mstr, m1, m2, m3, m4, offset, string) 47 | { 48 | // 49 | // CR LF sequences 50 | // 51 | function times(s,t) { 52 | var ret=""; 53 | while(t--) 54 | ret+=s; 55 | return ret; 56 | } 57 | 58 | if(m1 && m1.length) { 59 | if(typeof(window.fix_ie_pre)=='undefined') 60 | return mstr; 61 | 62 | switch (m1) { 63 | case ' ': 64 | return " "; 65 | case '\r': 66 | return ""; 67 | case '\n': 68 | return "
"; 69 | case '\t': 70 | return times(" ",8); 71 | } 72 | return mstr; 73 | } 74 | 75 | // 76 | // handle start tags 77 | // 78 | if(isValidTag(m2)) { 79 | // if in the noparse state, just echo the tag 80 | if(noparse) 81 | return "[" + m2 + "]"; 82 | 83 | // ignore any tags if there's an open option-less [url] tag 84 | if(opentags.length && opentags[opentags.length-1].bbtag == "url" && urlstart >= 0) 85 | return "[" + m2 + "]"; 86 | 87 | switch (m2) { 88 | case "code": 89 | opentags.push(new taginfo_t(m2, "")); 90 | crlf2br = false; 91 | return ''; 92 | 93 | case "pre": 94 | opentags.push(new taginfo_t(m2, "")); 95 | crlf2br = false; 96 | return ""; 97 | 98 | case "color": 99 | case "colour": 100 | if(!m3 || !color_re.test(m3)) 101 | m3 = "inherit"; 102 | opentags.push(new taginfo_t(m2, "")); 103 | return ""; 104 | 105 | case "size": 106 | if(!m3 || !number_re.test(m3)) 107 | m3 = "1"; 108 | opentags.push(new taginfo_t(m2, "")); 109 | return ""; 110 | 111 | case "s": 112 | opentags.push(new taginfo_t(m2, "")); 113 | return ""; 114 | 115 | case "noparse": 116 | noparse = true; 117 | return ""; 118 | 119 | case "url": 120 | opentags.push(new taginfo_t(m2, "")); 121 | 122 | // check if there's a valid option 123 | if(m3 && uri_re.test(m3)) { 124 | // if there is, output a complete start anchor tag 125 | urlstart = -1; 126 | return ""; 127 | } 128 | 129 | // otherwise, remember the URL offset 130 | urlstart = mstr.length + offset; 131 | 132 | // and treat the text following [url] as a URL 133 | return "")); 137 | 138 | return "")); 143 | return m3 && m3.length && uri_re.test(m3) ? "<" + m2 + " cite=\"" + m3 + "\">" : "<" + m2 + ">"; 144 | 145 | default: 146 | // [samp], [b], [i] and [u] don't need special processing 147 | opentags.push(new taginfo_t(m2, "")); 148 | return "<" + m2 + ">"; 149 | 150 | } 151 | } 152 | 153 | // 154 | // process end tags 155 | // 156 | if(isValidTag(m4)) { 157 | if(noparse) { 158 | // if it's the closing noparse tag, flip the noparse state 159 | if(m4 == "noparse") { 160 | noparse = false; 161 | return ""; 162 | } 163 | 164 | // otherwise just output the original text 165 | return "[/" + m4 + "]"; 166 | } 167 | 168 | // highlight mismatched end tags 169 | if(!opentags.length || opentags[opentags.length-1].bbtag != m4) 170 | return "[/" + m4 + "]"; 171 | 172 | if(m4 == "url") { 173 | // if there was no option, use the content of the [url] tag 174 | if(urlstart > 0) 175 | return "\">" + string.substr(urlstart, offset-urlstart) + opentags.pop().etag; 176 | 177 | // otherwise just close the tag 178 | return opentags.pop().etag; 179 | } 180 | else if(m4 == "code" || m4 == "pre") 181 | crlf2br = true; 182 | 183 | // other tags require no special processing, just output the end tag 184 | return opentags.pop().etag; 185 | } 186 | 187 | return mstr; 188 | } 189 | 190 | // 191 | // post must be HTML-encoded 192 | // 193 | function parseBBCode(post) 194 | { 195 | var result, endtags, tag; 196 | 197 | 198 | // create a new array for open tags 199 | if(opentags == null || opentags.length) 200 | opentags = new Array(0); 201 | 202 | // run the text through main regular expression matcher 203 | result = post.replace(postfmt_re, textToHtmlCB); 204 | 205 | // reset noparse, if it was unbalanced 206 | if(noparse) 207 | noparse = false; 208 | 209 | // if there are any unbalanced tags, make sure to close them 210 | if(opentags.length) { 211 | endtags = new String(); 212 | 213 | // if there's an open [url] at the top, close it 214 | if(opentags[opentags.length-1].bbtag == "url") { 215 | opentags.pop(); 216 | endtags += "\">" + post.substr(urlstart, post.length-urlstart) + ""; 217 | } 218 | 219 | // close remaining open tags 220 | while(opentags.length) 221 | endtags += opentags.pop().etag; 222 | } 223 | 224 | return endtags ? result + endtags : result; 225 | } 226 | -------------------------------------------------------------------------------- /web/public/assets/js/common.js: -------------------------------------------------------------------------------- 1 | function htmlEncode(str) { 2 | var s = ""; 3 | if (str.length == 0) return ""; 4 | s = str.replace(/&/g, "&"); 5 | s = s.replace(/ /g, " "); 6 | s = s.replace(//g, ">"); 8 | s = s.replace(/\'/g, "'"); 9 | s = s.replace(/\"/g, """); 10 | return s; 11 | } 12 | function encode_space(str) { 13 | var s=""; 14 | if(str.length == 0) return ""; 15 | s=str.replace(/\r?\n/g, "
"); 16 | s=s.replace(/ /g, " "); 17 | s=s.replace(/\t/g, "        "); 18 | return s; 19 | } 20 | function LoadCSS(url) { 21 | var head = document.getElementsByTagName('head')[0]; 22 | var link = document.createElement('link'); 23 | link.type = 'text/css'; 24 | link.rel = 'stylesheet'; 25 | link.href = url; 26 | head.appendChild(link); 27 | return link; 28 | } 29 | function InsertString(tb, str){ 30 | //var tb = document.getElementById(tbid); 31 | tb.focus(); 32 | if (document.all){ 33 | var r = document.selection.createRange(); 34 | document.selection.empty(); 35 | r.text = str; 36 | r.collapse(); 37 | r.select(); 38 | } 39 | else{ 40 | var newstart = tb.selectionStart+str.length; 41 | tb.value=tb.value.substr(0,tb.selectionStart)+str+tb.value.substring(tb.selectionEnd); 42 | tb.selectionStart = newstart; 43 | tb.selectionEnd = newstart; 44 | } 45 | } 46 | function GetSelection(tb){ 47 | var sel = ''; 48 | if (document.all){ 49 | var r = document.selection.createRange(); 50 | document.selection.empty(); 51 | sel = r.text; 52 | } 53 | else{ 54 | //var tb = document.getElementById(tbid); 55 | // tb.focus(); 56 | var start = tb.selectionStart; 57 | var end = tb.selectionEnd; 58 | sel = tb.value.substring(start, end); 59 | } 60 | return sel; 61 | } 62 | function GetUrlParms() 63 | { 64 | var args=new Object(); 65 | var query=location.search.substring(1); 66 | var pairs=query.split("&"); 67 | for(var i=0;ili>a.pager-pre-link').get(0).click(); 89 | }catch(exp){} 90 | } , //alt+A 91 | "68": function(){ 92 | try{ 93 | $('ul.pager>li>a.pager-next-link').get(0).click(); 94 | }catch(exp){} 95 | } , //alt+D 96 | "66": function(){location.href=$('#nav_bbs').attr('href');} , //alt+B 97 | "67": function(){location.href=$('#nav_cont').attr('href');} , //alt+C 98 | "80": function(){location.href=$('#nav_set').attr('href');} , //alt+P 99 | "82": function(){location.href=$('#nav_record').attr('href');} , //alt+R 100 | "73": function(){$('#nav_searchbtn').click();} , //alt+I 101 | "76": function(){$("#nav_login").click();} , //alt+L 102 | "77": function(){ 103 | var obj=$('#nav_mail'); 104 | if(obj.length) //if logged in 105 | location.href=obj.attr('href'); 106 | } //Alt+M 107 | 108 | }; 109 | shortcuts[49]=shortcuts[67]; //Alt+1 110 | shortcuts[50]=function(){location.href=$('#nav_set').attr('href');} //Alt+2 111 | shortcuts[51]=shortcuts[66]; //Alt+3 112 | shortcuts[52]=shortcuts[82]; //Alt+4 113 | shortcuts[53]=function(){location.href=$('#nav_rank').attr('href');} //Alt+5 114 | shortcuts[54]=function(){location.href=$('#nav_about').attr('href');} //Alt+6 115 | shortcuts[55]=shortcuts[73]; //Alt+7 116 | 117 | function hotkey_hint_show () { 118 | $('.shortcut-hint').addClass('shortcut-hint-active'); 119 | } 120 | function hotkey_hint_dismiss (E) { 121 | if(E.keyCode==18){ //alt key 122 | $('.shortcut-hint').removeClass('shortcut-hint-active'); 123 | } 124 | } 125 | function reg_hotkey (key, fun) { 126 | shortcuts[key] = fun; } 127 | function change_type(e){ 128 | $('#search_type').val(e); 129 | $('#search_select').html($('#type'+e).html()); 130 | $('#search_input').focus(); 131 | } 132 | $(document).ready(function(){ 133 | var $notifier=$('.notifier'),msgnum=0; 134 | $('#nav_logoff').click(function(){$.ajax({url:"/api/ajax_logoff.php",dataType:"html",success:function(){location.reload();}});}); 135 | $('#search_span').hover(function(){ 136 | $(this).addClass('open'); 137 | },function(){ 138 | $(this).removeClass('open'); 139 | }); 140 | $('#search_form').submit(function(){ 141 | if($.trim($('#search_input').val()).length==0) 142 | return false; 143 | return true; 144 | }); 145 | function checkMail(){ 146 | $.get("/api/ajax_mailfunc.php?op=check",function(data){ 147 | if(data=='-1') 148 | window.location.reload(); 149 | else if(isNaN(data)||data=='0') 150 | return; 151 | $notifier.html(data); 152 | if(data>msgnum){ 153 | msgnum=data; 154 | $('#alert_newmsg').fadeIn(); 155 | setTimeout(function(){$('#alert_newmsg').fadeOut()},2000); 156 | } 157 | }); 158 | } 159 | checkMail(); 160 | setInterval(checkMail,120000); 161 | 162 | }).keydown(function(E){ 163 | if(window.hidehotkey) 164 | return; 165 | if(E.altKey && !E.metaKey){ 166 | var key=E.keyCode; 167 | if(key>=97 && key<=122) 168 | key-=32; 169 | else if(key==18){ //alt key 170 | hotkey_hint_show(E); 171 | return; 172 | } 173 | if(shortcuts.hasOwnProperty(key)) 174 | (shortcuts[key])(E); 175 | return false; 176 | } 177 | }).keyup(hotkey_hint_dismiss); 178 | $('#search_input').keyup(hotkey_hint_dismiss); 179 | $('#nav_searchbtn').click(function(){ 180 | $('#search_form').addClass("visible-inline-block"); 181 | $('#nav_back').show(); 182 | $('#nav_left').addClass('hidden-xs hidden-sm hidden-md'); 183 | $('#search_input').focus(); 184 | }); 185 | $('#nav_clrsearch').click(function(){ 186 | $('#search_input').val(''); 187 | $('#nav_back').hide(); 188 | $('#search_form').removeClass("visible-inline-block"); 189 | $('#nav_left').removeClass('hidden-xs hidden-sm hidden-md'); 190 | }); 191 | -------------------------------------------------------------------------------- /web/public/assets/js/html5.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",version:"3.6.2pre",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d").attr(a.extend(b(this),{type:"text"}))}e.removeAttr("name").data({"placeholder-enabled":!0,"placeholder-password":g,"placeholder-id":i}).bind("focus.placeholder",c),g.data({"placeholder-textinput":e,"placeholder-id":i}).before(e)}f.value="",g=g.removeAttr("id").hide().prevAll('input[type="text"]:first').attr("id",g.data("placeholder-id")).show()}else{var k=g.data("placeholder-password");k&&(k[0].value="",g.attr("id",g.data("placeholder-id")).show().nextAll('input[type="password"]:last').hide().removeAttr("id"))}g.addClass(n.customClass),g[0].value=g.attr(h?"placeholder-x":"placeholder")}else g.removeClass(n.customClass)}function e(){try{return document.activeElement}catch(a){}}var f,g,h=!1,i="[object OperaMini]"===Object.prototype.toString.call(window.operamini),j="placeholder"in document.createElement("input")&&!i&&!h,k="placeholder"in document.createElement("textarea")&&!i&&!h,l=a.valHooks,m=a.propHooks,n={};j&&k?(g=a.fn.placeholder=function(){return this},g.input=!0,g.textarea=!0):(g=a.fn.placeholder=function(b){var e={customClass:"placeholder"};return n=a.extend({},e,b),this.filter((j?"textarea":":input")+"["+(h?"placeholder-x":"placeholder")+"]").not("."+n.customClass).not(":radio, :checkbox, [type=hidden]").bind({"focus.placeholder":c,"blur.placeholder":d}).data("placeholder-enabled",!0).trigger("blur.placeholder")},g.input=j,g.textarea=k,f={get:function(b){var c=a(b),d=c.data("placeholder-password");return d?d[0].value:c.data("placeholder-enabled")&&c.hasClass(n.customClass)?"":b.value},set:function(b,f){var g,h,i=a(b);return""!==f&&(g=i.data("placeholder-textinput"),h=i.data("placeholder-password"),g?(c.call(g[0],!0,f)||(b.value=f),g[0].value=f):h&&(c.call(b,!0,f)||(h[0].value=f),b.value=f)),i.data("placeholder-enabled")?(""===f?(b.value=f,b!=e()&&d.call(b)):(i.hasClass(n.customClass)&&c.call(b),b.value=f),i):(b.value=f,i)}},j||(l.input=f,m.value=f),k||(l.textarea=f,m.value=f),a(function(){a(document).delegate("form","submit.placeholder",function(){var b=a("."+n.customClass,this).each(function(){c.call(this,!0,"")});setTimeout(function(){b.each(d)},10)})}),a(window).bind("beforeunload.placeholder",function(){var b=!0;try{"javascript:void(0)"===document.activeElement.toString()&&(b=!1)}catch(c){}b&&a("."+n.customClass).each(function(){this.value=""})}))}); -------------------------------------------------------------------------------- /web/public/assets/js/jquery.plupload.queue.min.js: -------------------------------------------------------------------------------- 1 | ;(function(e,t){function r(e){return plupload.translate(e)||e}function i(t,n){n.contents().each(function(t,n){n=e(n),n.is(".plupload")||n.remove()}),n.prepend('
'+'
'+'
'+'
'+'
'+r("Select files")+"
"+'
'+r("Add files to the upload queue and click the start button.")+"
"+"
"+"
"+'
'+'
'+'
'+r("Filename")+"
"+'
 
'+'
'+r("Status")+"
"+'
'+r("Size")+"
"+'
 
'+"
"+'
    '+'"+"
    "+"
    "+"
    "+''+"
    ")}var n={};e.fn.pluploadQueue=function(s){return s?(this.each(function(){function c(t){var n;t.status==plupload.DONE&&(n="plupload_done"),t.status==plupload.FAILED&&(n="plupload_failed"),t.status==plupload.QUEUED&&(n="plupload_delete"),t.status==plupload.UPLOADING&&(n="plupload_uploading");var r=e("#"+t.id).attr("class",n).find("a").css("display","block");t.hint&&r.attr("title",t.hint)}function h(){e("span.plupload_total_status",a).html(u.total.percent+"%"),e("div.plupload_progress_bar",a).css("width",u.total.percent+"%"),e("span.plupload_upload_status",a).html(t.sprintf(r("Uploaded %d/%d files"),u.total.uploaded,u.files.length))}function p(){var n=e("ul.plupload_filelist",a).html(""),i=0,s;e.each(u.files,function(t,r){s="",r.status==plupload.DONE&&(r.target_name&&(s+=''),s+='',s+='',i++,e("#"+f+"_count").val(i)),n.append('
  • '+'
    '+r.name+"
    "+'
    '+'
    '+r.percent+"%
    "+'
    '+plupload.formatSize(r.size)+"
    "+'
     
    '+s+"
  • "),c(r),e("#"+r.id+".plupload_delete a").click(function(t){e("#"+r.id).remove(),u.removeFile(r),t.preventDefault()})}),e("span.plupload_total_file_size",a).html(plupload.formatSize(u.total.size)),u.total.queued===0?e("span.plupload_add_text",a).html(r("Add Files")):e("span.plupload_add_text",a).html(t.sprintf(r("%d files queued"),u.total.queued)),e("a.plupload_start",a).toggleClass("plupload_disabled",u.files.length==u.total.uploaded+u.total.failed),n[0].scrollTop=n[0].scrollHeight,h(),!u.files.length&&u.features.dragdrop&&u.settings.dragdrop&&e("#"+f+"_filelist").append('
  • '+r("Drag files here.")+"
  • ")}function d(){delete n[f],u.destroy(),a.html(l),u=a=l=null}var u,a,f,l;a=e(this),f=a.attr("id"),f||(f=plupload.guid(),a.attr("id",f)),l=a.html(),i(f,a),s=e.extend({dragdrop:!0,browse_button:f+"_browse",container:f},s),s.dragdrop&&(s.drop_element=f+"_filelist"),u=new plupload.Uploader(s),n[f]=u,u.bind("UploadFile",function(t,n){e("#"+n.id).addClass("plupload_current_file")}),u.bind("Init",function(t,n){!s.unique_names&&s.rename&&a.on("click","#"+f+"_filelist div.plupload_file_name span",function(n){var r=e(n.target),i,s,o,u="";i=t.getFile(r.parents("li")[0].id),o=i.name,s=/^(.+)(\.[^.]+)$/.exec(o),s&&(o=s[1],u=s[2]),r.hide().after(''),r.next().val(o).focus().blur(function(){r.show().next().remove()}).keydown(function(t){var n=e(this);t.keyCode==13&&(t.preventDefault(),i.name=n.val()+u,r.html(i.name),n.blur())})}),e("#"+f+"_container").attr("title","Using runtime: "+n.runtime),e("a.plupload_start",a).click(function(t){e(this).hasClass("plupload_disabled")||u.start(),t.preventDefault()}),e("a.plupload_stop",a).click(function(e){e.preventDefault(),u.stop()}),e("a.plupload_start",a).addClass("plupload_disabled")}),u.bind("Error",function(t,n){var i=n.file,s;i&&(s=n.message,n.details&&(s+=" ("+n.details+")"),n.code==plupload.FILE_SIZE_ERROR&&alert(r("Error: File too large:")+" "+i.name),n.code==plupload.FILE_EXTENSION_ERROR&&alert(r("Error: Invalid file extension:")+" "+i.name),i.hint=s,e("#"+i.id).attr("class","plupload_failed").find("a").css("display","block").attr("title",s)),n.code===plupload.INIT_ERROR&&setTimeout(function(){d()},1)}),u.bind("PostInit",function(t){t.settings.dragdrop&&t.features.dragdrop&&e("#"+f+"_filelist").append('
  • '+r("Drag files here.")+"
  • ")}),u.init(),u.bind("StateChanged",function(){u.state===plupload.STARTED?(e("li.plupload_delete a,div.plupload_buttons",a).hide(),u.disableBrowse(!0),e("span.plupload_upload_status,div.plupload_progress,a.plupload_stop",a).css("display","block"),e("span.plupload_upload_status",a).html("Uploaded "+u.total.uploaded+"/"+u.files.length+" files"),s.multiple_queues&&e("span.plupload_total_status,span.plupload_total_file_size",a).show()):(p(),e("a.plupload_stop,div.plupload_progress",a).hide(),e("a.plupload_delete",a).css("display","block"),s.multiple_queues&&u.total.uploaded+u.total.failed==u.files.length&&(e(".plupload_buttons,.plupload_upload_status",a).css("display","inline"),u.disableBrowse(!1),e(".plupload_start",a).addClass("plupload_disabled"),e("span.plupload_total_status,span.plupload_total_file_size",a).hide()))}),u.bind("FilesAdded",p),u.bind("FilesRemoved",function(){var t=e("#"+f+"_filelist").scrollTop();p(),e("#"+f+"_filelist").scrollTop(t)}),u.bind("FileUploaded",function(e,t){c(t)}),u.bind("UploadProgress",function(t,n){e("#"+n.id+" div.plupload_file_status",a).html(n.percent+"%"),c(n),h()}),s.setup&&s.setup(u)}),this):n[e(this[0]).attr("id")]}})(jQuery,mOxie); -------------------------------------------------------------------------------- /web/public/assets/js/plupload.zh_CN.js: -------------------------------------------------------------------------------- 1 | // Chinese (China) (zh_CN) 2 | plupload.addI18n({"Stop Upload":"停止上传","Upload URL might be wrong or doesn't exist.":"上传的URL可能是错误的或不存在。","tb":"tb","Size":"大小","Close":"关闭","You must specify either browse_button or drop_element.":"您必须指定 browse_button 或者 drop_element。","Init error.":"初始化错误。","Add files to the upload queue and click the start button.":"将文件添加到上传队列,然后点击”开始上传“按钮。","List":"列表","Filename":"文件名","%s specified, but cannot be found.":"%s 已指定,但是没有找到。","Image format either wrong or not supported.":"图片格式错误或者不支持。","Status":"状态","HTTP Error.":"HTTP 错误。","Start Upload":"开始上传","Error: File too large:":"错误: 文件太大:","kb":"kb","Duplicate file error.":"重复文件错误。","File size error.":"文件大小错误。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"错误:无效的文件扩展名:","Select files":"选择文件","%s already present in the queue.":"%s 已经在当前队列里。","Resoultion out of boundaries! %s runtime supports images only up to %wx%hpx.":"超限。%s 支持最大 %wx%hpx 的图片。","File: %s":"文件: %s","b":"b","Uploaded %d/%d files":"已上传 %d/%d 个文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只接受同时上传 %d 个文件,多余的文件将会被删除。","%d files queued":"%d 个文件加入到队列","File: %s, size: %d, max file size: %d":"文件: %s, 大小: %d, 最大文件大小: %d","Thumbnails":"缩略图","Drag files here.":"把文件拖到这里。","Runtime ran out of available memory.":"运行时已消耗所有可用内存。","File count error.":"文件数量错误。","File extension error.":"文件扩展名错误。","mb":"mb","Add Files":"增加文件"}); -------------------------------------------------------------------------------- /web/public/assets/res/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/android-chrome-192x192.png -------------------------------------------------------------------------------- /web/public/assets/res/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/android-chrome-512x512.png -------------------------------------------------------------------------------- /web/public/assets/res/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /web/public/assets/res/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /web/public/assets/res/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /web/public/assets/res/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /web/public/assets/res/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /web/public/assets/res/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/apple-touch-icon.png -------------------------------------------------------------------------------- /web/public/assets/res/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web/public/assets/res/chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/chrome.png -------------------------------------------------------------------------------- /web/public/assets/res/codgic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/codgic.png -------------------------------------------------------------------------------- /web/public/assets/res/edge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/edge.png -------------------------------------------------------------------------------- /web/public/assets/res/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/favicon-16x16.png -------------------------------------------------------------------------------- /web/public/assets/res/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/favicon-32x32.png -------------------------------------------------------------------------------- /web/public/assets/res/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/favicon.ico -------------------------------------------------------------------------------- /web/public/assets/res/firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/firefox.png -------------------------------------------------------------------------------- /web/public/assets/res/ie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/ie.png -------------------------------------------------------------------------------- /web/public/assets/res/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CWOJ", 3 | "icons": [ 4 | { 5 | "src": "\/assets\/res\/android-chrome-192x192.png?v=1", 6 | "sizes": "192x192", 7 | "type": "image\/png" 8 | }, 9 | { 10 | "src": "\/assets\/res\/android-chrome-512x512.png?v=1", 11 | "sizes": "512x512", 12 | "type": "image\/png" 13 | } 14 | ], 15 | "theme_color": "#ffffff", 16 | "display": "standalone" 17 | } 18 | -------------------------------------------------------------------------------- /web/public/assets/res/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/mstile-150x150.png -------------------------------------------------------------------------------- /web/public/assets/res/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/mstile-310x150.png -------------------------------------------------------------------------------- /web/public/assets/res/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/mstile-310x310.png -------------------------------------------------------------------------------- /web/public/assets/res/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/mstile-70x70.png -------------------------------------------------------------------------------- /web/public/assets/res/ojlogo-alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/ojlogo-alt.png -------------------------------------------------------------------------------- /web/public/assets/res/ojlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/ojlogo.png -------------------------------------------------------------------------------- /web/public/assets/res/opera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/assets/res/opera.png -------------------------------------------------------------------------------- /web/public/assets/res/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /web/public/backupcode.php: -------------------------------------------------------------------------------- 1 | '; 8 | } 9 | 10 | if(!isset($_SESSION['user'])){ 11 | $info=_('Please login first...'); 12 | show_alert($info); 13 | exit; 14 | } 15 | require __DIR__.'/../src/database.php'; 16 | require __DIR__.'/lib/lang.php'; 17 | require __DIR__.'/lib/tgz.lib.php'; 18 | 19 | $pref=unserialize($_SESSION['pref']); 20 | $now=time(); 21 | if($now - $pref->backuptime < 604800){ 22 | $info=_('You can only backup your code not more than once a month...'); 23 | show_alert($info); 24 | exit; 25 | } 26 | $archive="backup-$now"; 27 | header('Content-type: application/octet-stream'); 28 | header('Content-Disposition: attachment; filename="'.$archive.'.tar.gz"'); 29 | 30 | $fout = fopen('php://output','wb'); 31 | if($fout === FALSE) 32 | exit; 33 | 34 | $tar = new TGZfile($fout); 35 | 36 | $pref->backuptime=$now; 37 | $_SESSION['pref']=serialize($pref); 38 | 39 | $user=mysql_real_escape_string($_SESSION['user']); 40 | mysql_query("insert into preferences(user_id,property,value) values ('$user','backuptime','$now') ON DUPLICATE KEY UPDATE value='$now'"); 41 | 42 | $res=mysql_query("SELECT problem_id,language,source FROM source_code , (SELECT max_sol,problem_id,language FROM solution, (SELECT max(solution_id) AS max_sol FROM solution WHERE user_id='$user' AND result=0 GROUP BY problem_id) last WHERE solution_id=max_sol) tmp WHERE source_code.solution_id=max_sol"); 43 | 44 | while($row=mysql_fetch_row($res)){ 45 | $filename = $archive.'/'.$row[0].'.'.$LANG_EXT[$row[1]]; 46 | $tar->AddFile($filename, $row[2]); 47 | } 48 | 49 | $tar->Close(); -------------------------------------------------------------------------------- /web/public/conf/ojsettings.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | <?php echo _('Upgrade your browser')?> 19 | 20 | 34 | 35 | 36 |

    37 |

    38 |
    39 |

    40 |

    41 | 48 |
    49 |

    50 |

    51 | 52 | 56 | 57 | -------------------------------------------------------------------------------- /web/public/func/checklogin.php: -------------------------------------------------------------------------------- 1 | 64) 7 | $value=substr($value,0,64); 8 | else 9 | $value=str_pad($value,64,"\x00"); 10 | 11 | $crypted=""; 12 | openssl_public_encrypt($value,$crypted,PASSWORD_PUBLIC_KEY,OPENSSL_NO_PADDING); 13 | return "\x00".base64_encode($crypted); 14 | } 15 | 16 | function password_right($usr, $pwd_in){ 17 | require __DIR__.'/../../src/database.php'; 18 | $result=mysqli_query($con,"select password,user_id from users where user_id='$usr' or email='$usr' limit 1"); 19 | if(!($row=mysqli_fetch_row($result)) || !$row[0]) 20 | return false; 21 | $usr=$row[1]; 22 | $pwd_enc=my_rsa($pwd_in); 23 | $pwd_real=$row[0]; 24 | if(ord($pwd_real)!=0){ //password in database is not encrypted password 25 | $pwd_real=my_rsa($pwd_real); 26 | $pwd_escaped=mysqli_escape_string($con,$pwd_real); 27 | mysqli_query($con,"update users set password='$pwd_escaped' where user_id='$usr'"); 28 | } 29 | if(strcmp($pwd_enc, $pwd_real)!=0) 30 | return false; 31 | else 32 | return true; 33 | } -------------------------------------------------------------------------------- /web/public/func/contest.php: -------------------------------------------------------------------------------- 1 | strtotime($row[2])) 65 | $range_end=$row[2]; 66 | 67 | //As for every problem. 68 | for($i=0;$i'".$range_start."' and in_date<'".$range_end."' and problem_id=".$prob_arr[$i].' order by in_date limit 1')); 74 | //Process score. 75 | if(isset($s_row[0])) 76 | $score=$s_row[0]; 77 | $tot_score+=$score; 78 | //Process result. 79 | if(isset($s_row[1])) 80 | $result=$s_row[1]; 81 | //Process time. 82 | if(isset($s_row[2])) 83 | $time=strtotime($s_row[2])-strtotime($range_start); 84 | $tot_time+=$time; 85 | }else{ //Others: Select the highest score among eligible submits. 86 | $s_row=mysqli_fetch_row(mysqli_query($con,"select MAX(score),COUNT(score),MIN(result),MAX(in_date) from solution where user_id='$user_id' and in_date>'".$range_start."' and in_date<'".$range_end."' and problem_id=".$prob_arr[$i])); 87 | //Process score. 88 | if(isset($s_row[0])){ 89 | if($cont_judgeway==2 && $s_row[0]==100) //ACM: if score != 100 then score = 0. 90 | $score=100; 91 | else if($cont_judgeway==1 && $s_row[1]!=0){ //Codgic: Minus 5 points per non-AC submit. 92 | $score=$s_row[0]-5*($s_row[1]-1); 93 | 94 | if($score < 0) 95 | $score = 0; 96 | 97 | if ($s_row[2] == 0 && $score < CODGIC_MIN_SCORE) 98 | { 99 | $score = CODGIC_MIN_SCORE; 100 | } 101 | }else if($cont_judgeway==0) //Training: MAX(score). 102 | $score=$s_row[0]; 103 | } 104 | $tot_score+=$score; 105 | //Process result. 106 | if(isset($s_row[2])) 107 | $result=$s_row[2]; 108 | else 109 | $result='NULL'; 110 | //Process time. 111 | if(isset($s_row[3])){ 112 | if($s_row[0]==100) 113 | $time=strtotime($s_row[3])-strtotime($range_start)+1200*($s_row[1]-1); 114 | else 115 | $time=1200*$s_row[1]; 116 | } 117 | $tot_time+=$time; 118 | } 119 | //Write into database. 120 | mysqli_query($con, "INSERT into contest_detail (user_id,contest_id,problem_id,result,score,time) VALUES ('$user_id',$cont_id,".$prob_arr[$i].",$result,$score,$time) ON DUPLICATE KEY UPDATE result=$result,score=$score,time=$time"); 121 | mysqli_query($con, "UPDATE contest_status SET tot_score=$tot_score, tot_time=$tot_time where user_id='$user_id' and contest_id=$cont_id limit 1"); 122 | } 123 | } 124 | //Update user rank. 125 | update_cont_rank($cont_id); 126 | //Update last_upd_time. 127 | mysqli_query($con, "update contest set last_upd_time=NOW() where contest_id=$cont_id"); 128 | } 129 | 130 | //Return description text of each type of contest. 131 | function get_judgeway_destext($judge_way){ 132 | if($judge_way==0) 133 | return _('Final score is the sum of the highest score of each problem. Time Penalty records the latest submit time for solved problems and 1200s for unsolved problems.').'
    final_score = max_score;
    final_time = AC ? (last_submit_time + 1200s * (submit_times - 1)) : 1200s * submit_times; '; 134 | else if($judge_way==1) 135 | return _('Based on the highest score, each non-first submit will let you lose 5 points. Time Penalty records the latest submit time for solved problems and 1200s for unsolved problems.').'
    final_score = max_score - 5 * (0.9, submit_times - 1);
    final_time = AC ? (last_submit_time + 1200s * (submit_times - 1)) : 1200s * submit_times; '; 136 | else if($judge_way==2) 137 | return _('Final score is the sum of the scores of SOLVED problems. Time Penalty records the latest submit time for SOLVED problems and 1200s for unsolved problems.').'
    final_score = (max_score == full_score) ? full_score : 0;
    final_time = AC ? last_submit_time + 1200s * (submit_times - 1) : 1200s * submit_times; '; 138 | else if($judge_way==3) 139 | return _('Final score is the sum of the score of the FIRST submit of each problem. Time Penalty is the sum of the FIRST submit time of each problem.').'
    final_score = first_submit_score;
    final_time = first_submit_time; '; 140 | } 141 | 142 | //Generate time countdown text. 143 | function get_time_text($time){ 144 | $hour=intval($time/3600); 145 | if($hour<10) 146 | $hour='0'.$hour; 147 | $min=intval(($time-3600*$hour)/60); 148 | if($min<10) 149 | $min='0'.$min; 150 | $sec=$time-3600*$hour-60*$min; 151 | if($sec<10) 152 | $sec='0'.$sec; 153 | $ret="$hour:$min:$sec"; 154 | return $ret; 155 | } 156 | -------------------------------------------------------------------------------- /web/public/func/cookie.php: -------------------------------------------------------------------------------- 1 | 'codgic'); 28 | $arr['user']=$_SESSION['user']; 29 | 30 | $data = encrypt(COOKIE_KEY, serialize($arr)); 31 | if($remember==1) 32 | setcookie('SID', $data, time()+COOKIE_EXPIRE, '/', BIND_DOMAIN); 33 | else 34 | setcookie('SID', $data, 0, '/', BIND_DOMAIN); 35 | } 36 | 37 | //Clear certain cookie. 38 | function clear_cookie($name){ 39 | setcookie("$name",'',time()-3600, '/', BIND_DOMAIN); 40 | } 41 | 42 | //Encrypt cookie. 43 | function encrypt($key, $plain_text){ 44 | $iv='7284565820000000'; 45 | $key=hash('sha256',$key,true); 46 | return openssl_encrypt($plain_text,'aes-256-cbc',$key,false,$iv); 47 | } 48 | 49 | //Decrypt cookie. 50 | function decrypt($key, $c_t){ 51 | $iv='7284565820000000'; 52 | $key=hash('sha256',$key,true); 53 | return openssl_decrypt($c_t,'aes-256-cbc',$key,false,$iv); 54 | } 55 | -------------------------------------------------------------------------------- /web/public/func/preferences.php: -------------------------------------------------------------------------------- 1 | hidehotkey='off'; 11 | $this->night='auto'; 12 | $this->sharecode='off'; 13 | $this->edrmode='default'; 14 | } 15 | } -------------------------------------------------------------------------------- /web/public/func/privilege.php: -------------------------------------------------------------------------------- 1 | start_time and NOW() 0){ 40 | $accessible = false; 41 | while ($row = mysqli_fetch_row($res)){ 42 | if (!is_null($row[1])) 43 | $accessible = true; 44 | } 45 | if($accessible) 46 | { 47 | return TRUE; 48 | } 49 | else 50 | { 51 | return _('You can\'t see me before the contest ends'); 52 | } 53 | } 54 | return TRUE; 55 | } 56 | } 57 | return _('Looks like you can\'t access this page'); 58 | } 59 | -------------------------------------------------------------------------------- /web/public/func/text.php: -------------------------------------------------------------------------------- 1 | ', ' '); 5 | 6 | $result = preg_replace($find, $replace, $string); 7 | 8 | return $result; 9 | } -------------------------------------------------------------------------------- /web/public/func/userlogin.php: -------------------------------------------------------------------------------- 1 | $property=$r[1]; 45 | } 46 | $_SESSION['pref']=serialize($pref); 47 | 48 | require __DIR__ . '/../../src/userinfo.php'; 49 | $ip=mysqli_escape_string($con,get_ip()); 50 | mysqli_query($con,"update users set accesstime=NOW(),ip='$ip' where user_id='$user'"); 51 | 52 | return TRUE; 53 | } 54 | -------------------------------------------------------------------------------- /web/public/inc/403.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 |
    18 |
    19 |
    20 |

    21 | 22 |

    23 |

    24 | ERROR 403 25 |
    26 | 27 |

    28 |
    29 |
    30 |
    31 | 32 |
    33 | 34 | 35 | -------------------------------------------------------------------------------- /web/public/inc/404.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 |
    18 |
    19 |
    20 |

    21 | 22 |

    23 |

    24 | ERROR 404 25 |
    26 | 27 |

    28 |
    29 |
    30 |
    31 | 32 |
    33 | 34 | 35 | -------------------------------------------------------------------------------- /web/public/inc/footer.php: -------------------------------------------------------------------------------- 1 | 5 |
    6 |
    7 |

    8 |
    9 | -------------------------------------------------------------------------------- /web/public/inc/head.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | <?php echo $Title?> 18 | 22 | 26 | 27 | 28 | 33 | 38 | 39 | -------------------------------------------------------------------------------- /web/public/inc/init.php: -------------------------------------------------------------------------------- 1 | 12 | 15 | -------------------------------------------------------------------------------- /web/public/index.php: -------------------------------------------------------------------------------- 1 | 0 and privilege=0 order by importance desc, news_id desc limit 0,$news_num"); 12 | else{ 13 | $i=$_SESSION['priv']; 14 | $res=mysqli_query($con,"select news_id,title,importance from news where news_id>0 and ((privilege & $i)<>0 or privilege=0) order by importance desc, news_id desc limit 0,$news_num"); 15 | } 16 | $row=mysqli_fetch_row(mysqli_query($con,"select content from user_notes where problem_id=0 limit 1")); 17 | $category=$row[0]; 18 | 19 | $inTitle=_('Home'); 20 | $Title=$inTitle .' - '. $oj_name; 21 | $num=0; 22 | ?> 23 | 24 | 25 | 26 | 27 | 28 |
    29 |
    30 |
    31 |
    32 |
    33 |
    34 | 35 |
    36 |
    37 |
    38 |
    39 |
    40 |
    41 |

    42 | 43 | 47 | 48 | 49 | ... 50 | 51 | 52 |

    53 | 68 | 69 |
    70 |

    71 |

    72 | Whoops 73 |
    74 | 75 |

    76 |
    77 | 78 |
    79 |
    80 |

    81 |
    82 | 87 |
    88 |

    89 |

    90 | Whoops 91 |
    92 | 93 |

    94 |
    95 | 96 |
    97 |
    98 |
    99 | 100 |
    101 | 102 | 120 | 121 | 122 | 144 | 145 | -------------------------------------------------------------------------------- /web/public/lib/lang.php: -------------------------------------------------------------------------------- 1 | 'GNU C++', 4 | 1 => 'GNU C', 5 | 3 => 'GNU C++11', 6 | 6 => 'QBASIC', 7 | ); 8 | 9 | static $LANG_EXT=array( 10 | 0 => 'cpp', 11 | 1 => 'c', 12 | 3 => 'cpp', 13 | 7 => 'bas', 14 | ); 15 | -------------------------------------------------------------------------------- /web/public/lib/mail_flags.php: -------------------------------------------------------------------------------- 1 | 2 | MathJax.Hub.Config({ 3 | extensions: ["tex2jax.js"], 4 | jax: ["input/TeX", "output/HTML-CSS"], 5 | tex2jax: { 6 | inlineMath: [ ['[inline]','[/inline]'] ], 7 | displayMath: [ ["[tex]","[/tex]"] ], 8 | processEscapes: true 9 | }, 10 | "HTML-CSS": { availableFonts: ["TeX"], webFont: "TeX", imageFont: null } 11 | }); 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /web/public/lib/mutex.php: -------------------------------------------------------------------------------- 1 | use_sysv=extension_loaded("sysvsem"); 7 | if($this->use_sysv){ 8 | $key=crc32($lock_file); 9 | $this->resource=sem_get($key, 1); 10 | if(!$this->resource || !sem_acquire($this->resource)) 11 | die('Could not get lock'); 12 | }else{ 13 | $i=0; 14 | while(!($this->resource=fopen($lock_file,'w+'))){ 15 | usleep(50000); 16 | $i++; 17 | if($i>10) 18 | die('Lock wait timeout exceeded'); 19 | } 20 | if(!flock($this->resource,LOCK_EX)){ 21 | fclose($this->resource); 22 | die('Could not get lock'); 23 | } 24 | } 25 | } 26 | 27 | public function release_mutex(){ 28 | if($this->use_sysv){ 29 | sem_release($this->resource); 30 | //sem_remove($this->resource); 31 | }else{ 32 | flock($this->resource, LOCK_UN); 33 | fclose($this->resource); 34 | } 35 | } 36 | 37 | public function __destruct(){ 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /web/public/lib/problem_flags.php: -------------------------------------------------------------------------------- 1 | 'Accepted', 4 | 7 => 'Compile Error', 5 | 2 => 'Time Out', 6 | 3 => 'Memory Exceeded', 7 | 4 => 'Wrong Answer', 8 | 5 => 'Runtime Error', 9 | 6 => 'Wrong Answer',//'Output Limit Exceed', 10 | 1 => 'Wrong Answer',//'Presentation Error', 11 | 99 => 'Validator Error', 12 | 100 => 'System Error'//'System Error', 13 | ); 14 | 15 | static $RESULT_STYLE=array( 16 | 0 => 'label-ac', 17 | 7 => 'label-ce', 18 | 2 => 'label-le', 19 | 3 => 'label-le', 20 | 4 => 'label-wa', 21 | 5 => 'label-re', 22 | 6 => 'label-le',//'Output Limit Exceed', 23 | 1 => 'label-wa',//'Presentation Error', 24 | 99 => 'label-ve', 25 | 100 => 'label-ve'//'System Error', 26 | ); 27 | -------------------------------------------------------------------------------- /web/public/lib/tgz.lib.php: -------------------------------------------------------------------------------- 1 | tar_size = 0; 6 | $this->file = $_file; 7 | $this->create_time = time(); 8 | 9 | //gzip header 10 | fwrite($this->file, "\x1F\x8B\x08\x00".pack("V",$this->create_time)."\x00\x03"); 11 | 12 | $this->filter=stream_filter_append($this->file,'zlib.deflate',STREAM_FILTER_WRITE, -1); 13 | $this->hctx=hash_init('crc32b'); 14 | } 15 | private function calc_sum($tar_header){ 16 | $chksum=0; 17 | for($i=0;$i<512;$i++){ 18 | $chksum+=ord($tar_header{$i}); 19 | } 20 | 21 | return decoct($chksum); 22 | } 23 | private function str_modify(&$old, $pos, $new){ 24 | $len = strlen($new); 25 | 26 | for($i=0; $i<$len; $i++) 27 | $old[$pos++] = $new[$i]; 28 | } 29 | public function AddFile($name, $content){ 30 | if(strlen($name)>100) 31 | return FALSE; 32 | $length=strlen($content); 33 | 34 | $buf=str_pad($name,100,"\x00"); 35 | $buf.=str_pad('0000644',8,"\x00"); 36 | $buf.=str_pad('0001750',8,"\x00"); //uid 1000 37 | $buf.=str_pad('0001750',8,"\x00"); //gid 1000 38 | $buf.=str_pad(decoct($length),12,"\x00"); //size 39 | $buf.=str_pad(decoct($this->create_time), 12, "\x00"); //mtime 40 | $buf.="\x20\x20\x20\x20\x20\x20\x20\x20"; //chksum 41 | $buf.="\x30"; //flag 42 | $buf.=str_repeat("\0",100); //linkname 43 | $buf.='ustar '; //magic 44 | $buf.="\x20\x00"; //version GNU tar 45 | $buf.=str_pad('php',32,"\x00"); //uname 46 | $buf.=str_pad('php',32,"\x00"); //gname 47 | 48 | $buf.=str_repeat("\0",16); //dev 49 | $buf.=str_repeat("\0",155); //prefix 50 | $buf.=str_repeat("\0",12); //padding 51 | 52 | //write checksum 53 | $this->str_modify($buf, 148, $this->calc_sum($buf)); 54 | 55 | $align=($length+511)&(~511); // 512 bytes align 56 | $buf.=$content; 57 | $buf.=str_repeat("\0",$align-$length); 58 | 59 | fwrite($this->file, $buf); 60 | hash_update($this->hctx, $buf); 61 | $this->tar_size += strlen($buf); 62 | 63 | return TRUE; 64 | } 65 | // public function test_string($str){ 66 | // fwrite($this->file, $str); 67 | // hash_update($this->hctx, $str); 68 | // $this->tar_size += strlen($str); 69 | // } 70 | public function Close(){ 71 | $pad=str_repeat("\0",1024); 72 | fwrite($this->file, $pad); 73 | $this->tar_size += 1024; 74 | hash_update($this->hctx, $pad); 75 | 76 | stream_filter_remove($this->filter); 77 | $crc=hash_final($this->hctx, TRUE); 78 | fwrite($this->file, $crc[3].$crc[2].$crc[1].$crc[0], 4); 79 | fwrite($this->file, pack("V", $this->tar_size), 4); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /web/public/locale/zh_CN/LC_MESSAGES/main.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codgic/codgic-web-legacy/f5704d342b6abeb203db4ca26fe850018f4e3c8a/web/public/locale/zh_CN/LC_MESSAGES/main.mo -------------------------------------------------------------------------------- /web/public/login.php: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 |
    18 |
    19 | 55 |
    56 |
    57 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /web/public/news.php: -------------------------------------------------------------------------------- 1 | 0 and privilege=0"; 17 | $newsq="select news_id,title,time,importance from news where news_id>0 and privilege=0 order by importance desc, news_id desc limit ".(($page_id-1)*20).",20"; 18 | }else{ 19 | $maxq="select count(news_id) from news where news_id>0 and ((privilege & ".$_SESSION['priv'].")<>0 or privilege=0)"; 20 | $newsq="select news_id,title,time,importance from news where news_id>0 and ((privilege & ".$_SESSION['priv'].")<>0 or privilege=0) order by importance desc, news_id desc limit ".(($page_id-1)*20).",20"; 21 | } 22 | 23 | if($row=mysqli_fetch_row(mysqli_query($con,$maxq))) 24 | $maxpage=intval($row[0]/20)+1; 25 | else 26 | $maxpage=1; 27 | $res=mysqli_query($con,$newsq); 28 | } 29 | 30 | $inTitle=_('News'); 31 | $Title=$inTitle .' - '. $oj_name; 32 | ?> 33 | 34 | 35 | 36 | 37 | 38 | 39 |
    40 |
    41 |
    42 |
    43 | 44 |
    45 |

    46 |

    47 | Whoops 48 |
    49 | 50 |

    51 |
    52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | '; 69 | $addt2=''; 70 | } 71 | echo ''; 72 | echo ''; 73 | echo ''; 74 | echo "\n"; 75 | } 76 | ?> 77 | 78 |
    No.
    ',htmlspecialchars($row[0]),'',$addt1.htmlspecialchars($row[1]).$addt2,'',htmlspecialchars($row[2]),'
    79 | 80 |
    81 |
    82 | 96 | 97 |
    98 | 99 | 118 | 119 | 120 | 142 | 143 | -------------------------------------------------------------------------------- /web/public/proxy.php: -------------------------------------------------------------------------------- 1 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
    40 |
    41 | 42 |
    43 |
    44 |

    45 |

    46 | Whoops 47 |
    48 | 49 |

    50 |
    51 |
    52 | 53 |
    54 |

    55 |
    56 |
    57 |
    58 |
    59 | 60 | 61 |
    62 |
    63 |
    64 |
    65 |
    66 |
    67 |
    68 |
    69 |
    70 |
    71 | 72 | 73 |
    74 |
    75 |
    76 | 78 |
    79 | 80 | 81 | 82 | 83 | 84 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /web/public/upload.php: -------------------------------------------------------------------------------- 1 | 0) 13 | echo _('Error: '.$_FILES["file"]["error"]); 14 | 15 | $filename=isset($_POST['savename']) ? $_POST['savename'] : date('YmdHis_').mt_rand(10000,99999); 16 | if(!strlen($filename) || preg_match('/[^-)(\w]/',$filename)) 17 | echo _("Invalid File name..."); 18 | 19 | $tmp = explode('.', $filename); 20 | $file_extension = end($tmp); 21 | 22 | if(file_exists(OJDIR."/images/$filename")) 23 | echo _('File '),"'$filename'",_(' exists already, try another name...'); 24 | if(!is_dir(OJDIR."/images")) 25 | if(!mkdir(OJDIR."/images",0770)) 26 | echo _('Can\'t access upload directory...'); 27 | 28 | if(move_uploaded_file($_FILES["file"]["tmp_name"],OJDIR."/images/$filename")){ 29 | $imgtag="img src=\"/images/$filename\""; 30 | }else 31 | echo _('Upload Failed!'); 32 | }catch(Exception $e){ 33 | $info=$e->getMessage(); 34 | } 35 | }else{ 36 | $filename=date('YmdHis_').mt_rand(10000,99999); 37 | if(isset($_GET['id'])) 38 | $filename=intval($_GET['id']); 39 | } 40 | 41 | $inTitle=_('Upload'); 42 | $Title=$inTitle .' - '. $oj_name; 43 | ?> 44 | 45 | 46 | 47 | 48 | 49 |
    50 |
    51 |
    52 | 53 |

    54 | 55 |

    56 |
    57 |
    58 |
    59 | 60 |
    61 |
    62 | 63 | <> 64 | 65 |
    66 |
    67 |

    68 | 69 | 70 |

    71 | 72 |

    73 | 74 |

    75 |
    76 |
    77 | 78 | 79 |

    80 | 81 |

    82 |
    83 |
    84 |
    85 | 88 | 89 |
    90 |
    91 | 94 | 95 |
    96 |
    97 |
    98 | 99 |
    100 |
    101 | 102 |
    103 |
    104 |
    105 | 106 | 107 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /web/src/database.php: -------------------------------------------------------------------------------- 1 | CharSet ="UTF-8"; 25 | $mail->Encoding ="base64"; 26 | $mail->IsSMTP(); 27 | //$mail->SMTPDebug = 0; // 2 - DISABLE 28 | $mail->SMTPAuth = true; 29 | $mail->SMTPSecure = "ssl"; 30 | $mail->Host = SMTP_SERVER; //SMTP Server Address 31 | $mail->Port = SMTP_PORT; //SMTP Service Port 32 | $mail->Username = SMTP_USER; //Input your admin email 33 | $mail->Password = SMTP_PASSWORD; //Input your email password. 34 | $mail->SetFrom(SMTP_USER, SMTP_DISPLAY); 35 | $mail->AddReplyTo(SMTP_USER, SMTP_DISPLAY); 36 | $mail->Subject = $subject; 37 | $mail->WordWrap = 60; 38 | //$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional, comment out and test 39 | $mail->MsgHTML($body); 40 | $address = $to; 41 | $mail->AddAddress($address, ''); 42 | $mail->IsHTML(true); 43 | if(!$mail->Send()) { 44 | return $mail->ErrorInfo; 45 | } else { 46 | return 'success'; 47 | } 48 | } 49 | 50 | /** 51 | * 2. Functions 52 | * ---------------- 53 | * Here are various email generating functions you may would like to customize. 54 | */ 55 | 56 | //Generate Password Reset Email. 57 | function resetpwd_mail(){ 58 | require __DIR__.'/ojsettings.php'; 59 | if(!isset($_SESSION['resetpwd_user']) || !isset($_SESSION['resetpwd_email']) || !isset($_SESSION['resetpwd_code'])) 60 | return 'timeout'; 61 | $user = $_SESSION['resetpwd_user']; 62 | $email = $_SESSION['resetpwd_email']; 63 | $code = $_SESSION['resetpwd_code']; 64 | $subject = "$oj_name 密码重置验证"; 65 | require __DIR__.'/userinfo.php'; 66 | $ip = get_ip(); 67 | $nowtime = date("Y/m/d H:i:s"); 68 | $content = "
    亲爱的 $user ,

    我们收到了您在 {$constant('OJ_NAME')} 重置密码的请求并发送了验证码来确认您的身份。

    请求时间: $nowtime (UTC+08:00)

    IP地址: $ip

    验证码: $code

    如果您没有在 {$constant('OJ_NAME')} 有过重置密码的请求,您只需忽略这封邮件并不要把验证码告诉任何人。
    如有任何问题,请回复该邮件来与管理员取得联系。


    谢谢!

    {$constant('OJ_COPYRIGHT')}

    "; 69 | return postmail($email,$subject,$content); 70 | } 71 | -------------------------------------------------------------------------------- /web/src/mathjax.php: -------------------------------------------------------------------------------- 1 | 4 | 16 | 17 | 18 | MATHJAX_INLINE_BEGIN, 8 | 'end' => MATHJAX_INLINE_END 9 | ], [ 10 | 'begin' => MATHJAX_TEX_BEGIN, 11 | 'end' => MATHJAX_TEX_END 12 | ] 13 | ]); 14 | 15 | function parse_markdown($text) { 16 | $replaced_text = $text; 17 | $replace_list = []; 18 | foreach (MARKDOWN_PRESERVE as $preserve_obj) { 19 | $delimiter = '/'; 20 | $pregex = $delimiter . preg_quote($preserve_obj['begin'], $delimiter) . 21 | '[\s\S]*?' . preg_quote($preserve_obj['end'], $delimiter) . $delimiter .'iu'; 22 | $replaced_text = preg_replace_callback($pregex, function($matches) use (&$replace_list) { 23 | $token = uniqid('p_placeholder_'); 24 | $replace_list[$token] = $matches[0]; 25 | return $token; 26 | }, $replaced_text); 27 | } 28 | 29 | $parsedown = new ParsedownExtra(); 30 | $replaced_text = $parsedown->text($replaced_text); 31 | 32 | foreach($replace_list as $token => $text) { 33 | $replaced_text = str_replace($token, $text, $replaced_text); 34 | } 35 | return $replaced_text; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /web/src/userinfo.php: -------------------------------------------------------------------------------- 1 |