@dan-uni/dan-any 0.4.9 → 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 +322 -4912
- package/dist/index.umd.min.js +4604 -269
- 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 +26 -83
- 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 +243 -177
- 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') {
|
|
@@ -42,6 +56,11 @@ class SetBin {
|
|
|
42
56
|
this.bin &= ~(1 << bit)
|
|
43
57
|
}
|
|
44
58
|
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 获得数字的二进制,每位以boolean(true/false)表示1/0,从低位向高位
|
|
62
|
+
* @param number 任意进制数字
|
|
63
|
+
*/
|
|
45
64
|
const toBits = (number: number) => {
|
|
46
65
|
// 低速方案
|
|
47
66
|
// return [...number.toString(2)].map(Number)
|
|
@@ -52,26 +71,27 @@ const toBits = (number: number) => {
|
|
|
52
71
|
// bits.unshift(number & 1) // (0|1)[]
|
|
53
72
|
number >>= 1
|
|
54
73
|
} while (number)
|
|
55
|
-
return bits
|
|
74
|
+
return bits.reverse()
|
|
56
75
|
}
|
|
57
76
|
|
|
58
|
-
export
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
+
}
|
|
67
87
|
const DMAttrUtils = {
|
|
68
88
|
fromBin(bin: number = 0, format?: PlatformDanmakuSource) {
|
|
69
89
|
const array = toBits(bin),
|
|
70
90
|
attr: DMAttr[] = []
|
|
71
91
|
if (format === 'bili') {
|
|
72
|
-
if (array[0]) attr.push(
|
|
73
|
-
if (array[1]) attr.push(
|
|
74
|
-
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)
|
|
75
95
|
}
|
|
76
96
|
return attr
|
|
77
97
|
},
|
|
@@ -86,9 +106,9 @@ const DMAttrUtils = {
|
|
|
86
106
|
) {
|
|
87
107
|
const bin = new SetBin(0)
|
|
88
108
|
if (format === 'bili') {
|
|
89
|
-
if (attr.includes(
|
|
90
|
-
if (attr.includes(
|
|
91
|
-
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)
|
|
92
112
|
}
|
|
93
113
|
return bin.bin
|
|
94
114
|
},
|
|
@@ -314,129 +334,194 @@ export interface UniDMObj {
|
|
|
314
334
|
DMID: string
|
|
315
335
|
}
|
|
316
336
|
|
|
317
|
-
/**
|
|
318
|
-
* 所有 number/bigint 值设为0自动转换为默认
|
|
319
|
-
*/
|
|
320
337
|
export class UniDM {
|
|
321
338
|
/**
|
|
322
|
-
*
|
|
339
|
+
* 资源ID
|
|
340
|
+
* @description 由某一danuni服务确定的某一剧集下不同资源(不同视频站/字幕组具有细节差异)的ID
|
|
323
341
|
*/
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
-
|
|
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
|
|
406
473
|
|
|
407
|
-
this.
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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
|
|
411
496
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
args.SOID || ID.fromNull().toString(),
|
|
416
|
-
args.progress,
|
|
417
|
-
args.mode,
|
|
418
|
-
args.fontsize,
|
|
419
|
-
args.color,
|
|
420
|
-
args.senderID,
|
|
421
|
-
args.content,
|
|
422
|
-
args.ctime,
|
|
423
|
-
args.weight,
|
|
424
|
-
args.pool,
|
|
425
|
-
args.attr,
|
|
426
|
-
args.platform,
|
|
427
|
-
typeof args.extra === 'object'
|
|
428
|
-
? JSON.stringify(args.extra)
|
|
429
|
-
: args.extra || args.extraStr,
|
|
430
|
-
args.DMID,
|
|
431
|
-
)
|
|
432
|
-
: new UniDM(ID.fromNull().toString())
|
|
497
|
+
@Expose()
|
|
498
|
+
async validate() {
|
|
499
|
+
return validateOrReject(this)
|
|
433
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()
|
|
434
518
|
get extra(): Extra {
|
|
435
519
|
const extra = JSON.parse(this.extraStr || '{}')
|
|
436
520
|
// this.extraStr = JSON.stringify(cleanEmptyObjects(extra))
|
|
437
521
|
return extra
|
|
438
522
|
// return cleanEmptyObjects(extra) as Extra
|
|
439
523
|
}
|
|
524
|
+
@Expose()
|
|
440
525
|
get isFrom3rdPlatform() {
|
|
441
526
|
if (
|
|
442
527
|
this.platform &&
|
|
@@ -450,10 +535,16 @@ export class UniDM {
|
|
|
450
535
|
* @description sha3-256(content+senderID+ctime)截取前8位
|
|
451
536
|
* @description 同一SOID下唯一
|
|
452
537
|
*/
|
|
538
|
+
@Expose()
|
|
453
539
|
toDMID() {
|
|
454
|
-
return createDMID(this.content, this.senderID, this.ctime)
|
|
540
|
+
return createDMID(this.content, this.senderID, this.ctime, this.extraStr)
|
|
455
541
|
}
|
|
456
|
-
|
|
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
|
|
457
548
|
const isSame = (k: keyof UniDMObj) => this[k] === dan[k],
|
|
458
549
|
checks = (
|
|
459
550
|
[
|
|
@@ -464,39 +555,10 @@ export class UniDM {
|
|
|
464
555
|
'pool',
|
|
465
556
|
] satisfies (keyof UniDMObj)[]
|
|
466
557
|
).every((k) => isSame(k))
|
|
467
|
-
//
|
|
468
|
-
|
|
469
|
-
JSON.stringify(this.extra) === '{}' &&
|
|
470
|
-
JSON.stringify(dan.extra) === '{}'
|
|
471
|
-
) {
|
|
472
|
-
return checks
|
|
473
|
-
}
|
|
474
|
-
// 特殊情况:只包含danuni.merge的情况
|
|
475
|
-
const thisHasOnlyMerge =
|
|
476
|
-
this.extra.danuni?.merge &&
|
|
477
|
-
!this.extra.artplayer &&
|
|
478
|
-
!this.extra.bili &&
|
|
479
|
-
!this.extra.danuni.chapter
|
|
480
|
-
const danHasOnlyMerge =
|
|
481
|
-
dan.extra.danuni?.merge &&
|
|
482
|
-
!dan.extra.artplayer &&
|
|
483
|
-
!dan.extra.bili &&
|
|
484
|
-
!dan.extra.danuni.chapter
|
|
485
|
-
if (thisHasOnlyMerge && danHasOnlyMerge) {
|
|
486
|
-
return checks
|
|
487
|
-
}
|
|
488
|
-
if (_check2) {
|
|
489
|
-
return isSame('extraStr') && checks
|
|
490
|
-
}
|
|
491
|
-
const a = { ...this.extra }
|
|
492
|
-
const b = { ...dan.extra }
|
|
493
|
-
if (a.danuni) delete a.danuni.merge
|
|
494
|
-
if (b.danuni) delete b.danuni.merge
|
|
495
|
-
return UniDM.create({ ...a, extraStr: JSON.stringify(a) }).isSameAs(
|
|
496
|
-
UniDM.create({ ...b, extraStr: JSON.stringify(b) }),
|
|
497
|
-
true,
|
|
498
|
-
)
|
|
558
|
+
// 忽略使用了extra字段却不在mode里标记的弹幕
|
|
559
|
+
return checks
|
|
499
560
|
}
|
|
561
|
+
@Expose()
|
|
500
562
|
minify() {
|
|
501
563
|
type UObj = Partial<UniDMObj> & Pick<UniDMObj, 'SOID'>
|
|
502
564
|
const def: UObj = UniDM.create(),
|
|
@@ -516,6 +578,7 @@ export class UniDM {
|
|
|
516
578
|
}
|
|
517
579
|
return JSON.parse(JSON.stringify(dan)) as UObj
|
|
518
580
|
}
|
|
581
|
+
@Expose()
|
|
519
582
|
downgradeAdvcancedDan(
|
|
520
583
|
{
|
|
521
584
|
include,
|
|
@@ -561,7 +624,7 @@ export class UniDM {
|
|
|
561
624
|
}
|
|
562
625
|
}
|
|
563
626
|
clone.senderID = 'compat[bot]@dan-any'
|
|
564
|
-
clone.attr.push(
|
|
627
|
+
clone.attr.push(DMAttr.Compatible)
|
|
565
628
|
if (cleanExtra) clone.extraStr = undefined
|
|
566
629
|
return clone
|
|
567
630
|
}
|
|
@@ -655,7 +718,7 @@ export class UniDM {
|
|
|
655
718
|
bili: ExtraBili
|
|
656
719
|
}
|
|
657
720
|
if (args.oid && !cid) cid = args.oid
|
|
658
|
-
const SOID = `
|
|
721
|
+
const SOID = `def_${PlatformVideoSource.Bilibili}+${ID.fromBili({ cid })}`,
|
|
659
722
|
senderID = ID.fromBili({ midHash: args.midHash })
|
|
660
723
|
let mode = Modes.Normal
|
|
661
724
|
const pool = args.pool, //暂时不做处理,兼容bili的pool格式
|
|
@@ -707,11 +770,14 @@ export class UniDM {
|
|
|
707
770
|
// 需改进,7=>advanced 8=>code 9=>bas 互动=>command
|
|
708
771
|
// 同时塞进无法/无需直接解析的数据
|
|
709
772
|
// 另开一个解析器,为大部分播放器(无法解析该类dm)做文本类型降级处理
|
|
710
|
-
extra
|
|
711
|
-
args.mode >= 7 ? JSON.stringify(extra, BigIntSerializer) : undefined,
|
|
773
|
+
extra,
|
|
712
774
|
})
|
|
713
775
|
}
|
|
714
|
-
|
|
776
|
+
@Expose()
|
|
777
|
+
toBiliXML(options?: { skipBiliCommand: boolean }) {
|
|
778
|
+
if (options?.skipBiliCommand && this.extra.bili?.command) {
|
|
779
|
+
return null
|
|
780
|
+
}
|
|
715
781
|
const recMode = (mode: Modes, extra?: ExtraBili) => {
|
|
716
782
|
switch (mode) {
|
|
717
783
|
case Modes.Normal:
|
|
@@ -779,16 +845,13 @@ export class UniDM {
|
|
|
779
845
|
ctime: new Date(`${args.ctime} GMT+0800`), // 无视本地时区,按照B站的东8区计算时间
|
|
780
846
|
weight: 10,
|
|
781
847
|
pool: Pools.Adv,
|
|
782
|
-
attr: [
|
|
848
|
+
attr: [DMAttr.Protect],
|
|
783
849
|
platform: PlatformVideoSource.Bilibili,
|
|
784
|
-
extra:
|
|
785
|
-
{
|
|
786
|
-
|
|
787
|
-
command: args,
|
|
788
|
-
},
|
|
850
|
+
extra: {
|
|
851
|
+
bili: {
|
|
852
|
+
command: args,
|
|
789
853
|
},
|
|
790
|
-
|
|
791
|
-
),
|
|
854
|
+
},
|
|
792
855
|
})
|
|
793
856
|
}
|
|
794
857
|
static fromDplayer(args: DMDplayer, playerID: string, domain: string) {
|
|
@@ -806,6 +869,7 @@ export class UniDM {
|
|
|
806
869
|
platform: domain,
|
|
807
870
|
})
|
|
808
871
|
}
|
|
872
|
+
@Expose()
|
|
809
873
|
toDplayer(): DMDplayer {
|
|
810
874
|
let mode = 0
|
|
811
875
|
if (this.mode === Modes.Top) mode = 1
|
|
@@ -842,9 +906,10 @@ export class UniDM {
|
|
|
842
906
|
senderID: senderID.toString(),
|
|
843
907
|
// content: args.content,
|
|
844
908
|
platform: domain,
|
|
845
|
-
extra
|
|
909
|
+
extra, //optional BigINt parser
|
|
846
910
|
})
|
|
847
911
|
}
|
|
912
|
+
@Expose()
|
|
848
913
|
toArtplayer(): DMArtplayer {
|
|
849
914
|
let mode = 0
|
|
850
915
|
if (this.mode === Modes.Top) mode = 1
|
|
@@ -876,6 +941,7 @@ export class UniDM {
|
|
|
876
941
|
DMID: args.cid.toString(), //无需 new ID() 获取带suffix的ID
|
|
877
942
|
})
|
|
878
943
|
}
|
|
944
|
+
@Expose()
|
|
879
945
|
toDDplay(): DMDDplay {
|
|
880
946
|
let mode = 1
|
|
881
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"}
|