Skip to content

Commit

Permalink
Merge pull request #10 from Greesea/main
Browse files Browse the repository at this point in the history
增加转发覆盖前缀,增加转发日志高度设置,增加前缀不符合时的转发日志
  • Loading branch information
FHChen0420 authored Feb 20, 2024
2 parents 0770676 + 98aa7c6 commit 9f5de50
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 39 deletions.
9 changes: 5 additions & 4 deletions const/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ class InternalMessage(Enum):
WEBSOCKET_LISTEN_ON_ERROR = "102" # WebSocket - 连接异常

class SpreadEventTypes(Enum):
START = "0" # 开始转发
STOP = "1" # 停止转发
RECEIVE_TRANSLATED = "2" # 捕获到同传弹幕
SENT = "3" # 已转发处理后的同传弹幕
START = "0" # 开始转发
STOP = "1" # 停止转发
RECEIVE_VALID_TRANSLATED = "2" # 捕获到有效的同传弹幕
RECEIVE_INVALID_TRANSLATED = "3" # 捕获到无效(被过滤)的同传弹幕
SENT = "4" # 已转发处理后的同传弹幕
54 changes: 43 additions & 11 deletions frame/danmu_spread.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from utils.util import UIChange, getTime, setFont
from utils.controls import AutoPanel

UI_ROOT_MARGIN = (8, 8) # Left | Right
UI_ROOT_MARGIN = (0, 8, 8, 8) # Top | Right | Bottom | Left
UI_ROOT_SPACING = 4

class DanmuSpreadFrame(wx.Frame):
Expand Down Expand Up @@ -47,12 +47,17 @@ def __init__(self, parent):
self.SetBackgroundColour(wx.NullColour)

# 根节点
self.sizer = wx.BoxSizer()
self.SetSizer(self.sizer)
verticalBoxSizer = wx.BoxSizer(wx.VERTICAL)
horizontalBoxSizer = wx.BoxSizer()
self.sizer = verticalBoxSizer
self.SetSizer(verticalBoxSizer)
panel = AutoPanel(self, wx.VERTICAL, UI_ROOT_SPACING)
self.sizer.AddSpacer(UI_ROOT_MARGIN[0])
self.sizer.Add(panel)
self.sizer.AddSpacer(UI_ROOT_MARGIN[1])
verticalBoxSizer.AddSpacer(UI_ROOT_MARGIN[0])
verticalBoxSizer.Add(horizontalBoxSizer)
verticalBoxSizer.AddSpacer(UI_ROOT_MARGIN[2])
horizontalBoxSizer.AddSpacer(UI_ROOT_MARGIN[3])
horizontalBoxSizer.Add(panel)
horizontalBoxSizer.AddSpacer(UI_ROOT_MARGIN[1])

# 提示信息
infoRow = panel.AddToSizer(AutoPanel(panel, spacing = 12), flag = wx.EXPAND)
Expand Down Expand Up @@ -147,7 +152,7 @@ def ShowSpreadFilter(self,event):
lblFilter=event.GetEventObject()
slot,index=lblFilter.GetName().split(";")
if self.spreadFilter:
self.spreadFilter.Destory()
self.spreadFilter.Destroy()
self.spreadFilter=SpreadFilterFrame(self,int(slot),int(index))

def SelectRoom(self,slot,index,roomid):
Expand All @@ -158,10 +163,12 @@ def SelectRoom(self,slot,index,roomid):
if index>0 and old_rid!=roomid:
self.configs[slot][2][index-1]=""
self.configs[slot][3][index-1]=0
self.configs[slot][4][index-1]=False
else:
self.configs[slot][0].append(roomid)
self.configs[slot][2].append("")
self.configs[slot][3].append(0)
self.configs[slot][4].append(False)
if index>0 and self.configs[slot][1]:
if roomid not in self.websockets.keys():
self.websockets[roomid]=BiliLiveWebSocket(roomid)
Expand Down Expand Up @@ -289,11 +296,21 @@ def AppendLogToLogViewer(self, content, color):
self.tcLogViewer.AppendText("{lineWrap}{content}".format(content = content, lineWrap = "\n" if len(self.tcLogViewer.GetValue()) > 0 else ""))

def OnMessageCoreConfigUpdated(self, before, after):
shouldResize = False

if before["spread_logviewer_enabled"] != after["spread_logviewer_enabled"]:
self.tcLogViewer.Show(after["spread_logviewer_enabled"])
self.FitSizeForContent()
shouldResize = True

self.logViewerVerboseMode = after["spread_logviewer_verbose"]

if before["spread_logviewer_height"] != after["spread_logviewer_height"]:
self.tcLogViewer.SetMinSize((-1, after["spread_logviewer_height"]))
shouldResize = True

if shouldResize:
self.FitSizeForContent()

def OnMessageSpreadEvent(self, eventType: SpreadEventTypes, eventData):
internalTimeText = getTime(eventData["internalTime"])
internalData = eventData["internalData"]
Expand All @@ -317,7 +334,7 @@ def OnMessageSpreadEvent(self, eventType: SpreadEventTypes, eventData):
}),
"tan",
)
elif eventType == SpreadEventTypes.RECEIVE_TRANSLATED:
elif eventType == SpreadEventTypes.RECEIVE_VALID_TRANSLATED:
if self.logViewerVerboseMode:
self.AppendLogToLogViewer(
"{internalTimeText} | #{slot}.{fromRoomFull} | 捕获到:{rawContent}".format(**{
Expand All @@ -328,6 +345,17 @@ def OnMessageSpreadEvent(self, eventType: SpreadEventTypes, eventData):
}),
"gray",
)
elif eventType == SpreadEventTypes.RECEIVE_INVALID_TRANSLATED:
if self.logViewerVerboseMode:
self.AppendLogToLogViewer(
"{internalTimeText} | #{slot}.{fromRoomFull} | 捕获到前缀不符:{rawContent}".format(**{
"internalTimeText": internalTimeText,
"slot": slot,
"fromRoomFull": internalData["fromRoom"]["full"],
"rawContent": internalData["rawContent"],
}),
"gray",
)
elif eventType == SpreadEventTypes.SENT:
style = ERR_INFO[eventData["result"]]
self.AppendLogToLogViewer(
Expand Down Expand Up @@ -375,7 +403,7 @@ def __init__(self, parent, slot, index):
self.index=index
pos=parent.GetPosition()
x,y=pos[0]+50,pos[1]+60
wx.Frame.__init__(self, parent, title="房间转发设置", pos=(x,y), size=(300, 170),
wx.Frame.__init__(self, parent, title="房间转发设置", pos=(x,y), size=(300, 220),
style=wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX) |wx.FRAME_FLOAT_ON_PARENT)
if parent.show_pin:
self.ToggleWindowStyle(wx.STAY_ON_TOP)
Expand All @@ -391,7 +419,10 @@ def __init__(self, parent, slot, index):
speakers=self.configs[slot][2][index]
self.tcFilter=wx.TextCtrl(panel,-1,speakers,pos=(68,38),size=(210,27),style=wx.TE_PROCESS_ENTER)
self.tcFilter.Bind(wx.EVT_TEXT_ENTER,self.Save)
self.btnSave=wx.Button(panel,-1,"保 存",pos=(105,105),size=(80,32))
wx.StaticText(panel,-1,"覆盖前缀",pos=(10,110))
self.ckbOverride=wx.CheckBox(panel, -1, "使用主播简称覆盖原本前缀",pos=(68,110))
self.ckbOverride.SetValue(self.configs[slot][4][index])
self.btnSave=wx.Button(panel,-1,"保 存",pos=(105,145),size=(80,32))
self.btnSave.Bind(wx.EVT_BUTTON,self.Save)
self.Show()

Expand All @@ -405,4 +436,5 @@ def Save(self,event):
speakers="" if speakers==";" else speakers
self.configs[self.slot][2][self.index]=speakers
self.configs[self.slot][3][self.index]=self.sldDelay.GetValue()*100
self.configs[self.slot][4][self.index]=self.ckbOverride.GetValue()
self.Parent.RefreshUI() #该方法包含销毁本窗体的语句
11 changes: 10 additions & 1 deletion frame/general_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ def InitializeUINotebookPage(panel: wx.Panel):
row.AddToSizer(innerRow, 1, wx.EXPAND)
innerRow.AddToSizer(wx.StaticText(innerRow,-1,"字数要求"))
self.tcStatWords = innerRow.AddToSizer(wx.TextCtrl(innerRow,-1,str(parent.tl_stat_min_word_num),size=(40,22)))
innerRow.AddSpacing(8)
innerRow.AddToSizer(wx.StaticText(innerRow,-1,"弹幕数要求"))
self.tcStatCount = innerRow.AddToSizer(wx.TextCtrl(innerRow,-1,str(parent.tl_stat_min_count),size=(40,22)))

Expand All @@ -233,8 +234,12 @@ def InitializeUINotebookPage(panel: wx.Panel):

row.AddToSizer(wx.StaticText(row,-1,"数量修改后将重置当前转发配置")).SetForegroundColour("grey")

self.ckbSpreadLogViewerEnabled = row.AddToSizer(wx.CheckBox(row, -1, "启用转发日志"))
innerRow = AutoPanel(row)
row.AddToSizer(innerRow, 1, wx.EXPAND)
self.ckbSpreadLogViewerEnabled = innerRow.AddToSizer(wx.CheckBox(innerRow, -1, "启用转发日志"))
self.ckbSpreadLogViewerEnabled.SetValue(parent.spread_logviewer_enabled)
innerRow.AddToSizer(wx.StaticText(innerRow, -1, "高度"))
self.tcSpreadLogViewerHeight = innerRow.AddToSizer(wx.TextCtrl(innerRow, -1, str(parent.spread_logviewer_height), size=(40,22)))

self.ckbSpreadLogViewerVerbose = row.AddToSizer(wx.CheckBox(row, -1, "详细转发日志"))
self.ckbSpreadLogViewerVerbose.SetValue(parent.spread_logviewer_verbose)
Expand Down Expand Up @@ -411,6 +416,10 @@ def OnClose(self,event):

# 转发相关
parent.spread_logviewer_enabled=self.ckbSpreadLogViewerEnabled.GetValue()
try:
value=int(self.tcSpreadLogViewerHeight.GetValue().strip())
parent.spread_logviewer_height=min(3000, max(1, value))
except: pass
parent.spread_logviewer_verbose=self.ckbSpreadLogViewerVerbose.GetValue()
try:
value=int(self.tcSpreadMaximumSpreadRooms.GetValue().strip())
Expand Down
64 changes: 41 additions & 23 deletions frame/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ def DefaultConfig(self):
self.app_bottom_danmu = True # 是否将发出的弹幕在APP端置底
self.cancel_danmu_after_failed = True # 长句前半段发送失败后是否取消后半段的发送
self.spread_logviewer_enabled = False # 转发:是否启用转发日志
self.spread_logviewer_height = 240 # 转发:转发日志高度
self.spread_logviewer_verbose = False # 转发:是否详细转发日志
self.spread_maximum_spread_rooms = 3 # 转发:最大转发房间数
self.spread_maximum_listen_rooms = 5 # 转发:最大监听房间数
Expand Down Expand Up @@ -947,7 +948,7 @@ def OnMessageCoreConfigUpdated(self, before, after):
self.danmuSpreadFrame.StopAll()
self.danmuSpreadFrame.Close()
self.danmuSpreadFrame.Destroy()
self.sp_configs = [[[None],False,[],[]] for _ in range(self.spread_maximum_spread_rooms)] # 同传转发配置列表 每项为[房间号列表,转发开关,限定前缀列表,转发延时列表]
self.sp_configs = [[[None],False,[],[],[]] for _ in range(self.spread_maximum_spread_rooms)] # 同传转发配置列表 每项为[房间号列表,转发开关,限定前缀列表,转发延时列表,覆盖前缀开关列表]
self.danmuSpreadFrame = DanmuSpreadFrame(self)


Expand Down Expand Up @@ -1273,28 +1274,24 @@ def SpreadDanmu(self,roomid,speaker,content,rawContent):
if not self.GetCurrentDanmuConfig(roomid):
self.sp_max_len=20
for slot, cfg in enumerate(self.sp_configs):
to_room,from_rooms,spreading,speaker_filters,delays=cfg[0][0],cfg[0][1:],cfg[1],cfg[2],cfg[3]
to_room,from_rooms,spreading,speaker_filters,delays,override_toggles=cfg[0][0],cfg[0][1:],cfg[1],cfg[2],cfg[3],cfg[4]
if not spreading or to_room is None or roomid not in from_rooms: continue
speaker=self.sp_rooms[roomid][1] if not speaker else speaker
sp_delay_ms=0
# 如果前缀过滤条件不为空,则只转发指定的前缀
speaker_be_filtered=False
for from_roomid,allowed_speakers,delay in zip(from_rooms,speaker_filters,delays):
if roomid==from_roomid:
sp_delay_ms=delay
else:
continue
if allowed_speakers=="":

spreadConfigs = {
"delay": 0, # 转发延迟
"speakerNotMatch": False, # 限定前缀是否不匹配
"speakerOverride": False, # 是否覆盖前缀
}

for from_roomid,allowed_speakers,delay,override in zip(from_rooms,speaker_filters,delays,override_toggles):
if roomid != from_roomid: # room not match
continue
if speaker not in allowed_speakers.split(";"):
speaker_be_filtered=True
if allowed_speakers != "" and speaker not in allowed_speakers.split(";"): # 如果前缀过滤条件不为空,则只转发指定的前缀
spreadConfigs["speakerNotMatch"] = True
break
if speaker_be_filtered:
continue
# 弹幕开头添加标识符U+0592避免循环转发(本工具不会转发以U+0592开头的同传弹幕)
pre="\u0592"+speaker+"【"
msg=self.AntiShield(pre+content,to_room)
suf="】" if msg.count("【")>msg.count("】") else ""
spreadConfigs["delay"] = delay
spreadConfigs["speakerOverride"] = override

# 准备数据
internalData = {
Expand All @@ -1311,16 +1308,33 @@ def SpreadDanmu(self,roomid,speaker,content,rawContent):
"short": self.sp_rooms[to_room][1],
},
"content": content,
"sendContent": msg,
"rawContent": rawContent,
}
pub.sendMessage(InternalMessage.SPREAD_EVENT.value, eventType = SpreadEventTypes.RECEIVE_TRANSLATED, eventData = {

if spreadConfigs["speakerNotMatch"]:
pub.sendMessage(InternalMessage.SPREAD_EVENT.value, eventType = SpreadEventTypes.RECEIVE_INVALID_TRANSLATED, eventData = {
"internalTime": int(time.time()),
"internalData": internalData,
})
continue

# 构成实际发送弹幕
# 弹幕开头添加标识符U+0592避免循环转发(本工具不会转发以U+0592开头的同传弹幕)
actualSpeaker = internalData["fromRoom"]["short"] if spreadConfigs["speakerOverride"] else speaker
pre="\u0592"+actualSpeaker+"【"
msg=self.AntiShield(pre+content,to_room)
suf="】" if msg.count("【")>msg.count("】") else ""

pub.sendMessage(InternalMessage.SPREAD_EVENT.value, eventType = SpreadEventTypes.RECEIVE_VALID_TRANSLATED, eventData = {
"internalTime": int(time.time()),
"internalData": internalData,
"internalData": {
**internalData,
"sendContent": msg,
},
})

# 延迟指定毫秒数后,将弹幕添加到队列
self.pool_dm.submit(self.ThreadOfDelayDanmuQueue,sp_delay_ms,to_room,msg,DanmuSrc.SPREAD,pre,suf,self.sp_max_len,internalData)
self.pool_dm.submit(self.ThreadOfDelayDanmuQueue,spreadConfigs["delay"],to_room,msg,DanmuSrc.SPREAD,pre,suf,self.sp_max_len,internalData)

def StartListening(self,roomid):
"""建立与直播间之间的Websocket连接"""
Expand Down Expand Up @@ -1935,6 +1949,8 @@ def ReadFile(self):
self.spread_maximum_listen_rooms = min(20, max(1, int(v)))
elif k == "启用转发日志":
self.spread_logviewer_enabled = v.lower()=="true"
elif k == "转发日志高度":
self.spread_logviewer_height = min(3000, max(1, int(v)))
elif k == "详细转发日志":
self.spread_logviewer_verbose = v.lower()=="true"
except Exception:
Expand Down Expand Up @@ -2169,6 +2185,7 @@ def titleLine(title): return "%s\n#%s#\n%s\n"%("-"*15,title,"-"*15)
f.write("最大转发房间数=%d\n" % self.spread_maximum_spread_rooms)
f.write("最大监听房间数=%d\n" % self.spread_maximum_listen_rooms)
f.write("启用转发日志=%s\n" % self.spread_logviewer_enabled)
f.write("转发日志高度=%d\n" % self.spread_logviewer_height)
f.write("详细转发日志=%s\n" % self.spread_logviewer_verbose)
f.write(titleLine("弹幕记录配置"))
f.write("彩色弹幕记录=%s\n" % self.enable_rich_record)
Expand Down Expand Up @@ -2261,6 +2278,7 @@ def GenerateConfigSnapshot(self, schemeOnly = False):
"cancel_danmu_after_failed",
"qq_new_api",
"spread_logviewer_enabled",
"spread_logviewer_height",
"spread_logviewer_verbose",
"spread_maximum_spread_rooms",
"spread_maximum_listen_rooms",
Expand Down
3 changes: 3 additions & 0 deletions utils/controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ def AddToSizer(self, control, *args, **kw):
if self.__sizer.GetItemCount() > 0:
self.__sizer.AddSpacer(self.__spacing)
return self.AddToSizerWithoutSpacing(control, *args, **kw)

def AddSpacing(self, spacing = 0):
self.__sizer.AddSpacer(spacing)

0 comments on commit 9f5de50

Please sign in to comment.