bug fixes

This commit is contained in:
undefined committed 2024-06-27 03:58:29 +08:00
1 parent 16b6f53653
commit 84f7d5dc80
20 files changed
+43 -35

No files matched your search

+2 -1
View File
@@ -137,11 +137,12 @@ Hydro 用户群:1085853538
- serializer: 移除 showDisplayName 参数
- 移除了 loader.addScript, loader.addon 函数
- 移除了 Hydro.module.render (请使用 ctx.server.registerRenderer)
- 移除了 lib/paginate 和 lib/rank (请使用 db.paginate 和 db.ranked)
### Hydro 4.12.3 / UI 4.50.2
- core: 将 API 模块移入 service
- core: 比赛时提交被 hack 不触发整体重测
- core: 将添加 pid match 的逻辑移入搜索中
- core: 将添加 pid match 的逻辑移入搜索中
- ui: 修正 cssFilter
- judge: builtin: 维护 callback 顺序
- core: 优化邮件地址处理
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@hydrooj/hydrojudge",
"bin": "bin/hydrojudge.js",
"version": "3.3.14",
"version": "3.3.15",
"main": "./src/index.ts",
"author": "undefined <i@undefined.moe>",
"repository": "https://github.com/hydro-dev/Hydro.git",
+1 -1
View File
@@ -99,7 +99,7 @@ export async function postInit(ctx) {
function collectCompilerInfo() {
const coll = db.collection('status');
compilerVersions(langs).then((compilers) => coll.updateOne(
{ mid: info.mid, type: 'judge' },
{ mid: info.mid, type: 'server' },
{ $set: { compilers } },
{ upsert: true },
)).catch((e) => logger.error(e));
+6 -1
View File
@@ -175,6 +175,7 @@ export default class Hydro implements Session {
? JSON.stringify({ key: 'config', ...config })
: '{"key":"ping"}';
let compilers = {};
let compilerVersionCallback = () => { };
this.ws.on('message', (data) => {
if (data.toString() === 'ping') {
this.ws.send('pong');
@@ -185,6 +186,7 @@ export default class Hydro implements Session {
this.language = request.language;
compilerVersions(this.language).then((res) => {
compilers = res;
compilerVersionCallback();
});
}
if (request.task) queue.add(() => new JudgeTask(this, request.task).handle().catch((e) => log.error(e)));
@@ -203,7 +205,10 @@ export default class Hydro implements Session {
this.ws.send('{"key":"start"}');
if (!this.config.noStatus) {
const info = await sysinfo.get();
this.ws.send(JSON.stringify({ key: 'status', info: { ...info, compilers } }));
this.ws.send(JSON.stringify({ key: 'status', info: { ...info } }));
compilerVersionCallback = () => {
this.ws.send(JSON.stringify({ key: 'status', info: { ...info, compilers } }));
};
setInterval(async () => {
const [mid, inf] = await sysinfo.update();
this.ws.send(JSON.stringify({ key: 'status', info: { mid, ...inf, compilers } }));
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "4.13.0",
"version": "4.13.1",
"bin": "bin/hydrooj.js",
"main": "src/plugin-api",
"module": "src/plugin-api",
+1
View File
@@ -274,6 +274,7 @@ SystemSetting(
Setting('setting_basic', 'pagination.contest', 20, 'number', 'pagination.contest', 'Contests per page'),
Setting('setting_basic', 'pagination.discussion', 50, 'number', 'pagination.discussion', 'Discussions per page'),
Setting('setting_basic', 'pagination.record', 100, 'number', 'pagination.record', 'Records per page'),
Setting('setting_basic', 'pagination.ranking', 100, 'number', 'pagination.ranking', 'Users per page'),
Setting('setting_basic', 'pagination.solution', 20, 'number', 'pagination.solution', 'Solutions per page'),
Setting('setting_basic', 'pagination.training', 10, 'number', 'pagination.training', 'Trainings per page'),
Setting('setting_basic', 'pagination.reply', 50, 'number', 'pagination.reply', 'Replies per page'),
@@ -1,4 +1,4 @@
import { KoaContext } from '@hydrooj/framework';
import { KoaContext, NotFoundError } from '@hydrooj/framework';
import BlackListModel from '../../model/blacklist';
import DomainModel from '../../model/domain';
import * as system from '../../model/system';
@@ -24,5 +24,12 @@ export default async (ctx: KoaContext, next) => {
ctx.domainId = inferDomain?._id || domainId;
ctx.domainInfo = inferDomain || absoluteDomain;
if (ctx.domainInfo && ctx.domainId !== ctx.domainInfo._id) ctx.redirect(ctx.originalPath.replace(/^\/d\/[^/]+\//, `/d/${ctx.domainInfo._id}/`));
else await next();
else {
if (!ctx.domainInfo) {
ctx.pendingError = new NotFoundError(ctx.domainId);
ctx.domainId = 'system';
ctx.domainInfo = await DomainModel.get('system');
}
await next();
}
};
@@ -1,5 +1,4 @@
import type { KoaContext } from '@hydrooj/framework';
import { NotFoundError } from '../../error';
import { PERM } from '../../model/builtin';
import UserModel from '../../model/user';
@@ -15,9 +14,5 @@ export default async (ctx: KoaContext, next) => {
}
if (user._id === 0) delete user.viewLang;
ctx.HydroContext.user = await user.private();
if (!domain) {
ctx.pendingError = new NotFoundError(args.domainId);
args.domainId = 'system';
}
await next();
};
+1
View File
@@ -276,6 +276,7 @@ export async function apply(ctx: Context) {
text: global.Hydro.module.oauth[key].text,
}));
if (!h.noCheckPermView && !h.user.hasPriv(PRIV.PRIV_VIEW_ALL_DOMAIN)) h.checkPerm(PERM.PERM_VIEW);
if (h.context.pendingError) throw h.context.pendingError;
});
on('app/listen', () => {
@@ -89,6 +89,7 @@ export default function (env: { watch?: boolean, production?: boolean, measure?:
output: {
path: root('public'),
publicPath: '/', // overwrite in entry.js
workerPublicPath: '/',
hashFunction: 'sha1',
hashDigest: 'hex',
hashDigestLength: 10,
+4 -1
View File
@@ -49,7 +49,10 @@ async function runWebpack({
return;
}
if (argv.options.detail) console.log(stats.toString());
if (!watch && (!stats || stats.hasErrors())) process.exitCode = 1;
if (!watch && (!stats || stats.hasErrors())) {
if (!argv.options.detail) console.log(stats.toString());
process.exitCode = 1;
}
resolve(stats);
}
if (watch) compiler.watch({}, compilerCallback);
@@ -24,9 +24,8 @@ const Component = React.forwardRef<any, any>((props, ref) => {
);
});
export default class CustomSelectAutoComplete<Multi extends boolean> extends AutoComplete {
export default class CustomSelectAutoComplete<Multi extends boolean> extends AutoComplete<CustomSelectOptions> {
static DOMAttachKey = 'ucwCustomSelectAutoCompleteInstance';
options: CustomSelectOptions & AutoCompleteOptions;
constructor($dom, options: CustomSelectOptions & AutoCompleteOptions<Multi>) {
super($dom, {
@@ -27,9 +27,8 @@ const Component = React.forwardRef<any, any>((props, ref) => {
);
});
export default class FileSelectAutoComplete<Multi extends boolean> extends AutoComplete {
export default class FileSelectAutoComplete<Multi extends boolean> extends AutoComplete<FileSelectOptions> {
static DOMAttachKey = 'ucwFileSelectAutoCompleteInstance';
options: FileSelectOptions & AutoCompleteOptions;
constructor($dom, options: FileSelectOptions & AutoCompleteOptions<Multi>) {
super($dom, {
@@ -8,6 +8,7 @@ export interface AutoCompleteOptions<Multi extends boolean = boolean> {
defaultItems?: string;
width?: string;
height?: string;
classes?: string;
listStyle?: any;
allowEmptyQuery?: boolean;
freeSolo?: boolean;
@@ -18,17 +19,17 @@ export interface AutoCompleteOptions<Multi extends boolean = boolean> {
text?: () => string;
}
export default class AutoComplete extends DOMAttachedObject {
export default class AutoComplete<Options extends Record<string, any> = {}> extends DOMAttachedObject {
static DOMAttachKey = 'ucwAutoCompleteInstance';
ref = null;
container = document.createElement('div');
options: AutoCompleteOptions;
options: AutoCompleteOptions & Options;
component = ReactDOM.createRoot(this.container);
changeListener = [
(val) => this.$dom.val(val),
];
constructor($dom, options = {}) {
constructor($dom, options = {} as Options) {
super($dom);
this.options = {
items: async () => [],
@@ -1,5 +1,4 @@
import { nanoid } from 'nanoid';
import ReconnectingWebsocket from 'reconnecting-websocket';
import { InfoDialog } from 'vj/components/dialog';
import VjNotification from 'vj/components/notification/index';
import {
@@ -7,6 +6,7 @@ import {
} from 'vj/constant/message';
import { AutoloadPage } from 'vj/misc/Page';
import { i18n, tpl } from 'vj/utils';
import Sock from '../socket';
let previous: VjNotification;
const onmessage = (msg) => {
@@ -128,12 +128,8 @@ const messagePage = new AutoloadPage('messagePage', (pagename) => {
isMaster = true;
localStorage.setItem('page.master', selfId);
const masterChannel = new BroadcastChannel('hydro-messages');
const sock = new ReconnectingWebsocket(endpoint);
sock.onopen = () => console.log('Connected');
sock.onerror = console.error;
sock.onclose = (...args) => console.log('Closed', ...args);
const sock = new Sock(endpoint);
sock.onmessage = async (message) => {
if (process.env.NODE_ENV !== 'production') console.log('onmessage: ', message);
const payload = JSON.parse(message.data);
masterChannel.postMessage({ type: 'message', payload });
};
+1 -1
View File
@@ -31,7 +31,7 @@ window.UserContext = JSON.parse(window.UserContext);
if (process.env.NODE_ENV === 'production' && !UiContext.sentry_disable) {
window.captureException = (e) => Sentry.captureException(e);
Sentry.init({
dsn: UiContext.sentry_dsn || 'https://04d1d77b095231d55e1202bdc912ff16@sentry.hydro.ac/3',
dsn: UiContext.sentry_dsn || 'https://2f95d53751e08c74c1af1c4b93ccaff7@sentry.hydro.ac/2',
release: process.env.VERSION,
integrations: [
Sentry.browserTracingIntegration(),
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@hydrooj/ui-default",
"version": "4.51.0",
"version": "4.51.1",
"author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0",
"main": "index.ts",
@@ -51,6 +51,7 @@
"clean-webpack-plugin": "^4.0.0",
"clipboard": "^2.0.11",
"copy-webpack-plugin": "^12.0.2",
"core-js": "^3.37.1",
"css-loader": "^6.11.0",
"diff": "^5.2.0",
"diff-dom": "^5.1.3",
@@ -90,7 +91,6 @@
"prop-types": "^15.8.1",
"qface": "^1.4.1",
"qrcode": "^1.5.3",
"queue-microtask": "^1.2.3",
"react": "^18.3.1",
"react-colorful": "^5.6.1",
"react-dnd": "^16.0.1",
+1 -2
View File
@@ -1,9 +1,8 @@
import 'matchmedia-polyfill';
import 'core-js/stable';
import browserUpdate from 'browser-update';
import queueMicrotask from 'queue-microtask';
window.queueMicrotask = queueMicrotask;
browserUpdate({
required: {
e: -10, f: -10, o: -3, s: -1, c: -10,
@@ -47,7 +47,7 @@
var _htmlNode = document.documentElement;
_htmlNode.className = _htmlNode.className.replace(' nojs', ' hasjs');
try {
import('data:text/javascript,');Object.fromEntries([]);window.matchMedia('all').addEventListener('change',()=>{});
import('data:text/javascript,');Object.fromEntries([]);window.matchMedia('all').addEventListener('change',()=>{});Array.prototype.at(0);
} catch(e) {
const s = document.createElement('script');
s.async = false;
+3 -3
View File
@@ -34,8 +34,8 @@ export function secureRandomString(digit = 32, dict = defaultDict) {
type Substitution = string | number | { templateRaw: true, html: string };
export function tpl(node: React.ReactNode, reactive?: boolean);
export function tpl(pieces: TemplateStringsArray, ...substitutions: Substitution[]);
export function tpl<T extends boolean>(node: React.ReactNode, reactive?: T): T extends true ? React.ReactElement : string;
export function tpl(pieces: TemplateStringsArray, ...substitutions: Substitution[]): string;
export function tpl(pieces: TemplateStringsArray | React.ReactNode, ...substitutions: Substitution[] | boolean[]) {
if (React.isValidElement(pieces)) {
if (substitutions[0]) {
@@ -49,7 +49,7 @@ export function tpl(pieces: TemplateStringsArray | React.ReactNode, ...substitut
for (let i = 0; i < substitutions.length; ++i) {
const subst = substitutions[i];
let substHtml: string;
if (typeof subst === 'object' && subst.templateRaw) {
if (subst && typeof subst === 'object' && subst.templateRaw) {
substHtml = subst.html;
} else substHtml = _.escape(String(subst));
result += substHtml + pieces[i + 1];