diff --git a/packages/hydrooj/src/handler/contest.ts b/packages/hydrooj/src/handler/contest.ts index 73b8c1fd..aaff7eb7 100644 --- a/packages/hydrooj/src/handler/contest.ts +++ b/packages/hydrooj/src/handler/contest.ts @@ -224,8 +224,10 @@ export class ContestDetailHandler extends Handler { @param('code', Types.String, true) async postAttend(domainId: string, tid: ObjectID, code = '') { if (contest.isDone(this.tdoc)) throw new ContestNotLiveError(tid); - if (this.tdoc._code && code !== this.tdoc._code) throw new InvalidTokenError('Contest Invitation', code); + if (this.tdoc._code && code !== this.tdoc._code && !this.tdoc.uninvite) throw new InvalidTokenError('Contest Invitation', code); await contest.attend(domainId, tid, this.user._id); + if (this.tdoc.unrankUser.includes(this.user._id) + || (this.tdoc._code && code !== this.tdoc._code && this.tdoc.uninvite)) contest.setStatus(domainId, tid, this.user._id, { unrank: true }); this.back(); } } @@ -412,11 +414,14 @@ export class ContestEditHandler extends Handler { @param('assign', Types.CommaSeperatedArray, true) @param('lock', Types.UnsignedInt, true) @param('contestDuration', Types.Float, true) + @param('maintainer', Types.NumericArray, true) + @param('uninvite', Types.Boolean, true) + @param('allowViewCode', Types.Boolean, true) async postUpdate( domainId: string, tid: ObjectID, beginAtDate: string, beginAtTime: string, duration: number, title: string, content: string, rule: string, _pids: string, rated = false, _code = '', autoHide = false, assign: string[] = null, lock: number = null, - contestDuration: number = null, + contestDuration: number = null, maintainer: number[] = null, uninvite = false, allowViewCode = true, ) { if (autoHide) this.checkPerm(PERM.PERM_EDIT_PROBLEM); const pids = _pids.replace(/,/g, ',').split(',').map((i) => +i).filter((i) => i); @@ -457,7 +462,7 @@ export class ContestEditHandler extends Handler { }); } await contest.edit(domainId, tid, { - assign, _code, autoHide, lockAt, + assign, _code, autoHide, lockAt, maintainer, uninvite, allowViewCode, }); this.response.body = { tid }; this.response.redirect = this.url('contest_detail', { tid }); diff --git a/packages/ui-default/templates/contest_detail.html b/packages/ui-default/templates/contest_detail.html index 46ed8036..ce5e1bce 100644 --- a/packages/ui-default/templates/contest_detail.html +++ b/packages/ui-default/templates/contest_detail.html @@ -35,6 +35,11 @@

{{ _('The contest is a flexible time contest. You need to complete the contest within a specified time after you attended.') }}

{% endif %} + {% if tdoc.code and tdoc.uninvite %} +
+

{{ _('The contest is a invitational contest. However it allow users attend contest without the invitation code. Those users will not be ranked.') }}

+
+ {% endif %} diff --git a/packages/ui-default/templates/contest_edit.html b/packages/ui-default/templates/contest_edit.html index 276232ef..e41b168f 100644 --- a/packages/ui-default/templates/contest_edit.html +++ b/packages/ui-default/templates/contest_edit.html @@ -73,7 +73,7 @@ }) }} {{ form.form_textarea({ columns:null, - label:'Content', + label:'Description', name:'content', value:tdoc['content']|default(''), markdown:true @@ -117,7 +117,7 @@ - -
- {{ form.form_text({ - columns:9, - label:'UnRank User', - name:'unrankUser', - help_text:_('User who will not show rank in scoreboard'), - value:tdoc.unrankUser|default(''), - row:false - }) }} -