之前对学长的计分板进行了二次开发,最近要准备办招新赛和校赛,需要团队模式,一看团队模式之前的计分板插件完全用不了了,索性直接推倒重构。
首先就是对standings的处理,原先学长的方法是通过多层嵌套循环查询数据表来获得数据,只能说确实能跑起来。我们直接把数据库查询都单独拿出循环外面,然后循环内只处理数据,能优化不少性能,代码修改如下:
1 |
|
把所有排名数据只通过一个JSON对象返回模板引擎进行渲染,干净多了,另外也实现了个人赛时给新生加分和ctfd的award加分计算。
另外一部分就是对于challenges这个对象的处理,因为原先写了很多判断,分到各个类别需要很多if,这里我们用字典的形式优化下处理方法:
1 |
|
这不就干净多了?然后再稍微改下处理get请求的地方:
1 |
|
这不就好了?
当然,重构了后端函数之后,前端的渲染方式也需要重写,我们将scoreboard的模板移动到templates目录下方便动态加载(原来学长写的是用的override覆盖的模板。。):
首先就是表头类别的处理,既然改成了动态渲染表头,那么就改成这样写:
<thead>
<tr>
<th rowspan="3" style="border-top: 0"><b>{{"Place" if en else "排名"}}</b>
</th>
{% if get_config('user_mode') == 'teams' %}
<th rowspan="3" style="text-align: center;border-top: 0"><b>{{"Team" if en else "队伍名称"}}</b>
</th>
{% else %}
<th rowspan="3" style="text-align: center;border-top: 0"><b>{{"Username" if en else "用户昵称"}}</b>
</th>
{% endif %}
<th rowspan="3" class="right-line" style="border-top: 0"><b>{{"Score" if en else "得分"}}</b>
</th>
{% for cat in categories %}
<th data-halign="center" class="table-category-header" data-align="center" colspan="{% if loop.last %}{{ cat.count + 2 }}{% else %}{{ cat.count }}{% endif %}" style="text-align: center;background-color: {{color_hash(cat.category)}};">
<b>{{ cat.category }}</b>
</th>
{% endfor %}
<th data-halign="center" class="table-category-header" data-align="center" colspan="4" style="text-align: center;background-color: {{color_hash('奖项')}};">
<b>{{"Award" if en else "奖项"}}</b>
</th>
</tr>
<tr>
{% for chal in challenges %}
<div>
<th class="chalname" title="{{ chal.category }}">
<div><span>{{ chal.name }}</span></div>
</th>
</div>
{% endfor %}
<div>
<th class="chalname right-line" colspan="2">
<div><span></span></div>
</th>
</div>
<div>
<th class="right-line" style="border-bottom: 0;vertical-align: bottom;padding-bottom: 0;horiz-align: center" colspan="2">
<div><span>{{"Award" if en else "奖励"}}</span></div>
</th>
</div>
</tr>
<tr>
{% for chal in challenges %}
<div>
<th width="10%" class="score" title="{{ chal.category }}">
<div><span>{{ chal.value }}</span></div>
</th>
</div>
{% endfor %}
<div>
<th width="10%" class="score right-line" colspan="2">
<div><span></span></div>
</th>
</div>
<div>
<th width="10%" class="score right-line" style="border-top: 0;vertical-align: top;padding-top: 0;horiz-align: center" colspan="2">
<div><span>{{"Score" if en else "分数"}}</span></div>
</th>
</div>
</tr>
</thead>
这里的colorhash是一个全局定义的python函数:
1 |
|
然后表格内容直接使用standings进行渲染:
<tbody>
{% for team in standings %}
<tr>
<td class="left-line">{{ loop.index }}</td>
<td ><a href="{{ request.script_root }}/{{ mode }}/{{ team.id }}" target="_blank">{{ team.name }}</a></td>
<td class="right-line">{{ team.total_score }}</td>
{% for chal in challenges %}
<td class="chalmark">
{% for solved_challenge in team.challenge_solved %}
{% if solved_challenge.challenge_id == chal.id %}
{% set rank = solved_challenge.rank %}
{% if rank == 1 %}
<img src="/plugins/matrix/static/medal1.png" width="100%" height="100%">
{% elif rank == 2 %}
<img src="/plugins/matrix/static/medal2.png" width="100%" height="100%">
{% elif rank == 3 %}
<img src="/plugins/matrix/static/medal3.png" width="100%" height="100%">
{% else %}
<img src="/plugins/matrix/static/flag.png" width="100%" height="100%">
{% endif %}
{% endif %}
{% endfor %}
</td>
{% endfor %}
<td class="chalmark" colspan="2">
</td>
<td class="chalmark left-line right-line" colspan="2">
{{ team.award_value }}
</td>
</tr>
{% endfor %}
</tbody>
这样就好了,修复了之前最后一列过小的问题,加入了奖励分数和额外加分项的计算和渲染,优化了视觉效果和计算性能,完活下机!
项目地址:https://github.com/IShiraiKurokoI/CTFd-Matrix-Scoreboard