@dan-uni/dan-any 0.9.9 → 1.0.0
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 +245 -240
- package/dist/index.min.js +250 -245
- package/dist/index.umd.min.js +296 -281
- package/dist/src/index.d.ts +17 -7
- package/dist/src/proto/gen/danuni_pb.d.ts +2 -2
- package/package.json +5 -5
- package/src/ass-gen/ass/dialogue.ts +4 -4
- package/src/index.ts +164 -130
- package/src/proto/gen/bili/dm_pb.ts +1 -1
- package/src/proto/gen/danuni_pb.ts +4 -4
- package/src/proto/src/danuni.proto +1 -1
- package/src/utils/dm-gen.ts +16 -19
package/dist/src/index.d.ts
CHANGED
|
@@ -119,14 +119,15 @@ export interface DM_JSON_DDPlay {
|
|
|
119
119
|
export type DM_format = 'danuni.json' | 'danuni.pb.bin' | 'bili.xml' | 'bili.pb.bin' | 'bili.cmd.pb.bin' | 'bili.up.json' | 'dplayer.json' | 'artplayer.json' | 'ddplay.json' | 'common.ass';
|
|
120
120
|
type shareItems = Partial<Pick<UniDMTools.UniDMObj, 'SOID' | 'senderID' | 'platform' | 'SOID' | 'pool' | 'mode' | 'color'>>;
|
|
121
121
|
type statItems = Partial<Pick<UniDMTools.UniDMObj, 'SOID' | 'mode' | 'fontsize' | 'color' | 'senderID' | 'content' | 'weight' | 'pool' | 'platform'>>;
|
|
122
|
-
|
|
123
|
-
val: statItems[keyof statItems];
|
|
124
|
-
count: number;
|
|
125
|
-
}
|
|
122
|
+
type Stats<T extends keyof statItems> = Map<statItems[T], number>;
|
|
126
123
|
type UniPoolPipe = (that: UniPool) => Promise<UniPool>;
|
|
127
124
|
type UniPoolPipeSync = (that: UniPool) => UniPool;
|
|
128
125
|
export interface Options {
|
|
129
126
|
dedupe?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* @description
|
|
129
|
+
* 当为`false`时,关闭DMID生成; 当为正整数时,表示生成DMID的截取位数; 或可传入一个DMID生成器实例
|
|
130
|
+
*/
|
|
130
131
|
dmid?: boolean | number | UniIDTools.DMIDGenerator;
|
|
131
132
|
}
|
|
132
133
|
export declare class UniPool {
|
|
@@ -146,10 +147,19 @@ export declare class UniPool {
|
|
|
146
147
|
});
|
|
147
148
|
pipe(fn: UniPoolPipe): Promise<UniPool>;
|
|
148
149
|
pipeSync(fn: UniPoolPipeSync): UniPool;
|
|
150
|
+
/**
|
|
151
|
+
* @deprecated 使用 `getShared` 代替
|
|
152
|
+
*/
|
|
149
153
|
get shared(): shareItems;
|
|
150
|
-
getShared(key:
|
|
151
|
-
getStat(key:
|
|
152
|
-
getMost(key:
|
|
154
|
+
getShared<K extends keyof shareItems>(key: K): shareItems[K];
|
|
155
|
+
getStat<K extends keyof statItems>(key: K): Stats<K>;
|
|
156
|
+
getMost<K extends keyof statItems>(key: K): {
|
|
157
|
+
val: Partial<Pick<UniDMTools.UniDMObj, "SOID" | "mode" | "fontsize" | "color" | "senderID" | "content" | "weight" | "pool" | "platform">>[K] | undefined;
|
|
158
|
+
count: number;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* @deprecated 使用 `getMost` 代替
|
|
162
|
+
*/
|
|
153
163
|
get most(): {
|
|
154
164
|
mode: UniDMTools.Modes;
|
|
155
165
|
fontsize: number;
|
|
@@ -76,9 +76,9 @@ export type Danmaku = Message<"danuni.danmaku.v1.Danmaku"> & {
|
|
|
76
76
|
*/
|
|
77
77
|
attr: string[];
|
|
78
78
|
/**
|
|
79
|
-
* @generated from field: string platform = 13;
|
|
79
|
+
* @generated from field: optional string platform = 13;
|
|
80
80
|
*/
|
|
81
|
-
platform
|
|
81
|
+
platform?: string;
|
|
82
82
|
/**
|
|
83
83
|
* @generated from field: optional string extra = 14;
|
|
84
84
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dan-uni/dan-any",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "A danmaku transformer lib, supporting danmaku from different platforms.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"buf": "buf generate"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@bufbuild/protobuf": "^2.
|
|
35
|
+
"@bufbuild/protobuf": "^2.10.1",
|
|
36
36
|
"base16384": "^1.0.0",
|
|
37
37
|
"class-transformer": "^0.5.1",
|
|
38
38
|
"class-validator": "^0.14.2",
|
|
39
|
-
"fast-xml-parser": "^5.3.
|
|
39
|
+
"fast-xml-parser": "^5.3.2",
|
|
40
40
|
"fs-extra": "^11.3.2",
|
|
41
41
|
"hh-mm-ss": "^1.2.0",
|
|
42
42
|
"json-bigint": "^1.0.0",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"reflect-metadata": "^0.2.2"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@bufbuild/buf": "^1.
|
|
48
|
-
"@bufbuild/protoc-gen-es": "^2.
|
|
47
|
+
"@bufbuild/buf": "^1.60.0",
|
|
48
|
+
"@bufbuild/protoc-gen-es": "^2.10.1",
|
|
49
49
|
"@types/fs-extra": "^11.0.4",
|
|
50
50
|
"@types/hh-mm-ss": "^1.2.3",
|
|
51
51
|
"@types/json-bigint": "^1.0.4",
|
|
@@ -34,11 +34,11 @@ const scrollCommand = ({
|
|
|
34
34
|
start: number
|
|
35
35
|
end: number
|
|
36
36
|
top: number
|
|
37
|
-
}) =>
|
|
37
|
+
}) => String.raw`\move(${start},${top},${end},${top})`
|
|
38
38
|
const fixCommand = ({ top, left }: { top: number; left: number }) =>
|
|
39
|
-
|
|
40
|
-
const colorCommand = (color: RGB) =>
|
|
41
|
-
const borderColorCommand = (color: RGB) =>
|
|
39
|
+
String.raw`\an8\pos(${left},${top})`
|
|
40
|
+
const colorCommand = (color: RGB) => String.raw`\c${formatColor(color)}`
|
|
41
|
+
const borderColorCommand = (color: RGB) => String.raw`\3c${formatColor(color)}`
|
|
42
42
|
|
|
43
43
|
export const dialogue = (
|
|
44
44
|
danmaku: {
|
package/src/index.ts
CHANGED
|
@@ -183,16 +183,17 @@ type statItems = Partial<
|
|
|
183
183
|
| 'platform'
|
|
184
184
|
>
|
|
185
185
|
>
|
|
186
|
-
|
|
187
|
-
val: statItems[keyof statItems]
|
|
188
|
-
count: number
|
|
189
|
-
}
|
|
186
|
+
type Stats<T extends keyof statItems> = Map<statItems[T], number>
|
|
190
187
|
|
|
191
188
|
type UniPoolPipe = (that: UniPool) => Promise<UniPool>
|
|
192
189
|
type UniPoolPipeSync = (that: UniPool) => UniPool
|
|
193
190
|
|
|
194
191
|
export interface Options {
|
|
195
192
|
dedupe?: boolean
|
|
193
|
+
/**
|
|
194
|
+
* @description
|
|
195
|
+
* 当为`false`时,关闭DMID生成; 当为正整数时,表示生成DMID的截取位数; 或可传入一个DMID生成器实例
|
|
196
|
+
*/
|
|
196
197
|
dmid?: boolean | number | UniIDTools.DMIDGenerator
|
|
197
198
|
}
|
|
198
199
|
|
|
@@ -216,51 +217,109 @@ export class UniPool {
|
|
|
216
217
|
pipeSync(fn: UniPoolPipeSync): UniPool {
|
|
217
218
|
return fn(this)
|
|
218
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* @deprecated 使用 `getShared` 代替
|
|
222
|
+
*/
|
|
219
223
|
get shared(): shareItems {
|
|
220
|
-
|
|
221
|
-
|
|
224
|
+
if (this.dans.length === 0) return {}
|
|
225
|
+
const keys: (keyof shareItems)[] = [
|
|
226
|
+
'SOID',
|
|
227
|
+
'senderID',
|
|
228
|
+
'platform',
|
|
229
|
+
'pool',
|
|
230
|
+
'mode',
|
|
231
|
+
'color',
|
|
232
|
+
]
|
|
233
|
+
const result: shareItems = {} as shareItems
|
|
234
|
+
for (const key of keys) {
|
|
235
|
+
const sharedVal = this.getShared(key)
|
|
236
|
+
if (sharedVal !== undefined) {
|
|
237
|
+
result[key] = sharedVal as any
|
|
238
|
+
}
|
|
222
239
|
}
|
|
223
|
-
return
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
240
|
+
return result
|
|
241
|
+
}
|
|
242
|
+
getShared<K extends keyof shareItems>(key: K): shareItems[K] {
|
|
243
|
+
if (this.dans.length === 0) return undefined
|
|
244
|
+
const firstVal = this.dans[0][key]
|
|
245
|
+
for (let i = 1; i < this.dans.length; i++) {
|
|
246
|
+
if (this.dans[i][key] !== firstVal) {
|
|
247
|
+
return undefined
|
|
248
|
+
}
|
|
230
249
|
}
|
|
250
|
+
return firstVal
|
|
231
251
|
}
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
|
|
252
|
+
getStat<K extends keyof statItems>(key: K): Stats<K> {
|
|
253
|
+
const statMap = new Map<statItems[K], number>()
|
|
254
|
+
for (const dan of this.dans) {
|
|
255
|
+
const val = dan[key]
|
|
256
|
+
statMap.set(val, (statMap.get(val) || 0) + 1)
|
|
235
257
|
}
|
|
236
|
-
return
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
258
|
+
return statMap
|
|
259
|
+
}
|
|
260
|
+
getMost<K extends keyof statItems>(key: K) {
|
|
261
|
+
const stats = this.getStat(key)
|
|
262
|
+
if (stats.size === 0) return { val: undefined, count: 0 }
|
|
263
|
+
let mostVal: statItems[K] | undefined
|
|
264
|
+
let maxCount = 0
|
|
265
|
+
for (const [val, count] of stats.entries()) {
|
|
266
|
+
if (count > maxCount) {
|
|
267
|
+
maxCount = count
|
|
268
|
+
mostVal = val
|
|
246
269
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return stats
|
|
250
|
-
}
|
|
251
|
-
getMost(key: keyof statItems) {
|
|
252
|
-
return this.getStat(key).toSorted((a, b) => b.count - a.count)[0]
|
|
270
|
+
}
|
|
271
|
+
return { val: mostVal, count: maxCount }
|
|
253
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* @deprecated 使用 `getMost` 代替
|
|
275
|
+
*/
|
|
254
276
|
get most() {
|
|
277
|
+
const keys: (keyof statItems)[] = [
|
|
278
|
+
'mode',
|
|
279
|
+
'fontsize',
|
|
280
|
+
'color',
|
|
281
|
+
'senderID',
|
|
282
|
+
'content',
|
|
283
|
+
'weight',
|
|
284
|
+
'pool',
|
|
285
|
+
'platform',
|
|
286
|
+
]
|
|
287
|
+
const statMaps = new Map<
|
|
288
|
+
keyof statItems,
|
|
289
|
+
Map<statItems[keyof statItems], number>
|
|
290
|
+
>()
|
|
291
|
+
for (const dan of this.dans) {
|
|
292
|
+
for (const key of keys) {
|
|
293
|
+
if (!statMaps.has(key)) {
|
|
294
|
+
statMaps.set(key, new Map())
|
|
295
|
+
}
|
|
296
|
+
const statMap = statMaps.get(key)!
|
|
297
|
+
const val = dan[key]
|
|
298
|
+
statMap.set(val, (statMap.get(val) || 0) + 1)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const result: Record<string, any> = {}
|
|
302
|
+
for (const key of keys) {
|
|
303
|
+
const statMap = statMaps.get(key)!
|
|
304
|
+
let mostVal: statItems[keyof statItems] | undefined
|
|
305
|
+
let maxCount = 0
|
|
306
|
+
for (const [val, count] of statMap.entries()) {
|
|
307
|
+
if (count > maxCount) {
|
|
308
|
+
maxCount = count
|
|
309
|
+
mostVal = val
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
result[key] = mostVal
|
|
313
|
+
}
|
|
255
314
|
return {
|
|
256
|
-
mode:
|
|
257
|
-
fontsize:
|
|
258
|
-
color:
|
|
259
|
-
senderID:
|
|
260
|
-
content:
|
|
261
|
-
weight:
|
|
262
|
-
pool:
|
|
263
|
-
platform:
|
|
315
|
+
mode: result.mode as UniDMTools.Modes,
|
|
316
|
+
fontsize: result.fontsize as number,
|
|
317
|
+
color: result.color as number,
|
|
318
|
+
senderID: result.senderID as string,
|
|
319
|
+
content: result.content as string,
|
|
320
|
+
weight: result.weight as number,
|
|
321
|
+
pool: result.pool as UniDMTools.Pools,
|
|
322
|
+
platform: result.platform as string | undefined,
|
|
264
323
|
}
|
|
265
324
|
}
|
|
266
325
|
static create(options?: Options) {
|
|
@@ -286,7 +345,7 @@ export class UniPool {
|
|
|
286
345
|
* 按共通属性拆分弹幕库
|
|
287
346
|
*/
|
|
288
347
|
split(key: keyof shareItems) {
|
|
289
|
-
if (this.
|
|
348
|
+
if (this.getShared(key)) return [this]
|
|
290
349
|
const set = new Set(this.dans.map((d) => d[key]))
|
|
291
350
|
return [...set].map((v) => {
|
|
292
351
|
return new UniPool(
|
|
@@ -300,6 +359,7 @@ export class UniPool {
|
|
|
300
359
|
* 基于DMID的基本去重功能,用于解决该class下dans为array而非Set的问题
|
|
301
360
|
*/
|
|
302
361
|
private dedupe() {
|
|
362
|
+
// 这里基本上没有性能瓶颈(大文件测试与AI优化下无明显区别)
|
|
303
363
|
if (this.options.dmid !== false) {
|
|
304
364
|
const map = new Map()
|
|
305
365
|
this.dans.forEach((d) => map.set(d.DMID || d.toDMID(), d))
|
|
@@ -312,104 +372,77 @@ export class UniPool {
|
|
|
312
372
|
* @param lifetime 查重时间区段,单位秒 (默认为 0,表示不查重)
|
|
313
373
|
*/
|
|
314
374
|
merge(lifetime = 0) {
|
|
315
|
-
if (!this.
|
|
375
|
+
if (!this.getShared('SOID')) {
|
|
316
376
|
console.error(
|
|
317
377
|
"本功能仅支持同弹幕库内使用,可先 .split('SOID') 在分别使用",
|
|
318
378
|
)
|
|
319
379
|
return this
|
|
320
380
|
}
|
|
321
381
|
if (lifetime <= 0) return this
|
|
322
|
-
const
|
|
323
|
-
|
|
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
|
-
danmaku.extraStr = JSON.stringify(extra)
|
|
354
|
-
cache[key] = danmaku
|
|
355
|
-
mergeObj[key] = extra.danuni.merge
|
|
356
|
-
return [result, cache, mergeObj]
|
|
357
|
-
} else {
|
|
358
|
-
mergeObj[key] = {
|
|
359
|
-
count: 1,
|
|
360
|
-
duration: 0,
|
|
361
|
-
senders: [danmaku.senderID],
|
|
362
|
-
taolu_count: 1,
|
|
363
|
-
taolu_senders: [danmaku.senderID],
|
|
364
|
-
}
|
|
365
|
-
cache[key] = danmaku
|
|
366
|
-
// 初始化merge信息,包含第一个sender
|
|
367
|
-
const extra = danmaku.extra
|
|
368
|
-
extra.danuni = extra.danuni || {}
|
|
369
|
-
extra.danuni.merge = mergeObj[key]
|
|
370
|
-
danmaku.extraStr = JSON.stringify(extra)
|
|
371
|
-
result.push(danmaku)
|
|
372
|
-
return [result, cache, mergeObj]
|
|
382
|
+
const result: UniDM[] = []
|
|
383
|
+
const cache: Record<string, UniDM> = {}
|
|
384
|
+
const mergeObj: Record<string, UniDMTools.ExtraDanUniMerge> = {}
|
|
385
|
+
// 第一遍:合并弹幕
|
|
386
|
+
for (const danmaku of this.dans) {
|
|
387
|
+
const key = `${danmaku.content}|${danmaku.mode}|${danmaku.pool}|${danmaku.platform}`
|
|
388
|
+
const cached = cache[key]
|
|
389
|
+
|
|
390
|
+
if (
|
|
391
|
+
cached &&
|
|
392
|
+
danmaku.progress - cached.progress <= lifetime &&
|
|
393
|
+
danmaku.isSameAs(cached, { skipDanuniMerge: true })
|
|
394
|
+
) {
|
|
395
|
+
// 更新已存在的弹幕
|
|
396
|
+
mergeObj[key].senders.push(danmaku.senderID)
|
|
397
|
+
mergeObj[key].count = mergeObj[key].senders.length
|
|
398
|
+
mergeObj[key].taolu_count = mergeObj[key].count
|
|
399
|
+
mergeObj[key].taolu_senders = mergeObj[key].senders
|
|
400
|
+
mergeObj[key].duration = Number.parseFloat(
|
|
401
|
+
(danmaku.progress - cached.progress).toFixed(3),
|
|
402
|
+
)
|
|
403
|
+
cache[key] = danmaku
|
|
404
|
+
} else {
|
|
405
|
+
// 新弹幕
|
|
406
|
+
mergeObj[key] = {
|
|
407
|
+
count: 1,
|
|
408
|
+
duration: 0,
|
|
409
|
+
senders: [danmaku.senderID],
|
|
410
|
+
taolu_count: 1,
|
|
411
|
+
taolu_senders: [danmaku.senderID],
|
|
373
412
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const key =
|
|
381
|
-
.map((k) => danmaku[k as keyof UniDM])
|
|
382
|
-
.join('|')
|
|
383
|
-
const extra = result[i].extra
|
|
413
|
+
cache[key] = danmaku
|
|
414
|
+
result.push(danmaku)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
// 第二遍:更新 extraStr
|
|
418
|
+
for (const danmaku of result) {
|
|
419
|
+
const key = `${danmaku.content}|${danmaku.mode}|${danmaku.pool}|${danmaku.platform}`
|
|
384
420
|
const mergeData = mergeObj[key]
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
421
|
+
const extra = danmaku.extra
|
|
422
|
+
if (mergeData.count > 1) {
|
|
423
|
+
// 多个发送者:设置为机器人并添加保护标记
|
|
424
|
+
danmaku.senderID = 'merge[bot]@dan-any'
|
|
425
|
+
if (!danmaku.attr) {
|
|
426
|
+
danmaku.attr = [UniDMTools.DMAttr.Protect]
|
|
427
|
+
} else if (!danmaku.attr.includes(UniDMTools.DMAttr.Protect)) {
|
|
428
|
+
danmaku.attr.push(UniDMTools.DMAttr.Protect)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
extra.danuni = extra.danuni || {}
|
|
432
|
+
extra.danuni.merge = mergeData
|
|
433
|
+
danmaku.extraStr = JSON.stringify(extra)
|
|
434
|
+
} else {
|
|
435
|
+
// 单个发送者:清理 merge 字段
|
|
436
|
+
if (extra.danuni?.merge) {
|
|
437
|
+
delete extra.danuni.merge
|
|
438
|
+
if (Object.keys(extra.danuni).length === 0) {
|
|
439
|
+
delete extra.danuni
|
|
400
440
|
}
|
|
401
|
-
result[i].extraStr =
|
|
402
|
-
Object.keys(updatedExtra).length > 0
|
|
403
|
-
? JSON.stringify(updatedExtra)
|
|
404
|
-
: undefined
|
|
405
|
-
} else {
|
|
406
|
-
result[i].senderID = 'merge[bot]@dan-any'
|
|
407
|
-
result[i].attr
|
|
408
|
-
? result[i].attr.push(UniDMTools.DMAttr.Protect)
|
|
409
|
-
: (result[i].attr = [UniDMTools.DMAttr.Protect])
|
|
410
441
|
}
|
|
442
|
+
danmaku.extraStr =
|
|
443
|
+
Object.keys(extra).length > 0 ? JSON.stringify(extra) : undefined
|
|
411
444
|
}
|
|
412
|
-
}
|
|
445
|
+
}
|
|
413
446
|
return new UniPool(result, this.options, this.info)
|
|
414
447
|
}
|
|
415
448
|
minify() {
|
|
@@ -447,6 +480,7 @@ export class UniPool {
|
|
|
447
480
|
} else if (
|
|
448
481
|
json.count &&
|
|
449
482
|
json.comments &&
|
|
483
|
+
Array.isArray(json.comments) &&
|
|
450
484
|
json.comments.every((d) => d.m)
|
|
451
485
|
) {
|
|
452
486
|
return {
|
|
@@ -694,7 +728,7 @@ export class UniPool {
|
|
|
694
728
|
state: 0,
|
|
695
729
|
real_name: 0,
|
|
696
730
|
source: 'k-v',
|
|
697
|
-
danuni: { ...DanUniConvertTipTemplate, data: this.
|
|
731
|
+
danuni: { ...DanUniConvertTipTemplate, data: this.getShared('SOID') },
|
|
698
732
|
d: this.dans.map((dan) => dan.toBiliXML(options)),
|
|
699
733
|
},
|
|
700
734
|
})
|
|
@@ -896,7 +930,7 @@ export class UniPool {
|
|
|
896
930
|
toASS(canvasCtx: CanvasCtx, options?: AssGenOptions): string {
|
|
897
931
|
const defaultOptions: AssGenOptions = { substyle: {} }
|
|
898
932
|
const finalOptions = options ?? defaultOptions
|
|
899
|
-
const fn = this.
|
|
933
|
+
const fn = this.getShared('SOID')
|
|
900
934
|
return generateASS(
|
|
901
935
|
this,
|
|
902
936
|
{ filename: fn, title: fn, ...finalOptions },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by protoc-gen-es v2.
|
|
1
|
+
// @generated by protoc-gen-es v2.10.1 with parameter "target=ts"
|
|
2
2
|
// @generated from file danuni.proto (package danuni.danmaku.v1, syntax proto3)
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ import type { Message } from "@bufbuild/protobuf";
|
|
|
12
12
|
* Describes the file danuni.proto.
|
|
13
13
|
*/
|
|
14
14
|
export const file_danuni: GenFile = /*@__PURE__*/
|
|
15
|
-
fileDesc("
|
|
15
|
+
fileDesc("CgxkYW51bmkucHJvdG8SEWRhbnVuaS5kYW5tYWt1LnYxIjIKCmxpc3REYW5SZXESCgoCSUQYASABKAkSEAoDc2VnGAIgASgFSACIAQFCBgoEX3NlZyLUAgoHRGFubWFrdRIMCgRTT0lEGAEgASgJEgwKBERNSUQYAiABKAkSEAoIcHJvZ3Jlc3MYAyABKAUSJQoEbW9kZRgEIAEoDjIXLmRhbnVuaS5kYW5tYWt1LnYxLk1vZGUSEAoIZm9udHNpemUYBSABKAUSDQoFY29sb3IYBiABKAUSEAoIc2VuZGVySUQYByABKAkSDwoHY29udGVudBgIIAEoCRIpCgVjdGltZRgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASDgoGd2VpZ2h0GAogASgFEiUKBHBvb2wYCyABKA4yFy5kYW51bmkuZGFubWFrdS52MS5Qb29sEgwKBGF0dHIYDCADKAkSFQoIcGxhdGZvcm0YDSABKAlIAIgBARISCgVleHRyYRgOIAEoCUgBiAEBQgsKCV9wbGF0Zm9ybUIICgZfZXh0cmEiPAoMRGFubWFrdVJlcGx5EiwKCGRhbm1ha3VzGAEgAygLMhouZGFudW5pLmRhbm1ha3UudjEuRGFubWFrdSo9CgRNb2RlEgoKBk5vcm1hbBAAEgoKBkJvdHRvbRABEgcKA1RvcBACEgsKB1JldmVyc2UQAxIHCgNFeHQQBCopCgRQb29sEgcKA0RlZhAAEgcKA1N1YhABEgcKA0FkdhACEgYKAkl4EAMyXQoORGFubWFrdVNlcnZpY2USSwoHbGlzdERhbhIdLmRhbnVuaS5kYW5tYWt1LnYxLmxpc3REYW5SZXEaHy5kYW51bmkuZGFubWFrdS52MS5EYW5tYWt1UmVwbHkiAFAAYgZwcm90bzM", [file_google_protobuf_timestamp]);
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @generated from message danuni.danmaku.v1.listDanReq
|
|
@@ -101,9 +101,9 @@ export type Danmaku = Message<"danuni.danmaku.v1.Danmaku"> & {
|
|
|
101
101
|
attr: string[];
|
|
102
102
|
|
|
103
103
|
/**
|
|
104
|
-
* @generated from field: string platform = 13;
|
|
104
|
+
* @generated from field: optional string platform = 13;
|
|
105
105
|
*/
|
|
106
|
-
platform
|
|
106
|
+
platform?: string;
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
109
|
* @generated from field: optional string extra = 14;
|
package/src/utils/dm-gen.ts
CHANGED
|
@@ -562,6 +562,8 @@ export class UniDM {
|
|
|
562
562
|
}
|
|
563
563
|
@Expose()
|
|
564
564
|
isSameAs(dan: UniDM, options?: { skipDanuniMerge?: boolean }): boolean {
|
|
565
|
+
// 引用相同直接返回
|
|
566
|
+
if (this === dan) return true
|
|
565
567
|
// 不支持比较高级弹幕
|
|
566
568
|
if (this.mode === Modes.Ext || dan.mode === Modes.Ext) return false
|
|
567
569
|
// 合并过视为不同,防止存在合并完成弹幕后再次合并造成计数错误
|
|
@@ -586,25 +588,20 @@ export class UniDM {
|
|
|
586
588
|
@Expose()
|
|
587
589
|
minify() {
|
|
588
590
|
type UObj = Partial<UniDMObj> & Pick<UniDMObj, 'SOID'>
|
|
589
|
-
const def
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
if (shouldKeep(key, value)) {
|
|
604
|
-
if (key === 'SOID') continue
|
|
605
|
-
Reflect.set(result, key, value)
|
|
606
|
-
}
|
|
607
|
-
}
|
|
591
|
+
const def = new UniDM()
|
|
592
|
+
const result: UObj = { SOID: this.SOID }
|
|
593
|
+
if (this.progress !== def.progress) result.progress = this.progress
|
|
594
|
+
if (this.mode !== def.mode) result.mode = this.mode
|
|
595
|
+
if (this.fontsize !== def.fontsize) result.fontsize = this.fontsize
|
|
596
|
+
if (this.color !== def.color) result.color = this.color
|
|
597
|
+
if (this.senderID !== def.senderID) result.senderID = this.senderID
|
|
598
|
+
if (this.content !== def.content) result.content = this.content
|
|
599
|
+
if (this.weight !== def.weight) result.weight = this.weight
|
|
600
|
+
if (this.pool !== def.pool) result.pool = this.pool
|
|
601
|
+
if (this.attr.length > 0) result.attr = this.attr
|
|
602
|
+
if (this.platform !== undefined) result.platform = this.platform
|
|
603
|
+
if (this.extraStr && this.extraStr !== '{}') result.extraStr = this.extraStr
|
|
604
|
+
if (this.DMID !== undefined) result.DMID = this.DMID
|
|
608
605
|
return result
|
|
609
606
|
}
|
|
610
607
|
@Expose()
|