Files
DanMuRead/BarrageGrab/Forms/FormView.cs
T

659 lines
25 KiB
C#
Raw Normal View History

2026-08-04 00:10:33 +08:00
using System;
2023-11-23 16:43:21 +08:00
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
2026-08-04 00:10:33 +08:00
using System.IO;
2023-11-23 16:43:21 +08:00
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using BarrageGrab.Forms;
using BarrageGrab.Forms.Models;
using BarrageGrab.Modles.JsonEntity;
using BarrageGrab.Proxy;
2026-08-04 00:10:33 +08:00
using Newtonsoft.Json;
2023-11-23 16:43:21 +08:00
namespace BarrageGrab
{
public partial class FormView : Form
{
static int printCount = 0;
2024-03-29 17:34:14 +08:00
WsBarrageServer barServer = AppRuntime.WsServer;
WssBarrageGrab grab = AppRuntime.WsServer.Grab;
ISystemProxy proxy = AppRuntime.WsServer.Grab.Proxy;
2023-11-23 16:43:21 +08:00
2026-08-04 00:10:33 +08:00
private Panel testPanel;
private ComboBox cmbPlayers;
private ComboBox cmbEventType;
private PictureBox picAvatar;
private TextBox txtPlayerName;
private Label lblPlayerid;
private Button btnGeneratePlayers;
private Panel inputPanel;
private Label lblDynamic1, lblDynamic2;
private TextBox txtDynamic1, txtDynamic2;
private Button btnSendTest;
private Label lblStatus;
2023-11-23 16:43:21 +08:00
public FormView()
{
InitializeComponent();
barServer.OnPrint += WssService_OnPrint;
barServer.Grab.Proxy.OnProxyStatus += Proxy_OnProxyStatus;
AppRuntime.RoomCaches.OnCache += RoomCaches_OnCache;
2026-08-04 00:10:33 +08:00
// 扩大form和panel2高度
this.ClientSize = new Size(687, 650);
this.panel2.Height = 390;
this.panel1.Top = 392;
this.panel1.Height = this.ClientSize.Height - this.panel1.Top - 20;
// 固定panel3高度,不让它随panel2拉伸
this.panel3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
this.panel3.Height = 159;
BuildTestPanel();
// 游戏配置按钮
var btnConfig = new Button
{
Text = "游戏配置",
Width = 100,
Left = 10,
Top = 90
};
btnConfig.Click += (s, e) => { using (var f = new Forms.ConfigEditorForm()) f.ShowDialog(this); };
this.panel3.Controls.Add(btnConfig);
// Settings button
var btnSettings = new Button
{
Text = "设置",
Width = 60,
Left = 120,
Top = 90
};
btnSettings.Click += (s, e) => { using (var f = new Forms.SettingsForm()) f.ShowDialog(this); };
this.panel3.Controls.Add(btnSettings);
// 打开游戏按钮
var btnLaunchGame = new Button
{
Text = "打开游戏",
Width = 80,
Left = 190,
Top = 90
};
btnLaunchGame.Click += (s, e) => { Program.LaunchGame(); };
this.panel3.Controls.Add(btnLaunchGame);
// 重新打开游戏按钮
var btnRestartGame = new Button
{
Text = "重启游戏",
Width = 80,
Left = 280,
Top = 90
};
btnRestartGame.Click += (s, e) => { Program.RestartGame(); };
this.panel3.Controls.Add(btnRestartGame);
2023-11-23 16:43:21 +08:00
}
2026-08-04 00:10:33 +08:00
2023-11-23 16:43:21 +08:00
private void InitTabPages()
{
var msgTypes = GetMsgTypes();
foreach (TabPage page in this.tab_filters.TabPages)
{
page.Padding = new Padding(0)
{
Left = 5
};
page.Margin = new Padding(0);
foreach (Control control in page.Controls)
{
var panel = control as FlowLayoutPanel;
if (panel == null) continue;
panel.Padding = new Padding(0);
panel.Margin = new Padding(0);
foreach (var label in msgTypes)
{
var ck = new CheckBox()
{
Text = label.Value,
Tag = label.Key,
Parent = panel,
Padding = new Padding(0),
Margin = new Padding(0)
};
string type = "console";
if (page == this.tabPage_Ws)
{
type = "ws";
2024-03-29 17:46:24 +08:00
ck.Checked = AppSetting.Current.PushFilter.Contains(label.Key);
2023-11-23 16:43:21 +08:00
}
if (page == this.tabPage_Console)
{
type = "console";
2024-03-29 17:46:24 +08:00
ck.Checked = AppSetting.Current.PrintFilter.Contains(label.Key);
2023-11-23 16:43:21 +08:00
}
if (page == this.tabPage_Log)
{
type = "log";
2024-03-29 17:46:24 +08:00
ck.Checked = AppSetting.Current.LogFilter.Contains(label.Key);
2023-11-23 16:43:21 +08:00
}
ck.Name = $"cbx_bartype_{type}_{label.Key}";
ck.CheckedChanged += Ck_CheckedChanged;
panel.Controls.Add(ck);
}
}
}
}
private void Ck_CheckedChanged(object sender, EventArgs e)
{
CheckBox cbx = sender as CheckBox;
if (cbx == null) return;
2023-11-23 16:43:21 +08:00
var selected = GetCheckedBarTypes((FlowLayoutPanel)cbx.Parent);
if (cbx.Parent.Parent == this.tabPage_Console)
{
2024-03-29 17:46:24 +08:00
AppSetting.Current.PrintFilter = selected;
2023-11-23 16:43:21 +08:00
}
if (cbx.Parent.Parent == this.tabPage_Ws)
{
2024-03-29 17:46:24 +08:00
AppSetting.Current.PushFilter = selected;
2023-11-23 16:43:21 +08:00
}
if (cbx.Parent.Parent == this.tabPage_Log)
2023-11-23 16:43:21 +08:00
{
2024-03-29 17:46:24 +08:00
AppSetting.Current.LogFilter = selected;
2023-11-23 16:43:21 +08:00
}
2024-03-29 17:46:24 +08:00
AppSetting.Current.Save();
2023-11-23 16:43:21 +08:00
}
private int[] GetCheckedBarTypes(FlowLayoutPanel panel)
{
List<int> list = new List<int>();
foreach (Control ctr in panel.Controls)
{
var cbk = ctr as CheckBox;
if (cbk == null) continue;
if (cbk.Checked && cbk.Name.StartsWith("cbx_bartype_"))
{
list.Add((int)cbk.Tag);
}
2023-11-23 16:43:21 +08:00
}
return list.OrderBy(o => o).ToArray();
}
private Dictionary<int, string> GetMsgTypes()
2023-11-23 16:43:21 +08:00
{
var dic = new Dictionary<int, string>();
Type enumType = typeof(PackMsgType);
FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (var field in fields)
{
DescriptionAttribute attribute = (DescriptionAttribute)field.GetCustomAttribute(typeof(DescriptionAttribute), false);
int value = (int)field.GetValue(null);
if (attribute != null && value > 0)
2023-11-23 16:43:21 +08:00
{
dic.Add(value, attribute.Description);
}
}
return dic;
}
private void RoomCaches_OnCache(object sender, AppRuntime.RoomCacheManager.RoomCacheEventArgs e)
{
this.Invoke(new Action(() =>
{
if (e.Model == 0)
{
var item = new RoomCacheItem(e.RoomInfo);
this.label3.Text = $"房间缓存列表({AppRuntime.RoomCaches.RoomInfoCache.Count})";
list_roomCaches.Items.Add(item);
}
}));
2023-11-23 16:43:21 +08:00
}
private void FormView_Load(object sender, EventArgs e)
{
2024-05-16 22:24:45 +08:00
this.txb_wsaddr.Text = barServer.ServerLocation;
this.txb_upstreamProxy.Text = proxy.HttpUpstreamProxy;
this.cbx_barrageLog.Checked = AppSetting.Current.BarrageLog;
InitTabPages();
2023-11-23 16:43:21 +08:00
this.cbx_enableProxy.Checked = SystemProxy.ProxyIsOpen();
}
private void Proxy_OnProxyStatus(object sender, Proxy.ProxyEventArgs.SystemProxyChangeEventArgs e)
{
if (this.Disposing || this.IsDisposed) return;
this.Invoke(new Action(() =>
{
this.cbx_enableProxy.Checked = e.Open;
}));
2023-11-23 16:43:21 +08:00
}
2024-03-29 17:34:14 +08:00
private void WssService_OnPrint(object sender, WsBarrageServer.PrintEventArgs e)
2023-11-23 16:43:21 +08:00
{
//将弹幕输出到richTextBox
//颜色转换
2024-03-29 17:46:24 +08:00
Color color = AppSetting.Current.ColorMap[e.MsgType].Item2;
2023-11-23 16:43:21 +08:00
string msg = e.Message;
this.Invoke(new Action(() =>
{
//输出到richTextBox
this.rich_output.SelectionColor = color;
this.rich_output.AppendText(msg + "\n");
this.rich_output.ScrollToCaret();
if (++printCount > 10000)
{
this.rich_output.Clear();
printCount = 0;
}
}));
2023-11-23 16:43:21 +08:00
}
private void cbx_enableProxy_CheckedChanged(object sender, EventArgs e)
{
var checker = (CheckBox)sender;
if (checker.Checked)
{
barServer.Grab.Proxy.RegisterSystemProxy();
}
else
{
barServer.Grab.Proxy.CloseSystemProxy();
}
}
private void list_roomCaches_DoubleClick(object sender, EventArgs e)
{
// 获取双击的 ListBox 中的选中项
var selectedItem = list_roomCaches.SelectedItem as RoomCacheItem;
if (selectedItem == null) return;
var form = new RoomDetail(selectedItem.RoomInfo);
2023-11-23 16:43:21 +08:00
form.ShowDialog();
}
private void btn_updateUpProxy_Click(object sender, EventArgs e)
{
var text = this.txb_upstreamProxy.Text;
try
{
proxy.SetUpstreamProxy(text);
2024-03-29 17:46:24 +08:00
AppSetting.Current.UpstreamProxy = text;
AppSetting.Current.Save();
2023-11-23 16:43:21 +08:00
}
catch (Exception ex)
{
//弹窗提示错误
MessageBox.Show(ex.Message, "设置失败");
}
2023-11-23 16:43:21 +08:00
}
private void cbx_barrageLog_CheckedChanged(object sender, EventArgs e)
{
var checker = (CheckBox)sender;
2024-03-29 17:46:24 +08:00
AppSetting.Current.BarrageLog = checker.Checked;
AppSetting.Current.Save();
2023-11-23 16:43:21 +08:00
}
2026-08-04 00:10:33 +08:00
// ==================== 测试面板 ====================
private readonly string DefaultAvatarUrl = "https://aliyun_id_photo_bucket.oss.aliyuncs.com/default_handsome_intl.jpg";
private readonly List<(long Id, string Name)> _testPlayers = new List<(long Id, string Name)>();
private static readonly string[] SampleNames = {
"小明", "小红", "玩家001", "铁柱", "翠花", "老六", "大佬666",
"战神", "小可爱", "路人甲", "氪金玩家", "欧皇", "非酋", "主播铁粉",
"水友123", "弹幕刷屏王", "白嫖党", "榜一大哥", "守塔小兵", "运营总监"
};
private void BuildTestPanel()
{
// 测试面板标题
int yBase = 195;
var lblTitle = new Label
{
Text = "📡 WebSocket 模拟测试",
Location = new Point(250, yBase),
Size = new Size(200, 18),
Font = new Font("微软雅黑", 10, FontStyle.Bold),
ForeColor = Color.DarkBlue
};
panel2.Controls.Add(lblTitle);
// ── 生成按钮 ──
btnGeneratePlayers = new Button
{
Text = "随机生成玩家",
Location = new Point(250, yBase + 20),
Size = new Size(130, 24),
BackColor = Color.LightSteelBlue,
UseVisualStyleBackColor = true
};
btnGeneratePlayers.Click += BtnGeneratePlayers_Click;
panel2.Controls.Add(btnGeneratePlayers);
// ── 玩家下拉(含头像) ──
cmbPlayers = new ComboBox
{
Location = new Point(250, yBase + 46),
Size = new Size(310, 22),
DropDownStyle = ComboBoxStyle.DropDownList,
DropDownWidth = 400
};
cmbPlayers.SelectedIndexChanged += CmbPlayers_SelectedIndexChanged;
panel2.Controls.Add(cmbPlayers);
lblPlayerid = new Label
{
Text = "ID: --",
Location = new Point(565, yBase + 48),
Size = new Size(110, 18),
ForeColor = Color.Gray
};
panel2.Controls.Add(lblPlayerid);
// ── 事件类型下拉 ──
var lblEvent = new Label { Text = "事件:", Location = new Point(250, yBase + 74), Size = new Size(40, 20) };
panel2.Controls.Add(lblEvent);
cmbEventType = new ComboBox
{
Location = new Point(290, yBase + 72),
Size = new Size(130, 22),
DropDownStyle = ComboBoxStyle.DropDownList
};
cmbEventType.Items.AddRange(new object[] { "弹幕消息", "点赞消息", "礼物消息", "关注消息", "进直播间", "直播间分享", "粉丝团消息" });
cmbEventType.SelectedIndex = 0;
cmbEventType.SelectedIndexChanged += CmbEventType_SelectedIndexChanged;
panel2.Controls.Add(cmbEventType);
// ── 发送按钮 ──
btnSendTest = new Button
{
Text = "发送",
Location = new Point(430, yBase + 70),
Size = new Size(130, 26),
BackColor = Color.Orange,
Font = new Font("微软雅黑", 9, FontStyle.Bold),
UseVisualStyleBackColor = true
};
btnSendTest.Click += BtnSendTest_Click;
panel2.Controls.Add(btnSendTest);
// ── 动态输入面板 ──
inputPanel = new Panel
{
Location = new Point(248, yBase + 100),
Size = new Size(430, 50),
BorderStyle = BorderStyle.FixedSingle
};
panel2.Controls.Add(inputPanel);
lblDynamic1 = new Label { Location = new Point(8, 8), Size = new Size(50, 18), Text = "内容:" };
inputPanel.Controls.Add(lblDynamic1);
txtDynamic1 = new TextBox { Location = new Point(60, 6), Size = new Size(200, 21), Text = "测试弹幕666" };
inputPanel.Controls.Add(txtDynamic1);
lblDynamic2 = new Label { Location = new Point(8, 30), Size = new Size(50, 18), Text = "" };
inputPanel.Controls.Add(lblDynamic2);
txtDynamic2 = new TextBox { Location = new Point(60, 28), Size = new Size(80, 21), Text = "", Visible = false };
inputPanel.Controls.Add(txtDynamic2);
// ── 状态 ──
lblStatus = new Label
{
Location = new Point(250, yBase + 155),
Size = new Size(425, 18),
ForeColor = Color.DimGray
};
panel2.Controls.Add(lblStatus);
// 初始刷新
RefreshInputPanel();
}
private void BtnGeneratePlayers_Click(object sender, EventArgs e)
{
_testPlayers.Clear();
cmbPlayers.Items.Clear();
var rnd = new Random();
// 生成28个完全随机玩家
for (int i = 0; i < 28; i++)
{
long id = 10000 + rnd.Next(1, 99999);
string name = SampleNames[rnd.Next(SampleNames.Length)];
if (rnd.Next(2) == 0) name += rnd.Next(10, 999).ToString();
_testPlayers.Add((id, name));
cmbPlayers.Items.Add($"{name} (ID:{id})");
}
cmbPlayers.SelectedIndex = 0;
lblStatus.Text = $"已生成 {_testPlayers.Count} 个测试玩家";
}
private void CmbPlayers_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbPlayers.SelectedIndex >= 0 && cmbPlayers.SelectedIndex < _testPlayers.Count)
{
var (id, name) = _testPlayers[cmbPlayers.SelectedIndex];
lblPlayerid.Text = $"ID: {id}";
}
}
private void CmbEventType_SelectedIndexChanged(object sender, EventArgs e)
{
RefreshInputPanel();
}
private void RefreshInputPanel()
{
string evt = cmbEventType.SelectedItem?.ToString() ?? "";
switch (evt)
{
case "弹幕消息":
lblDynamic1.Text = "内容:";
txtDynamic1.Visible = true;
txtDynamic1.Text = "测试弹幕666";
lblDynamic2.Text = "";
txtDynamic2.Visible = false;
break;
case "点赞消息":
lblDynamic1.Text = "点赞数:";
txtDynamic1.Visible = true;
txtDynamic1.Text = "10";
lblDynamic2.Text = "";
txtDynamic2.Visible = false;
break;
case "礼物消息":
lblDynamic1.Text = "礼物名:";
txtDynamic1.Visible = true;
txtDynamic1.Text = "小心心";
lblDynamic2.Text = "数量:";
txtDynamic2.Visible = true;
txtDynamic2.Text = "1";
break;
case "直播间分享":
lblDynamic1.Text = "次数:";
txtDynamic1.Visible = true;
txtDynamic1.Text = "1";
lblDynamic2.Text = "";
txtDynamic2.Visible = false;
break;
default: // 关注/进房/粉丝团
lblDynamic1.Text = "无额外参数";
txtDynamic1.Visible = false;
lblDynamic2.Text = "";
txtDynamic2.Visible = false;
break;
}
}
private void BtnSendTest_Click(object sender, EventArgs e)
{
try
{
if (cmbPlayers.SelectedIndex < 0 || cmbPlayers.SelectedIndex >= _testPlayers.Count)
{
lblStatus.Text = "❌ 请先选择玩家";
return;
}
var (pid, pname) = _testPlayers[cmbPlayers.SelectedIndex];
string evt = cmbEventType.SelectedItem?.ToString() ?? "弹幕消息";
MsgUser user = new MsgUser
{
Id = pid,
Nickname = pname,
HeadImgUrl = DefaultAvatarUrl,
DisplayId = pid.ToString(),
Level = 10,
Gender = 1
};
BarrageMsgPack pack = null;
string desc = "";
switch (evt)
{
case "弹幕消息":
{
var msg = new Msg
{
MsgId = DateTime.Now.Ticks,
User = user,
Content = txtDynamic1.Text,
RoomId = "123456"
};
pack = new BarrageMsgPack(JsonConvert.SerializeObject(msg), PackMsgType.弹幕消息, "test");
desc = $"弹幕: {txtDynamic1.Text}";
}
break;
case "点赞消息":
{
long cnt = long.TryParse(txtDynamic1.Text, out var c) ? c : 1;
var msg = new LikeMsg
{
MsgId = DateTime.Now.Ticks,
User = user,
Count = cnt,
Total = cnt + 100,
RoomId = "123456"
};
pack = new BarrageMsgPack(JsonConvert.SerializeObject(msg), PackMsgType.点赞消息, "test");
desc = $"点赞 x{cnt}";
}
break;
case "礼物消息":
{
long cnt = long.TryParse(txtDynamic2.Text, out var gc) ? gc : 1;
var msg = new GiftMsg
{
MsgId = DateTime.Now.Ticks,
User = user,
GiftName = txtDynamic1.Text,
GiftCount = cnt,
GiftId = 100,
DiamondCount = 1,
RoomId = "123456"
};
pack = new BarrageMsgPack(JsonConvert.SerializeObject(msg), PackMsgType.礼物消息, "test");
desc = $"礼物: {txtDynamic1.Text} x{cnt}";
}
break;
case "关注消息":
{
var msg = new Msg
{
MsgId = DateTime.Now.Ticks,
User = user,
Content = "关注了主播",
RoomId = "123456"
};
pack = new BarrageMsgPack(JsonConvert.SerializeObject(msg), PackMsgType.关注消息, "test");
desc = "关注主播";
}
break;
case "进直播间":
{
var msg = new MemberMessage
{
MsgId = DateTime.Now.Ticks,
User = user,
CurrentCount = 999,
RoomId = "123456"
};
pack = new BarrageMsgPack(JsonConvert.SerializeObject(msg), PackMsgType.进直播间, "test");
desc = "进入直播间";
}
break;
case "直播间分享":
{
long cnt = long.TryParse(txtDynamic1.Text, out var sc) ? sc : 1;
var msg = new ShareMessage
{
MsgId = DateTime.Now.Ticks,
User = user,
ShareType = BarrageGrab.Modles.JsonEntity.ShareType.微信,
RoomId = "123456"
};
desc = $"分享 x{cnt}";
// 分享用次数送多次
for (int i = 0; i < cnt; i++)
{
pack = new BarrageMsgPack(JsonConvert.SerializeObject(msg), PackMsgType.直播间分享, "test");
barServer.Broadcast(pack);
}
lblStatus.Text = $"✅ 已发送: {pname}(ID:{pid}) → {desc}";
return;
}
case "粉丝团消息":
{
var msg = new FansclubMsg
{
MsgId = DateTime.Now.Ticks,
User = user,
Type = 2, // 加入
Level = 1,
RoomId = "123456"
};
pack = new BarrageMsgPack(JsonConvert.SerializeObject(msg), PackMsgType.粉丝团消息, "test");
desc = "加入粉丝团";
}
break;
}
if (pack != null)
{
barServer.Broadcast(pack);
lblStatus.Text = $"✅ 已发送: {pname}(ID:{pid}) → {desc}";
}
}
catch (Exception ex)
{
lblStatus.Text = $"❌ 发送失败: {ex.Message}";
}
}
}
2023-11-23 16:43:21 +08:00
}