@dan-uni/dan-any 0.5.0 → 0.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +330 -4919
- package/dist/index.umd.min.js +4612 -276
- package/dist/index.umd.min.js.LICENSE.txt +15 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/utils/dm-gen.d.ts +24 -87
- package/dist/src/utils/id-gen.d.ts +1 -1
- package/package.json +9 -4
- package/src/ass-gen/__tests__/898651903.xml.ass +1 -1
- package/src/index.test.ts +1 -1
- package/src/index.ts +50 -45
- package/src/proto/gen/bili/dm_pb.ts +1 -1
- package/src/proto/gen/danuni_pb.ts +1 -1
- package/src/utils/dm-gen.test.ts +4 -1
- package/src/utils/dm-gen.ts +241 -180
- package/src/utils/id-gen.ts +4 -1
- package/tsconfig.json +3 -3
- package/types/tsconfig.tsbuildinfo +1 -0
package/src/utils/dm-gen.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
import { Expose, plainToInstance } from 'class-transformer'
|
|
2
|
+
import {
|
|
3
|
+
IsDate,
|
|
4
|
+
IsEmail,
|
|
5
|
+
IsEnum,
|
|
6
|
+
IsInt,
|
|
7
|
+
IsNotEmpty,
|
|
8
|
+
IsNumber,
|
|
9
|
+
IsOptional,
|
|
10
|
+
IsString,
|
|
11
|
+
Max,
|
|
12
|
+
Min,
|
|
13
|
+
validateOrReject,
|
|
14
|
+
} from 'class-validator'
|
|
1
15
|
import TimeFormat from 'hh-mm-ss'
|
|
16
|
+
import JSONbig from 'json-bigint'
|
|
2
17
|
import type { DM_JSON_BiliCommandGrpc } from '..'
|
|
3
18
|
import type { PlatformDanmakuSource } from './platform'
|
|
4
19
|
|
|
@@ -9,8 +24,7 @@ import {
|
|
|
9
24
|
PlatformVideoSource,
|
|
10
25
|
} from './platform'
|
|
11
26
|
|
|
12
|
-
const
|
|
13
|
-
typeof v === 'bigint' ? v.toString() : v
|
|
27
|
+
const JSON = JSONbig({ useNativeBigInt: true })
|
|
14
28
|
|
|
15
29
|
function cleanEmptyObjects(obj: object): object {
|
|
16
30
|
if (obj === null || typeof obj !== 'object') {
|
|
@@ -60,23 +74,24 @@ const toBits = (number: number) => {
|
|
|
60
74
|
return bits.reverse()
|
|
61
75
|
}
|
|
62
76
|
|
|
63
|
-
export
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
export enum DMAttr {
|
|
78
|
+
Protect = 'Protect',
|
|
79
|
+
FromLive = 'FromLive',
|
|
80
|
+
HighLike = 'HighLike',
|
|
81
|
+
Compatible = 'Compatible', // 由dan-any进行过兼容处理的弹幕,可能丢失部分信息
|
|
82
|
+
Reported = 'Reported', // 在DanUni上被多人举报过的弹幕
|
|
83
|
+
Unchecked = 'Unchecked', // 在DanUni上未被审核过的弹幕
|
|
84
|
+
HasEvent = 'HasEvent', // 该弹幕当前在DanUni上存在事件(如点赞/举报等)
|
|
85
|
+
Hide = 'Hide', // 由于其它原因需要隐藏的弹幕(建议在server端不返回该类弹幕)
|
|
86
|
+
}
|
|
72
87
|
const DMAttrUtils = {
|
|
73
88
|
fromBin(bin: number = 0, format?: PlatformDanmakuSource) {
|
|
74
89
|
const array = toBits(bin),
|
|
75
90
|
attr: DMAttr[] = []
|
|
76
91
|
if (format === 'bili') {
|
|
77
|
-
if (array[0]) attr.push(
|
|
78
|
-
if (array[1]) attr.push(
|
|
79
|
-
if (array[2]) attr.push(
|
|
92
|
+
if (array[0]) attr.push(DMAttr.Protect)
|
|
93
|
+
if (array[1]) attr.push(DMAttr.FromLive)
|
|
94
|
+
if (array[2]) attr.push(DMAttr.HighLike)
|
|
80
95
|
}
|
|
81
96
|
return attr
|
|
82
97
|
},
|
|
@@ -91,9 +106,9 @@ const DMAttrUtils = {
|
|
|
91
106
|
) {
|
|
92
107
|
const bin = new SetBin(0)
|
|
93
108
|
if (format === 'bili') {
|
|
94
|
-
if (attr.includes(
|
|
95
|
-
if (attr.includes(
|
|
96
|
-
if (attr.includes(
|
|
109
|
+
if (attr.includes(DMAttr.Protect)) bin.set1(0)
|
|
110
|
+
if (attr.includes(DMAttr.FromLive)) bin.set1(1)
|
|
111
|
+
if (attr.includes(DMAttr.HighLike)) bin.set1(2)
|
|
97
112
|
}
|
|
98
113
|
return bin.bin
|
|
99
114
|
},
|
|
@@ -319,133 +334,194 @@ export interface UniDMObj {
|
|
|
319
334
|
DMID: string
|
|
320
335
|
}
|
|
321
336
|
|
|
322
|
-
/**
|
|
323
|
-
* 所有 number/bigint 值设为0自动转换为默认
|
|
324
|
-
*/
|
|
325
337
|
export class UniDM {
|
|
326
338
|
/**
|
|
327
|
-
*
|
|
339
|
+
* 资源ID
|
|
340
|
+
* @description 由某一danuni服务确定的某一剧集下不同资源(不同视频站/字幕组具有细节差异)的ID
|
|
328
341
|
*/
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
)
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
342
|
+
@IsEmail({ require_tld: false })
|
|
343
|
+
@IsString()
|
|
344
|
+
@IsNotEmpty()
|
|
345
|
+
@Expose()
|
|
346
|
+
public SOID: string = ID.fromNull().toString()
|
|
347
|
+
/**
|
|
348
|
+
* 弹幕出现位置(单位s;精度为ms,即保留三位小数)
|
|
349
|
+
*/
|
|
350
|
+
@Min(0)
|
|
351
|
+
@IsNumber()
|
|
352
|
+
@IsNotEmpty()
|
|
353
|
+
@Expose()
|
|
354
|
+
public progress: number = 0
|
|
355
|
+
/**
|
|
356
|
+
* 弹幕类型
|
|
357
|
+
*/
|
|
358
|
+
@IsEnum(Modes)
|
|
359
|
+
@IsNotEmpty()
|
|
360
|
+
@Expose()
|
|
361
|
+
public mode: Modes = Modes.Normal
|
|
362
|
+
/**
|
|
363
|
+
* 字号
|
|
364
|
+
* @default 25
|
|
365
|
+
* - 12
|
|
366
|
+
* - 16
|
|
367
|
+
* - 18:小
|
|
368
|
+
* - 25:标准
|
|
369
|
+
* - 36:大
|
|
370
|
+
* - 45
|
|
371
|
+
* - 64
|
|
372
|
+
*/
|
|
373
|
+
@Max(64)
|
|
374
|
+
@Min(12)
|
|
375
|
+
@IsNumber()
|
|
376
|
+
@IsNotEmpty()
|
|
377
|
+
@Expose()
|
|
378
|
+
public fontsize: number = 25
|
|
379
|
+
/**
|
|
380
|
+
* 颜色
|
|
381
|
+
* @description 为DEC值(十进制RGB888值),默认白色
|
|
382
|
+
* @default 16777215
|
|
383
|
+
*/
|
|
384
|
+
@IsNumber()
|
|
385
|
+
@IsNotEmpty()
|
|
386
|
+
@Expose()
|
|
387
|
+
public color: number = 16777215
|
|
388
|
+
/**
|
|
389
|
+
* 发送者 senderID
|
|
390
|
+
*/
|
|
391
|
+
@IsEmail({ require_tld: false })
|
|
392
|
+
@IsString()
|
|
393
|
+
@IsNotEmpty()
|
|
394
|
+
@Expose()
|
|
395
|
+
public senderID: string = ID.fromNull().toString()
|
|
396
|
+
/**
|
|
397
|
+
* 正文
|
|
398
|
+
*/
|
|
399
|
+
@IsString()
|
|
400
|
+
@IsNotEmpty()
|
|
401
|
+
@Expose()
|
|
402
|
+
public content: string = ''
|
|
403
|
+
/**
|
|
404
|
+
* 发送时间
|
|
405
|
+
*/
|
|
406
|
+
@IsDate()
|
|
407
|
+
@IsNotEmpty()
|
|
408
|
+
@Expose()
|
|
409
|
+
public ctime: Date = new Date()
|
|
410
|
+
/**
|
|
411
|
+
* 权重 用于屏蔽等级 区间:[0,11]
|
|
412
|
+
* @description 参考B站,源弹幕有该参数则直接利用,
|
|
413
|
+
* 本实现默认取5,再经过ruleset匹配加减分数
|
|
414
|
+
* @description 为0时表示暂时未计算权重
|
|
415
|
+
*/
|
|
416
|
+
@Max(11)
|
|
417
|
+
@Min(0)
|
|
418
|
+
@IsInt()
|
|
419
|
+
@IsNotEmpty()
|
|
420
|
+
@Expose()
|
|
421
|
+
public weight: number = 0
|
|
422
|
+
/**
|
|
423
|
+
* 弹幕池 0:普通池 1:字幕池 2:特殊池(代码/BAS弹幕) 3:互动池(互动弹幕中选择投票快速发送的弹幕)
|
|
424
|
+
*/
|
|
425
|
+
@IsEnum(Pools)
|
|
426
|
+
@IsNotEmpty()
|
|
427
|
+
@Expose()
|
|
428
|
+
public pool: Pools = Pools.Def
|
|
429
|
+
/**
|
|
430
|
+
* 弹幕属性位(bin求AND)
|
|
431
|
+
* bit0:保护 bit1:直播 bit2:高赞
|
|
432
|
+
*/
|
|
433
|
+
@IsEnum(DMAttr, { each: true })
|
|
434
|
+
@IsNotEmpty()
|
|
435
|
+
@Expose()
|
|
436
|
+
public attr: DMAttr[] = []
|
|
437
|
+
/**
|
|
438
|
+
* 初始来源平台
|
|
439
|
+
* `danuni`与任意空值(可隐式转换为false的值)等价
|
|
440
|
+
*/
|
|
441
|
+
@IsString()
|
|
442
|
+
@IsOptional()
|
|
443
|
+
@Expose()
|
|
444
|
+
public platform?: PlatformDanmakuSource | string
|
|
445
|
+
/**
|
|
446
|
+
* 弹幕原始数据(不推荐使用)
|
|
447
|
+
* @description 适用于无法解析的B站代码弹幕、Artplayer弹幕样式等
|
|
448
|
+
* @description 初步约定:
|
|
449
|
+
* - Artplayer: style不为空时,将其JSON.stringify()存入
|
|
450
|
+
*/
|
|
451
|
+
@IsString()
|
|
452
|
+
@IsOptional()
|
|
453
|
+
@Expose()
|
|
454
|
+
public extraStr?: string
|
|
455
|
+
@IsString()
|
|
456
|
+
@IsOptional()
|
|
457
|
+
@Expose()
|
|
458
|
+
public DMID?: string
|
|
459
|
+
@Expose()
|
|
460
|
+
init() {
|
|
461
|
+
const def = new UniDM()
|
|
462
|
+
if (!this.SOID) this.SOID = def.SOID
|
|
463
|
+
if (!this.progress) this.progress = def.progress
|
|
464
|
+
if (!this.mode) this.mode = def.mode
|
|
465
|
+
if (!this.fontsize) this.fontsize = def.mode
|
|
466
|
+
if (!this.color) this.color = def.color
|
|
467
|
+
if (!this.senderID) this.senderID = def.senderID
|
|
468
|
+
if (!this.content) this.content = def.content
|
|
469
|
+
if (!this.ctime) this.ctime = def.ctime
|
|
470
|
+
if (!this.weight) this.weight = def.weight
|
|
471
|
+
if (!this.pool) this.pool = def.pool
|
|
472
|
+
if (!this.attr) this.attr = def.attr
|
|
415
473
|
|
|
416
|
-
this.
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
474
|
+
if (!this.DMID) this.DMID = this.toDMID()
|
|
475
|
+
this.progress = Number.parseFloat(this.progress.toFixed(3))
|
|
476
|
+
if (this.extraStr)
|
|
477
|
+
this.extraStr = JSON.stringify(
|
|
478
|
+
cleanEmptyObjects(JSON.parse(this.extraStr)),
|
|
479
|
+
)
|
|
480
|
+
if (this.extraStr === '{}') this.extraStr = undefined
|
|
481
|
+
else if (this.mode !== Modes.Ext) {
|
|
482
|
+
const checkExtraBili = (obj?: ExtraBili) =>
|
|
483
|
+
obj
|
|
484
|
+
? (['adv', 'bas', 'code', 'command'] as (keyof ExtraBili)[]).some(
|
|
485
|
+
(k) => obj[k],
|
|
486
|
+
)
|
|
487
|
+
: false
|
|
488
|
+
if (
|
|
489
|
+
this.extra.artplayer ||
|
|
490
|
+
this.extra.danuni?.chapter ||
|
|
491
|
+
checkExtraBili(this.extra.bili)
|
|
492
|
+
)
|
|
493
|
+
this.mode = Modes.Ext
|
|
494
|
+
}
|
|
495
|
+
return this
|
|
420
496
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
args.SOID || ID.fromNull().toString(),
|
|
425
|
-
args.progress,
|
|
426
|
-
args.mode,
|
|
427
|
-
args.fontsize,
|
|
428
|
-
args.color,
|
|
429
|
-
args.senderID,
|
|
430
|
-
args.content,
|
|
431
|
-
args.ctime,
|
|
432
|
-
args.weight,
|
|
433
|
-
args.pool,
|
|
434
|
-
args.attr,
|
|
435
|
-
args.platform,
|
|
436
|
-
typeof args.extra === 'object'
|
|
437
|
-
? JSON.stringify(args.extra)
|
|
438
|
-
: args.extra || args.extraStr,
|
|
439
|
-
args.DMID,
|
|
440
|
-
)
|
|
441
|
-
: new UniDM(ID.fromNull().toString())
|
|
497
|
+
@Expose()
|
|
498
|
+
async validate() {
|
|
499
|
+
return validateOrReject(this)
|
|
442
500
|
}
|
|
501
|
+
static create(pjson?: Partial<UniDMObj>) {
|
|
502
|
+
return pjson
|
|
503
|
+
? plainToInstance(
|
|
504
|
+
UniDM,
|
|
505
|
+
pjson.extra
|
|
506
|
+
? {
|
|
507
|
+
...pjson,
|
|
508
|
+
extraStr: pjson.extra
|
|
509
|
+
? JSON.stringify(pjson.extra)
|
|
510
|
+
: pjson.extraStr,
|
|
511
|
+
}
|
|
512
|
+
: pjson,
|
|
513
|
+
{ excludeExtraneousValues: true },
|
|
514
|
+
).init()
|
|
515
|
+
: new UniDM()
|
|
516
|
+
}
|
|
517
|
+
@Expose()
|
|
443
518
|
get extra(): Extra {
|
|
444
519
|
const extra = JSON.parse(this.extraStr || '{}')
|
|
445
520
|
// this.extraStr = JSON.stringify(cleanEmptyObjects(extra))
|
|
446
521
|
return extra
|
|
447
522
|
// return cleanEmptyObjects(extra) as Extra
|
|
448
523
|
}
|
|
524
|
+
@Expose()
|
|
449
525
|
get isFrom3rdPlatform() {
|
|
450
526
|
if (
|
|
451
527
|
this.platform &&
|
|
@@ -459,10 +535,20 @@ export class UniDM {
|
|
|
459
535
|
* @description sha3-256(content+senderID+ctime)截取前8位
|
|
460
536
|
* @description 同一SOID下唯一
|
|
461
537
|
*/
|
|
538
|
+
@Expose()
|
|
462
539
|
toDMID() {
|
|
463
|
-
return createDMID(this.content, this.senderID, this.ctime)
|
|
540
|
+
return createDMID(this.content, this.senderID, this.ctime, this.extraStr)
|
|
464
541
|
}
|
|
465
|
-
|
|
542
|
+
@Expose()
|
|
543
|
+
isSameAs(dan: UniDM, options?: { skipDanuniMerge?: boolean }): boolean {
|
|
544
|
+
// 不支持比较高级弹幕
|
|
545
|
+
if (this.mode === Modes.Ext || dan.mode === Modes.Ext) return false
|
|
546
|
+
// 合并过视为不同,防止存在合并完成弹幕后再次合并造成计数错误
|
|
547
|
+
if (
|
|
548
|
+
!options?.skipDanuniMerge &&
|
|
549
|
+
(this.extra.danuni?.merge || dan.extra.danuni?.merge)
|
|
550
|
+
)
|
|
551
|
+
return false
|
|
466
552
|
const isSame = (k: keyof UniDMObj) => this[k] === dan[k],
|
|
467
553
|
checks = (
|
|
468
554
|
[
|
|
@@ -473,39 +559,10 @@ export class UniDM {
|
|
|
473
559
|
'pool',
|
|
474
560
|
] satisfies (keyof UniDMObj)[]
|
|
475
561
|
).every((k) => isSame(k))
|
|
476
|
-
//
|
|
477
|
-
|
|
478
|
-
JSON.stringify(this.extra) === '{}' &&
|
|
479
|
-
JSON.stringify(dan.extra) === '{}'
|
|
480
|
-
) {
|
|
481
|
-
return checks
|
|
482
|
-
}
|
|
483
|
-
// 特殊情况:只包含danuni.merge的情况
|
|
484
|
-
const thisHasOnlyMerge =
|
|
485
|
-
this.extra.danuni?.merge &&
|
|
486
|
-
!this.extra.artplayer &&
|
|
487
|
-
!this.extra.bili &&
|
|
488
|
-
!this.extra.danuni.chapter
|
|
489
|
-
const danHasOnlyMerge =
|
|
490
|
-
dan.extra.danuni?.merge &&
|
|
491
|
-
!dan.extra.artplayer &&
|
|
492
|
-
!dan.extra.bili &&
|
|
493
|
-
!dan.extra.danuni.chapter
|
|
494
|
-
if (thisHasOnlyMerge && danHasOnlyMerge) {
|
|
495
|
-
return checks
|
|
496
|
-
}
|
|
497
|
-
if (_check2) {
|
|
498
|
-
return isSame('extraStr') && checks
|
|
499
|
-
}
|
|
500
|
-
const a = { ...this.extra }
|
|
501
|
-
const b = { ...dan.extra }
|
|
502
|
-
if (a.danuni) delete a.danuni.merge
|
|
503
|
-
if (b.danuni) delete b.danuni.merge
|
|
504
|
-
return UniDM.create({ ...a, extraStr: JSON.stringify(a) }).isSameAs(
|
|
505
|
-
UniDM.create({ ...b, extraStr: JSON.stringify(b) }),
|
|
506
|
-
true,
|
|
507
|
-
)
|
|
562
|
+
// 忽略使用了extra字段却不在mode里标记的弹幕
|
|
563
|
+
return checks
|
|
508
564
|
}
|
|
565
|
+
@Expose()
|
|
509
566
|
minify() {
|
|
510
567
|
type UObj = Partial<UniDMObj> & Pick<UniDMObj, 'SOID'>
|
|
511
568
|
const def: UObj = UniDM.create(),
|
|
@@ -525,6 +582,7 @@ export class UniDM {
|
|
|
525
582
|
}
|
|
526
583
|
return JSON.parse(JSON.stringify(dan)) as UObj
|
|
527
584
|
}
|
|
585
|
+
@Expose()
|
|
528
586
|
downgradeAdvcancedDan(
|
|
529
587
|
{
|
|
530
588
|
include,
|
|
@@ -570,7 +628,7 @@ export class UniDM {
|
|
|
570
628
|
}
|
|
571
629
|
}
|
|
572
630
|
clone.senderID = 'compat[bot]@dan-any'
|
|
573
|
-
clone.attr.push(
|
|
631
|
+
clone.attr.push(DMAttr.Compatible)
|
|
574
632
|
if (cleanExtra) clone.extraStr = undefined
|
|
575
633
|
return clone
|
|
576
634
|
}
|
|
@@ -664,7 +722,7 @@ export class UniDM {
|
|
|
664
722
|
bili: ExtraBili
|
|
665
723
|
}
|
|
666
724
|
if (args.oid && !cid) cid = args.oid
|
|
667
|
-
const SOID = `
|
|
725
|
+
const SOID = `def_${PlatformVideoSource.Bilibili}+${ID.fromBili({ cid })}`,
|
|
668
726
|
senderID = ID.fromBili({ midHash: args.midHash })
|
|
669
727
|
let mode = Modes.Normal
|
|
670
728
|
const pool = args.pool, //暂时不做处理,兼容bili的pool格式
|
|
@@ -716,11 +774,14 @@ export class UniDM {
|
|
|
716
774
|
// 需改进,7=>advanced 8=>code 9=>bas 互动=>command
|
|
717
775
|
// 同时塞进无法/无需直接解析的数据
|
|
718
776
|
// 另开一个解析器,为大部分播放器(无法解析该类dm)做文本类型降级处理
|
|
719
|
-
extra
|
|
720
|
-
args.mode >= 7 ? JSON.stringify(extra, BigIntSerializer) : undefined,
|
|
777
|
+
extra,
|
|
721
778
|
})
|
|
722
779
|
}
|
|
723
|
-
|
|
780
|
+
@Expose()
|
|
781
|
+
toBiliXML(options?: { skipBiliCommand: boolean }) {
|
|
782
|
+
if (options?.skipBiliCommand && this.extra.bili?.command) {
|
|
783
|
+
return null
|
|
784
|
+
}
|
|
724
785
|
const recMode = (mode: Modes, extra?: ExtraBili) => {
|
|
725
786
|
switch (mode) {
|
|
726
787
|
case Modes.Normal:
|
|
@@ -788,16 +849,13 @@ export class UniDM {
|
|
|
788
849
|
ctime: new Date(`${args.ctime} GMT+0800`), // 无视本地时区,按照B站的东8区计算时间
|
|
789
850
|
weight: 10,
|
|
790
851
|
pool: Pools.Adv,
|
|
791
|
-
attr: [
|
|
852
|
+
attr: [DMAttr.Protect],
|
|
792
853
|
platform: PlatformVideoSource.Bilibili,
|
|
793
|
-
extra:
|
|
794
|
-
{
|
|
795
|
-
|
|
796
|
-
command: args,
|
|
797
|
-
},
|
|
854
|
+
extra: {
|
|
855
|
+
bili: {
|
|
856
|
+
command: args,
|
|
798
857
|
},
|
|
799
|
-
|
|
800
|
-
),
|
|
858
|
+
},
|
|
801
859
|
})
|
|
802
860
|
}
|
|
803
861
|
static fromDplayer(args: DMDplayer, playerID: string, domain: string) {
|
|
@@ -815,6 +873,7 @@ export class UniDM {
|
|
|
815
873
|
platform: domain,
|
|
816
874
|
})
|
|
817
875
|
}
|
|
876
|
+
@Expose()
|
|
818
877
|
toDplayer(): DMDplayer {
|
|
819
878
|
let mode = 0
|
|
820
879
|
if (this.mode === Modes.Top) mode = 1
|
|
@@ -851,9 +910,10 @@ export class UniDM {
|
|
|
851
910
|
senderID: senderID.toString(),
|
|
852
911
|
// content: args.content,
|
|
853
912
|
platform: domain,
|
|
854
|
-
extra
|
|
913
|
+
extra, //optional BigINt parser
|
|
855
914
|
})
|
|
856
915
|
}
|
|
916
|
+
@Expose()
|
|
857
917
|
toArtplayer(): DMArtplayer {
|
|
858
918
|
let mode = 0
|
|
859
919
|
if (this.mode === Modes.Top) mode = 1
|
|
@@ -885,6 +945,7 @@ export class UniDM {
|
|
|
885
945
|
DMID: args.cid.toString(), //无需 new ID() 获取带suffix的ID
|
|
886
946
|
})
|
|
887
947
|
}
|
|
948
|
+
@Expose()
|
|
888
949
|
toDDplay(): DMDDplay {
|
|
889
950
|
let mode = 1
|
|
890
951
|
if (this.mode === Modes.Top) mode = 5
|
package/src/utils/id-gen.ts
CHANGED
|
@@ -66,10 +66,13 @@ export function createDMID(
|
|
|
66
66
|
content: string = '',
|
|
67
67
|
senderID: string,
|
|
68
68
|
ctime: ctime,
|
|
69
|
+
extraStr?: string,
|
|
69
70
|
slice = 8,
|
|
70
71
|
) {
|
|
71
72
|
return new jsSHA('SHA3-256', 'TEXT')
|
|
72
|
-
.update(
|
|
73
|
+
.update(
|
|
74
|
+
`${content}|${senderID}|${UniDM.transCtime(ctime).toISOString()}|${extraStr}`,
|
|
75
|
+
)
|
|
73
76
|
.getHash('HEX')
|
|
74
77
|
.slice(0, slice)
|
|
75
78
|
}
|
package/tsconfig.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
4
4
|
/* Projects */
|
|
5
|
-
|
|
5
|
+
"incremental": true /* Save .tsbuildinfo files to allow for incremental compilation of projects. */,
|
|
6
6
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
|
7
7
|
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
|
8
8
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
11
11
|
/* Language and Environment */
|
|
12
12
|
"target": "ES2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
13
|
+
"emitDecoratorMetadata": true /* Emit design-type metadata for decorated declarations in source files. */,
|
|
13
14
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
14
15
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
15
|
-
|
|
16
|
-
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
|
16
|
+
"experimentalDecorators": true /* Enable experimental support for legacy experimental decorators. */,
|
|
17
17
|
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
|
18
18
|
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
|
19
19
|
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"5.8.3"}
|