opt: danmaku filter (#486)

This commit is contained in:
My-Responsitories
2025-03-23 12:07:57 +08:00
committed by GitHub
parent 066f3d4132
commit 99b14d0f0e
9 changed files with 141 additions and 189 deletions

View File

@@ -1,5 +1,5 @@
class DanmakuBlockDataModel {
List<Rule>? rule;
List<SimpleRule>? rule;
String? toast;
int? valid;
int? ver;
@@ -7,88 +7,22 @@ class DanmakuBlockDataModel {
DanmakuBlockDataModel({this.rule, this.toast, this.valid, this.ver});
DanmakuBlockDataModel.fromJson(Map<String, dynamic> json) {
if (json['rule'] != null) {
rule = <Rule>[];
json['rule'].forEach((v) {
rule!.add(Rule.fromJson(v));
});
}
rule = (json['rule'] as List?)?.map((v) => SimpleRule.fromJson(v)).toList();
toast = json['toast'];
valid = json['valid'];
ver = json['ver'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (rule != null) {
data['rule'] = rule!.map((v) => v.toJson()).toList();
}
data['toast'] = toast;
data['valid'] = valid;
data['ver'] = ver;
return data;
}
}
class Rule {
int? id;
int? mid;
int? type;
String? filter;
String? comment;
int? ctime;
int? mtime;
Rule(
{this.id,
this.mid,
this.type,
this.filter,
this.comment,
this.ctime,
this.mtime});
Rule.fromJson(Map<String, dynamic> json) {
id = json['id'];
mid = json['mid'];
type = json['type'];
filter = json['filter'];
comment = json['comment'];
ctime = json['ctime'];
mtime = json['mtime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['mid'] = mid;
data['type'] = type;
data['filter'] = filter;
data['comment'] = comment;
data['ctime'] = ctime;
data['mtime'] = mtime;
return data;
}
}
class SimpleRule {
final int id;
final int type;
String filter;
late final int id;
late final int type;
late String filter;
SimpleRule(this.id, this.type, this.filter);
Map<String, dynamic> toMap() {
return {
'id': id,
'type': type,
'filter': filter,
};
}
factory SimpleRule.fromMap(Map<String, dynamic> map) {
return SimpleRule(
map['id'],
map['type'],
map['filter'],
);
SimpleRule.fromJson(Map<String, dynamic> json) {
id = json['id'];
type = json['type'];
filter = json['filter'];
}
}

View File

@@ -0,0 +1,44 @@
import 'package:PiliPlus/grpc/dm/v1/dm.pb.dart';
class RuleFilter {
static final _regExp = RegExp(r'^/(.*)/$');
List<String> dmFilterString = [];
List<RegExp> dmRegExp = [];
Set<String> dmUid = {};
int count = 0;
RuleFilter(this.dmFilterString, this.dmRegExp, this.dmUid, [int? count]) {
this.count =
count ?? dmFilterString.length + dmRegExp.length + dmUid.length;
}
RuleFilter.fromRuleTypeEntires(
Iterable<MapEntry<int, Map<int, String>>> rules) {
for (var rule in rules) {
switch (rule.key) {
case 0:
dmFilterString.addAll(rule.value.values);
break;
case 1:
dmRegExp.addAll(rule.value.values.map((i) => RegExp(
_regExp.matchAsPrefix(i)?.group(1) ?? i,
caseSensitive: false)));
break;
case 2:
dmUid.addAll(rule.value.values);
break;
}
}
count = dmFilterString.length + dmRegExp.length + dmUid.length;
}
RuleFilter.empty();
bool retain(DanmakuElem elem) {
return !(dmUid.contains(elem.midHash) ||
dmFilterString.any((i) => elem.content.contains(i)) ||
dmRegExp.any((i) => i.hasMatch(elem.content)));
}
}

View File

@@ -0,0 +1,36 @@
import 'package:PiliPlus/models/user/danmaku_rule.dart';
import 'package:hive/hive.dart';
class RuleFilterAdapter extends TypeAdapter<RuleFilter> {
@override
final int typeId = 12;
@override
RuleFilter read(BinaryReader reader) {
return RuleFilter(
reader.readStringList(),
reader
.readStringList()
.map((i) => RegExp(i, caseSensitive: false))
.toList(),
reader.readStringList().toSet());
}
@override
void write(BinaryWriter writer, RuleFilter obj) {
writer
..writeStringList(obj.dmFilterString)
..writeStringList(obj.dmRegExp.map((i) => i.pattern).toList())
..writeStringList(obj.dmUid.toList());
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is RuleFilterAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}