@dan-uni/dan-any 0.5.0 → 0.6.6
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 +321 -4911
- package/dist/index.umd.min.js +4603 -268
- 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 +22 -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 +44 -41
- 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 +237 -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.test.ts
CHANGED
|
@@ -114,13 +114,16 @@ describe('其它', () => {
|
|
|
114
114
|
UniDM.create({ ...commonSample }),
|
|
115
115
|
UniDM.create({ ...commonSample, extra: { artplayer: { border: true } } }),
|
|
116
116
|
]
|
|
117
|
+
let counter = 0
|
|
117
118
|
for (const pool of pool2) {
|
|
118
119
|
console.info(pool.extraStr)
|
|
119
120
|
console.info(pool2[0].isSameAs(pool))
|
|
121
|
+
if (counter <= 2) expect(pool2[0].extraStr).toBe(undefined)
|
|
122
|
+
counter++
|
|
120
123
|
}
|
|
121
124
|
expect(pool2[0].isSameAs(pool2[1])).toBe(true)
|
|
122
125
|
expect(pool2[0].isSameAs(pool2[2])).toBe(true)
|
|
123
|
-
expect(pool2[0].isSameAs(pool2[3])).toBe(
|
|
126
|
+
expect(pool2[0].isSameAs(pool2[3])).toBe(false)
|
|
124
127
|
expect(pool2[0].isSameAs(pool2[4])).toBe(false)
|
|
125
128
|
})
|
|
126
129
|
})
|
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,16 @@ 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): boolean {
|
|
544
|
+
// 不支持比较高级弹幕
|
|
545
|
+
if (this.mode === Modes.Ext || dan.mode === Modes.Ext) return false
|
|
546
|
+
// 合并过视为不同,防止存在合并完成弹幕后再次合并造成计数错误
|
|
547
|
+
if (this.extra.danuni?.merge || dan.extra.danuni?.merge) return false
|
|
466
548
|
const isSame = (k: keyof UniDMObj) => this[k] === dan[k],
|
|
467
549
|
checks = (
|
|
468
550
|
[
|
|
@@ -473,39 +555,10 @@ export class UniDM {
|
|
|
473
555
|
'pool',
|
|
474
556
|
] satisfies (keyof UniDMObj)[]
|
|
475
557
|
).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
|
-
)
|
|
558
|
+
// 忽略使用了extra字段却不在mode里标记的弹幕
|
|
559
|
+
return checks
|
|
508
560
|
}
|
|
561
|
+
@Expose()
|
|
509
562
|
minify() {
|
|
510
563
|
type UObj = Partial<UniDMObj> & Pick<UniDMObj, 'SOID'>
|
|
511
564
|
const def: UObj = UniDM.create(),
|
|
@@ -525,6 +578,7 @@ export class UniDM {
|
|
|
525
578
|
}
|
|
526
579
|
return JSON.parse(JSON.stringify(dan)) as UObj
|
|
527
580
|
}
|
|
581
|
+
@Expose()
|
|
528
582
|
downgradeAdvcancedDan(
|
|
529
583
|
{
|
|
530
584
|
include,
|
|
@@ -570,7 +624,7 @@ export class UniDM {
|
|
|
570
624
|
}
|
|
571
625
|
}
|
|
572
626
|
clone.senderID = 'compat[bot]@dan-any'
|
|
573
|
-
clone.attr.push(
|
|
627
|
+
clone.attr.push(DMAttr.Compatible)
|
|
574
628
|
if (cleanExtra) clone.extraStr = undefined
|
|
575
629
|
return clone
|
|
576
630
|
}
|
|
@@ -664,7 +718,7 @@ export class UniDM {
|
|
|
664
718
|
bili: ExtraBili
|
|
665
719
|
}
|
|
666
720
|
if (args.oid && !cid) cid = args.oid
|
|
667
|
-
const SOID = `
|
|
721
|
+
const SOID = `def_${PlatformVideoSource.Bilibili}+${ID.fromBili({ cid })}`,
|
|
668
722
|
senderID = ID.fromBili({ midHash: args.midHash })
|
|
669
723
|
let mode = Modes.Normal
|
|
670
724
|
const pool = args.pool, //暂时不做处理,兼容bili的pool格式
|
|
@@ -716,11 +770,14 @@ export class UniDM {
|
|
|
716
770
|
// 需改进,7=>advanced 8=>code 9=>bas 互动=>command
|
|
717
771
|
// 同时塞进无法/无需直接解析的数据
|
|
718
772
|
// 另开一个解析器,为大部分播放器(无法解析该类dm)做文本类型降级处理
|
|
719
|
-
extra
|
|
720
|
-
args.mode >= 7 ? JSON.stringify(extra, BigIntSerializer) : undefined,
|
|
773
|
+
extra,
|
|
721
774
|
})
|
|
722
775
|
}
|
|
723
|
-
|
|
776
|
+
@Expose()
|
|
777
|
+
toBiliXML(options?: { skipBiliCommand: boolean }) {
|
|
778
|
+
if (options?.skipBiliCommand && this.extra.bili?.command) {
|
|
779
|
+
return null
|
|
780
|
+
}
|
|
724
781
|
const recMode = (mode: Modes, extra?: ExtraBili) => {
|
|
725
782
|
switch (mode) {
|
|
726
783
|
case Modes.Normal:
|
|
@@ -788,16 +845,13 @@ export class UniDM {
|
|
|
788
845
|
ctime: new Date(`${args.ctime} GMT+0800`), // 无视本地时区,按照B站的东8区计算时间
|
|
789
846
|
weight: 10,
|
|
790
847
|
pool: Pools.Adv,
|
|
791
|
-
attr: [
|
|
848
|
+
attr: [DMAttr.Protect],
|
|
792
849
|
platform: PlatformVideoSource.Bilibili,
|
|
793
|
-
extra:
|
|
794
|
-
{
|
|
795
|
-
|
|
796
|
-
command: args,
|
|
797
|
-
},
|
|
850
|
+
extra: {
|
|
851
|
+
bili: {
|
|
852
|
+
command: args,
|
|
798
853
|
},
|
|
799
|
-
|
|
800
|
-
),
|
|
854
|
+
},
|
|
801
855
|
})
|
|
802
856
|
}
|
|
803
857
|
static fromDplayer(args: DMDplayer, playerID: string, domain: string) {
|
|
@@ -815,6 +869,7 @@ export class UniDM {
|
|
|
815
869
|
platform: domain,
|
|
816
870
|
})
|
|
817
871
|
}
|
|
872
|
+
@Expose()
|
|
818
873
|
toDplayer(): DMDplayer {
|
|
819
874
|
let mode = 0
|
|
820
875
|
if (this.mode === Modes.Top) mode = 1
|
|
@@ -851,9 +906,10 @@ export class UniDM {
|
|
|
851
906
|
senderID: senderID.toString(),
|
|
852
907
|
// content: args.content,
|
|
853
908
|
platform: domain,
|
|
854
|
-
extra
|
|
909
|
+
extra, //optional BigINt parser
|
|
855
910
|
})
|
|
856
911
|
}
|
|
912
|
+
@Expose()
|
|
857
913
|
toArtplayer(): DMArtplayer {
|
|
858
914
|
let mode = 0
|
|
859
915
|
if (this.mode === Modes.Top) mode = 1
|
|
@@ -885,6 +941,7 @@ export class UniDM {
|
|
|
885
941
|
DMID: args.cid.toString(), //无需 new ID() 获取带suffix的ID
|
|
886
942
|
})
|
|
887
943
|
}
|
|
944
|
+
@Expose()
|
|
888
945
|
toDDplay(): DMDDplay {
|
|
889
946
|
let mode = 1
|
|
890
947
|
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"}
|