添加项目文件。
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<!--过滤Websocket数据源进程,可用','进行分隔,程序将会监听以下进程的弹幕信息-->
|
||||
<add key="filterProcess" value="直播伴侣"/>
|
||||
<!--Websocket监听端口-->
|
||||
<add key="wsListenPort" value="8888"/>
|
||||
</appSettings>
|
||||
</configuration>
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Configuration.ConfigurationManager;
|
||||
namespace BarrageGrab
|
||||
{
|
||||
internal class Appsetting
|
||||
{
|
||||
private static readonly Appsetting ins = new Appsetting();
|
||||
|
||||
public static Appsetting Get()
|
||||
{
|
||||
return ins;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 过滤的进程
|
||||
/// </summary>
|
||||
public string[] FilterProcess { get => AppSettings["filterProcess"].Trim().Split(','); }
|
||||
|
||||
/// <summary>
|
||||
/// 端口号
|
||||
/// </summary>
|
||||
public int WsProt { get => int.Parse(AppSettings["wsListenPort"]); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ColorConsole;
|
||||
using Fiddler;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace BarrageGrab
|
||||
{
|
||||
/// <summary>
|
||||
/// FiddlerCore 代理程序
|
||||
/// </summary>
|
||||
internal class FiddlerProxy : IDisposable
|
||||
{
|
||||
bool disposed = false;
|
||||
public event EventHandler<WsMessageEventArgs> OnWebSocketData;
|
||||
ConsoleWriter console = new ConsoleWriter();
|
||||
|
||||
public FiddlerProxy()
|
||||
{
|
||||
InitFiddler();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动代理监听
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
FiddlerApplication.Startup(8887, FiddlerCoreStartupFlags.Default);
|
||||
console.WriteLine("Fiddler代理已启动", ConsoleColor.Green);
|
||||
}
|
||||
|
||||
//初始化Fiddler
|
||||
private void InitFiddler()
|
||||
{
|
||||
//这个名字随便
|
||||
FiddlerApplication.SetAppDisplayName("FiddlerCore");
|
||||
FiddlerApplication.OnWebSocketMessage += FiddlerApplication_OnWebSocketMessage;
|
||||
|
||||
X509Certificate2 oRootCert;
|
||||
if (null == CertMaker.GetRootCertificate())
|
||||
{
|
||||
CertMaker.createRootCert();
|
||||
oRootCert = CertMaker.GetRootCertificate();
|
||||
X509Store certStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
|
||||
certStore.Open(OpenFlags.ReadWrite);
|
||||
try
|
||||
{
|
||||
certStore.Add(oRootCert);
|
||||
}
|
||||
finally
|
||||
{
|
||||
certStore.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oRootCert = CertMaker.GetRootCertificate();
|
||||
}
|
||||
FiddlerApplication.oDefaultClientCertificate = oRootCert;
|
||||
//忽略服务器证书错误
|
||||
CONFIG.IgnoreServerCertErrors = true;
|
||||
//信任证书
|
||||
CertMaker.trustRootCert();
|
||||
}
|
||||
|
||||
private void FiddlerApplication_OnWebSocketMessage(object sender, WebSocketMessageEventArgs e)
|
||||
{
|
||||
var msg = e.oWSM;
|
||||
OnWebSocketData?.Invoke(this, new WsMessageEventArgs(msg));
|
||||
}
|
||||
|
||||
[DllImport(@"wininet", SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "InternetSetOption", CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern bool InternetSetOption(int hInternet, int dmOption, IntPtr lpBuffer, int dwBufferLength);
|
||||
private static void CloseSystemProxy()
|
||||
{
|
||||
//打开注册表
|
||||
var regKey = Registry.CurrentUser;
|
||||
|
||||
const string subKeyPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
|
||||
var optionKey = regKey.OpenSubKey(subKeyPath, true);
|
||||
//更改健值,设置代理,
|
||||
if (optionKey != null) optionKey.SetValue("ProxyEnable", 0);
|
||||
|
||||
//激活代理设置
|
||||
InternetSetOption(0, 39, IntPtr.Zero, 0);
|
||||
InternetSetOption(0, 37, IntPtr.Zero, 0);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed) return;
|
||||
FiddlerApplication.Shutdown();
|
||||
CloseSystemProxy();
|
||||
console.WriteLine("Fiddler代理已关闭");
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
|
||||
public class WsMessageEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息体
|
||||
/// </summary>
|
||||
public WebSocketMessage Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进程ID
|
||||
/// </summary>
|
||||
public int ProcessID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进程名
|
||||
/// </summary>
|
||||
public string ProcessName { get; set; }
|
||||
|
||||
|
||||
public WsMessageEventArgs(WebSocketMessage msg)
|
||||
{
|
||||
this.Message = msg;
|
||||
|
||||
FieldInfo field = msg.GetType().GetField("_wsOwner", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
WebSocket obj = (WebSocket)field.GetValue(msg);
|
||||
field = obj.GetType().GetField("oCP", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
ClientPipe ocp = (ClientPipe)field.GetValue(obj);
|
||||
|
||||
this.ProcessID = ocp.LocalProcessID;
|
||||
this.ProcessName = ocp.LocalProcessName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
namespace BarrageGrab.JsonEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 弹幕消息类型
|
||||
/// </summary>
|
||||
public enum BarrageMsgType
|
||||
{
|
||||
无 = 0,
|
||||
消息,
|
||||
点赞,
|
||||
进入直播间,
|
||||
关注主播,
|
||||
送礼
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据包装器
|
||||
/// </summary>
|
||||
public class BarrageMsgPack
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息类型
|
||||
/// </summary>
|
||||
public BarrageMsgType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息对象
|
||||
/// </summary>
|
||||
public string Data { get; set; }
|
||||
|
||||
public BarrageMsgPack()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public BarrageMsgPack(string data, BarrageMsgType type)
|
||||
{
|
||||
this.Data = data;
|
||||
this.Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息
|
||||
/// </summary>
|
||||
public class Msg
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户数据
|
||||
/// </summary>
|
||||
public MsgUser User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息内容
|
||||
/// </summary>
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 房间号
|
||||
/// </summary>
|
||||
public long RoomId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户弹幕信息
|
||||
/// </summary>
|
||||
public class MsgUser
|
||||
{
|
||||
/// <summary>
|
||||
/// 真实ID
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义ID
|
||||
/// </summary>
|
||||
public string DisplayId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
/// </summary>
|
||||
public string Nickname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别 1男 2女
|
||||
/// </summary>
|
||||
public int Gender { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 礼物消息
|
||||
/// </summary>
|
||||
public class GiftMsg : Msg
|
||||
{
|
||||
/// <summary>
|
||||
/// 礼物ID
|
||||
/// </summary>
|
||||
public long GiftId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 礼物名称
|
||||
/// </summary>
|
||||
public string GiftName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 礼物数量
|
||||
/// </summary>
|
||||
public long GiftCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 抖币价格
|
||||
/// </summary>
|
||||
public int GiamondCount { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点赞消息
|
||||
/// </summary>
|
||||
public class LikeMsg : Msg
|
||||
{
|
||||
/// <summary>
|
||||
/// 点赞数量
|
||||
/// </summary>
|
||||
public long Count { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BarrageGrab
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private delegate bool ControlCtrlDelegate(int CtrlType);
|
||||
|
||||
static WssBarrageService server = null;
|
||||
static void Main(string[] args)
|
||||
{
|
||||
SetConsoleCtrlHandler(cancelHandler, true);//捕获控制台关闭
|
||||
|
||||
server = new WssBarrageService();
|
||||
server.StartListen();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var input = Console.ReadKey();
|
||||
switch (input.Key)
|
||||
{
|
||||
case ConsoleKey.Escape: goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
Console.ReadKey();
|
||||
Console.WriteLine("服务器已正常关闭,按任意键结束...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);
|
||||
private static ControlCtrlDelegate cancelHandler = new ControlCtrlDelegate(HandlerRoutine);
|
||||
|
||||
public static bool HandlerRoutine(int CtrlType)
|
||||
{
|
||||
switch (CtrlType)
|
||||
{
|
||||
case 0:
|
||||
//Console.WriteLine("0工具被强制关闭"); //Ctrl+C关闭
|
||||
//server.Close();
|
||||
break;
|
||||
case 2:
|
||||
Console.WriteLine("2工具被强制关闭");//按控制台关闭按钮关闭
|
||||
server.Close();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("LiveCompanionBarrageGrab")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("LiveCompanionBarrageGrab")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2022")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("a07bb1da-d5c2-4eea-9f3f-e42aadb9c1d6")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC 清单选项
|
||||
如果想要更改 Windows 用户帐户控制级别,请使用
|
||||
以下节点之一替换 requestedExecutionLevel 节点。
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
|
||||
如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此
|
||||
元素。
|
||||
-->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
<applicationRequestMinimum>
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
|
||||
</applicationRequestMinimum>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
|
||||
Windows 版本的列表。取消评论适当的元素,
|
||||
Windows 将自动选择最兼容的环境。 -->
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
<!-- Windows 7 -->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||
<!-- Windows 8 -->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||
<!-- Windows 8.1 -->
|
||||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||
<!-- Windows 10 -->
|
||||
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
|
||||
</application>
|
||||
</compatibility>
|
||||
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
|
||||
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需
|
||||
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
|
||||
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
|
||||
|
||||
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
|
||||
<!--
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
-->
|
||||
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
</assembly>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
// <auto-generated>
|
||||
// This file was generated by a tool; you should avoid making direct changes.
|
||||
// Consider using 'partial classes' to extend these types
|
||||
// Input: my.proto
|
||||
// </auto-generated>
|
||||
|
||||
namespace BarrageGrab.ProtoEntity
|
||||
{
|
||||
#region Designer generated code
|
||||
#pragma warning disable CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
|
||||
[global::ProtoBuf.ProtoContract()]
|
||||
public partial class WssResponse : global::ProtoBuf.IExtensible
|
||||
{
|
||||
private global::ProtoBuf.IExtension __pbn__extensionData;
|
||||
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
|
||||
=> global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
|
||||
|
||||
[global::ProtoBuf.ProtoMember(1, Name = @"seqid")]
|
||||
public ulong Seqid { get; set; }
|
||||
|
||||
[global::ProtoBuf.ProtoMember(2, Name = @"logid")]
|
||||
public ulong Logid { get; set; }
|
||||
|
||||
[global::ProtoBuf.ProtoMember(3, Name = @"service")]
|
||||
public ulong Service { get; set; }
|
||||
|
||||
[global::ProtoBuf.ProtoMember(4, Name = @"method")]
|
||||
public ulong Method { get; set; }
|
||||
|
||||
[global::ProtoBuf.ProtoMember(5, Name = @"headers")]
|
||||
[global::ProtoBuf.ProtoMap]
|
||||
public global::System.Collections.Generic.Dictionary<string, string> Headers { get; } = new global::System.Collections.Generic.Dictionary<string, string>();
|
||||
|
||||
[global::ProtoBuf.ProtoMember(6)]
|
||||
[global::System.ComponentModel.DefaultValue("")]
|
||||
public string payloadEncoding { get; set; } = "";
|
||||
|
||||
[global::ProtoBuf.ProtoMember(7)]
|
||||
[global::System.ComponentModel.DefaultValue("")]
|
||||
public string payloadType { get; set; } = "";
|
||||
|
||||
[global::ProtoBuf.ProtoMember(8, Name = @"payload")]
|
||||
public byte[] Payload { get; set; }
|
||||
|
||||
}
|
||||
|
||||
#pragma warning restore CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BarrageGrab.ProtoEntity;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace BarrageGrab
|
||||
{
|
||||
/// <summary>
|
||||
/// 本机Wss弹幕抓取器
|
||||
/// </summary>
|
||||
public class WssBarrageGrab : IDisposable
|
||||
{
|
||||
FiddlerProxy proxy = new FiddlerProxy();
|
||||
Appsetting appsetting = Appsetting.Get();
|
||||
|
||||
/// <summary>
|
||||
/// 进入直播间
|
||||
/// </summary>
|
||||
public event EventHandler<MemberMessage> OnMemberMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 关注
|
||||
/// </summary>
|
||||
public event EventHandler<SocialMessage> OnSocialMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 聊天
|
||||
/// </summary>
|
||||
public event EventHandler<ChatMessage> OnChatMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 点赞
|
||||
/// </summary>
|
||||
public event EventHandler<LikeMessage> OnLikeMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 礼物
|
||||
/// </summary>
|
||||
public event EventHandler<GiftMessage> OnGiftMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 直播间统计
|
||||
/// </summary>
|
||||
public event EventHandler<RoomUserSeqMessage> OnRoomUserSeqMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 直播间状态变更
|
||||
/// </summary>
|
||||
public event EventHandler<ControlMessage> OnControlMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 粉丝团消息
|
||||
/// </summary>
|
||||
public event EventHandler<FansclubMessage> OnFansclubMessage;
|
||||
|
||||
public WssBarrageGrab()
|
||||
{
|
||||
proxy.OnWebSocketData += Proxy_OnWebSocketData;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
proxy.Start();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
proxy.Dispose();
|
||||
}
|
||||
|
||||
//gzip解压缩
|
||||
private byte[] Decompress(byte[] zippedData)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream(zippedData);
|
||||
GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Decompress);
|
||||
MemoryStream outBuffer = new MemoryStream();
|
||||
byte[] block = new byte[1024];
|
||||
while (true)
|
||||
{
|
||||
int bytesRead = compressedzipStream.Read(block, 0, block.Length);
|
||||
if (bytesRead <= 0)
|
||||
break;
|
||||
else
|
||||
outBuffer.Write(block, 0, bytesRead);
|
||||
}
|
||||
compressedzipStream.Close();
|
||||
return outBuffer.ToArray();
|
||||
}
|
||||
|
||||
private void Proxy_OnWebSocketData(object sender, FiddlerProxy.WsMessageEventArgs e)
|
||||
{
|
||||
if (!appsetting.FilterProcess.Contains(e.ProcessName)) return;
|
||||
var buff = e.Message.PayloadData;
|
||||
if (buff.Length == 0) return;
|
||||
if (buff[0] != 0x08) return;
|
||||
|
||||
try
|
||||
{
|
||||
var enty = Serializer.Deserialize<WssResponse>(new ReadOnlyMemory<byte>(buff));
|
||||
if (enty == null) return;
|
||||
|
||||
//检测包格式
|
||||
if (!enty.Headers.Any(a => a.Key == "compress_type" && a.Value == "gzip")) return;
|
||||
|
||||
//解压gzip
|
||||
var odata = enty.Payload;
|
||||
var decomp = Decompress(odata);
|
||||
|
||||
var response = Serializer.Deserialize<Response>(new ReadOnlyMemory<byte>(decomp));
|
||||
response.Messages.ForEach(f => DoMessage(f));
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
private void DoMessage(Message msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (msg.Method)
|
||||
{
|
||||
case "WebcastMemberMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<MemberMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
this.OnMemberMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
case "WebcastSocialMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<SocialMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
this.OnSocialMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
case "WebcastChatMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<ChatMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
this.OnChatMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
case "WebcastLikeMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<LikeMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
this.OnLikeMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
case "WebcastGiftMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<GiftMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
|
||||
if (arg.Gift == null)
|
||||
{
|
||||
if (arg.giftId == 685)
|
||||
{
|
||||
arg.Gift = new ProtoEntity.GiftStruct()
|
||||
{
|
||||
Id = arg.giftId,
|
||||
Name = "粉丝灯牌",
|
||||
diamondCount = 1
|
||||
};
|
||||
}
|
||||
else if (arg.giftId == 3389)
|
||||
{
|
||||
arg.Gift = new GiftStruct()
|
||||
{
|
||||
Id = arg.giftId,
|
||||
Name = "欢乐盲盒",
|
||||
diamondCount = 10
|
||||
};
|
||||
}
|
||||
else if (arg.giftId == 4021)
|
||||
{
|
||||
arg.Gift = new GiftStruct()
|
||||
{
|
||||
Id = arg.giftId,
|
||||
Name = "欢乐拼图",
|
||||
diamondCount = 10
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.OnGiftMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
case "WebcastRoomUserSeqMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<RoomUserSeqMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
this.OnRoomUserSeqMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
case "WebcastControlMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<ControlMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
this.OnControlMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
case "WebcastFansclubMessage":
|
||||
{
|
||||
var arg = Serializer.Deserialize<FansclubMessage>(new ReadOnlyMemory<byte>(msg.Payload));
|
||||
this.OnFansclubMessage?.Invoke(this, arg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using BarrageGrab.JsonEntity;
|
||||
using ColorConsole;
|
||||
using Fleck;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BarrageGrab
|
||||
{
|
||||
/// <summary>
|
||||
/// 弹幕服务
|
||||
/// </summary>
|
||||
internal class WssBarrageService
|
||||
{
|
||||
WebSocketServer socketServer;
|
||||
Dictionary<string, UserState> socketList = new Dictionary<string, UserState>();
|
||||
Timer dieout = new Timer(10000);
|
||||
ConsoleWriter console = new ConsoleWriter();
|
||||
WssBarrageGrab grab = new WssBarrageGrab();
|
||||
Appsetting Appsetting = Appsetting.Get();
|
||||
|
||||
public WssBarrageService()
|
||||
{
|
||||
var socket = new WebSocketServer($"ws://127.0.0.1:{Appsetting.WsProt}");
|
||||
socket.RestartAfterListenError = true;//异常重启
|
||||
|
||||
dieout.Elapsed += Dieout_Elapsed;
|
||||
|
||||
this.grab.OnChatMessage += Grab_OnChatMessage;
|
||||
this.grab.OnLikeMessage += Grab_OnLikeMessage;
|
||||
this.grab.OnMemberMessage += Grab_OnMemberMessage;
|
||||
this.grab.OnSocialMessage += Grab_OnSocialMessage;
|
||||
this.grab.OnGiftMessage += Grab_OnGiftMessage;
|
||||
|
||||
this.socketServer = socket;
|
||||
//dieout.Start();
|
||||
}
|
||||
|
||||
private MsgUser GetUser(dynamic obj)
|
||||
{
|
||||
MsgUser user = new MsgUser()
|
||||
{
|
||||
DisplayId = obj.User.displayId,
|
||||
Gender = obj.User.Gender,
|
||||
Id = obj.User.Id,
|
||||
Level = obj.User.Level,
|
||||
Nickname = obj.User.Nickname
|
||||
};
|
||||
return user;
|
||||
}
|
||||
|
||||
private void Grab_OnGiftMessage(object sender, ProtoEntity.GiftMessage e)
|
||||
{
|
||||
var enty = new GiftMsg()
|
||||
{
|
||||
RoomId = e.Common.roomId,
|
||||
Content = e.Common.Describe,
|
||||
GiamondCount = e.Gift.diamondCount,
|
||||
GiftCount = e.repeatCount,
|
||||
GiftId = e.giftId,
|
||||
GiftName = e.Gift.Name,
|
||||
User = GetUser(e)
|
||||
};
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.送礼);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
private void Grab_OnSocialMessage(object sender, ProtoEntity.SocialMessage e)
|
||||
{
|
||||
var enty = new Msg()
|
||||
{
|
||||
Content = e.Common.Describe,
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
};
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.关注主播);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
private void Grab_OnMemberMessage(object sender, ProtoEntity.MemberMessage e)
|
||||
{
|
||||
var enty = new Msg()
|
||||
{
|
||||
Content = e.Common.Describe,
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
};
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.进入直播间);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
private void Grab_OnLikeMessage(object sender, ProtoEntity.LikeMessage e)
|
||||
{
|
||||
var enty = new LikeMsg()
|
||||
{
|
||||
Count = e.Count,
|
||||
Content = e.Common.Describe,
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
};
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.点赞);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
private void Grab_OnChatMessage(object sender, ProtoEntity.ChatMessage e)
|
||||
{
|
||||
var enty = new Msg()
|
||||
{
|
||||
Content = e.Content,
|
||||
RoomId = e.Common.roomId,
|
||||
User = GetUser(e)
|
||||
};
|
||||
var pack = new BarrageMsgPack(JsonConvert.SerializeObject(enty), BarrageMsgType.消息);
|
||||
var json = JsonConvert.SerializeObject(pack);
|
||||
this.Broadcast(json);
|
||||
}
|
||||
|
||||
private void Dieout_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
var dieoutKvs = socketList.Where(w => w.Value.LastPing.AddSeconds(dieout.Interval * 3) < now).ToList();
|
||||
dieoutKvs.ForEach(f => f.Value.Socket.Close());
|
||||
}
|
||||
|
||||
private void Listen(IWebSocketConnection socket)
|
||||
{
|
||||
//客户端url
|
||||
string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
|
||||
if (!socketList.ContainsKey(clientUrl))
|
||||
{
|
||||
socketList.Add(clientUrl, new UserState(socket));
|
||||
console.WriteLine($"{DateTime.Now.ToLongTimeString()} 已经建立与[{clientUrl}]的连接", ConsoleColor.Green);
|
||||
}
|
||||
else
|
||||
{
|
||||
socketList[clientUrl].Socket = socket;
|
||||
}
|
||||
|
||||
socket.OnClose = () =>
|
||||
{
|
||||
socketList.Remove(clientUrl);
|
||||
console.WriteLine($"{DateTime.Now.ToLongTimeString()} 已经关闭与[{clientUrl}]的连接", ConsoleColor.Red);
|
||||
};
|
||||
|
||||
socket.OnPing = (data) =>
|
||||
{
|
||||
socketList[clientUrl].LastPing = DateTime.Now;
|
||||
socket.SendPong(Encoding.UTF8.GetBytes("pong"));
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 广播消息
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
public void Broadcast(string msg)
|
||||
{
|
||||
foreach (var user in socketList)
|
||||
{
|
||||
var socket = user.Value;
|
||||
socket.Socket.Send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartListen()
|
||||
{
|
||||
this.grab.Start(); //启动代理
|
||||
this.socketServer.Start(Listen);//启动监听
|
||||
console.WriteLine($"{this.socketServer.Location} 弹幕服务已启动...", ConsoleColor.Green);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭服务器连接
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
socketList.Values.ToList().ForEach(f => f.Socket.Close());
|
||||
socketList.Clear();
|
||||
socketServer.Dispose();
|
||||
grab.Dispose();
|
||||
|
||||
console.WriteLine("服务器已关闭...");
|
||||
}
|
||||
|
||||
class UserState
|
||||
{
|
||||
/// <summary>
|
||||
/// 套接字
|
||||
/// </summary>
|
||||
public IWebSocketConnection Socket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次发起心跳包时间
|
||||
/// </summary>
|
||||
public DateTime LastPing { get; set; } = DateTime.Now;
|
||||
|
||||
public UserState()
|
||||
{
|
||||
|
||||
}
|
||||
public UserState(IWebSocketConnection socket)
|
||||
{
|
||||
Socket = socket;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A07BB1DA-D5C2-4EEA-9F3F-E42AADB9C1D6}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>BarrageGrab</RootNamespace>
|
||||
<AssemblyName>WssBarrageService</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>false</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BasicFormatsForCore, Version=2.6.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FiddlerCore.4.6.2.0\lib\net40\BasicFormatsForCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BCMakeCert, Version=2.0.7.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FiddlerCore.4.6.2.0\lib\net40\BCMakeCert.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CertMaker, Version=4.5.0.1, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FiddlerCore.4.6.2.0\lib\net40\CertMaker.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ColorConsole, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ColorConsole.1.0.1\lib\net40\ColorConsole.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FiddlerCore4, Version=4.6.2.0, Culture=neutral, PublicKeyToken=67cb91587178ac5a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FiddlerCore.4.6.2.0\lib\net40\FiddlerCore4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Fleck, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Fleck.1.2.0\lib\net45\Fleck.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="protobuf-net, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\protobuf-net.3.1.22\lib\net462\protobuf-net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="protobuf-net.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\protobuf-net.Core.3.1.22\lib\net462\protobuf-net.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Immutable, Version=1.2.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Appsetting.cs" />
|
||||
<Compile Include="JsonEntity\BarrageMessages.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="WssBarrageGrab.cs" />
|
||||
<Compile Include="FiddlerProxy.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ProtoEntity\Messages.cs" />
|
||||
<Compile Include="ProtoEntity\Wss.cs" />
|
||||
<Compile Include="WssBarrageService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\app.manifest" />
|
||||
<None Include="proto\message.proto">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="proto\wss.proto">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ColorConsole" version="1.0.1" targetFramework="net48" />
|
||||
<package id="FiddlerCore" version="4.6.2.0" targetFramework="net48" />
|
||||
<package id="Fleck" version="1.2.0" targetFramework="net48" />
|
||||
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
|
||||
<package id="protobuf-net" version="3.1.22" targetFramework="net48" />
|
||||
<package id="protobuf-net.Core" version="3.1.22" targetFramework="net48" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
||||
<package id="System.Collections.Immutable" version="1.7.1" targetFramework="net48" />
|
||||
<package id="System.Memory" version="4.5.4" targetFramework="net48" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net48" />
|
||||
</packages>
|
||||
@@ -0,0 +1,582 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message Response{
|
||||
repeated Message messages = 1;
|
||||
string cursor = 2;
|
||||
int64 fetchInterval = 3;
|
||||
int64 now = 4;
|
||||
string internalExt = 5;
|
||||
int32 fetchType = 6;
|
||||
map<string, string> routeParams = 7;
|
||||
int64 heartbeatDuration = 8;
|
||||
bool needAck = 9;
|
||||
string pushServer = 10;
|
||||
string liveCursor = 11;
|
||||
bool historyNoMore = 12;
|
||||
}
|
||||
|
||||
message Message{
|
||||
string method = 1;
|
||||
bytes payload = 2;
|
||||
int64 msgId = 3;
|
||||
int32 msgType = 4;
|
||||
int64 offset = 5;
|
||||
}
|
||||
|
||||
message RoomUserSeqMessage {
|
||||
Common common = 1;
|
||||
repeated Contributor ranks = 2;
|
||||
int64 total = 3;
|
||||
string popStr = 4;
|
||||
repeated Contributor seats = 5;
|
||||
int64 popularity = 6;
|
||||
int64 totalUser = 7;
|
||||
string totalUserStr = 8;
|
||||
string totalStr = 9;
|
||||
string onlineUserForAnchor = 10;
|
||||
string totalPvForAnchor = 11;
|
||||
|
||||
message Contributor {
|
||||
int64 score = 1;
|
||||
User user = 2;
|
||||
int64 rank = 3;
|
||||
int64 delta = 4;
|
||||
bool isHidden = 5;
|
||||
string scoreDescription = 6;
|
||||
string exactlyScore = 7;
|
||||
}
|
||||
}
|
||||
|
||||
message GiftMessage {
|
||||
Common common = 1;
|
||||
int64 giftId = 2;
|
||||
int64 fanTicketCount = 3;
|
||||
int64 groupCount = 4;
|
||||
int64 repeatCount = 5;
|
||||
int64 comboCount = 6;
|
||||
User user = 7;
|
||||
User toUser = 8;
|
||||
int32 repeatEnd = 9;
|
||||
TextEffect textEffect = 10;
|
||||
int64 groupId = 11;
|
||||
int64 incomeTaskgifts = 12;
|
||||
int64 roomFanTicketCount = 13;
|
||||
GiftIMPriority priority = 14;
|
||||
GiftStruct gift = 15;
|
||||
string logId = 16;
|
||||
int64 sendType = 17;
|
||||
PublicAreaCommon publicAreaCommon = 18;
|
||||
Text trayDisplayText = 19;
|
||||
int64 bannedDisplayEffects = 20;
|
||||
GiftTrayInfo trayInfo = 21;
|
||||
AssetEffectMixInfo assetEffectMixInfo = 24;
|
||||
|
||||
message TextEffect{
|
||||
Detail portrait = 1;
|
||||
Detail landscape = 2;
|
||||
|
||||
message Detail {
|
||||
Text text = 1;
|
||||
int32 textFontSize = 2;
|
||||
Image background = 3;
|
||||
int32 start = 4;
|
||||
int32 duration = 5;
|
||||
int32 x = 6;
|
||||
int32 y = 7;
|
||||
int32 width = 8;
|
||||
int32 height = 9;
|
||||
int32 shadowDx = 10;
|
||||
int32 shadowDy = 11;
|
||||
int32 shadowRadius = 12;
|
||||
string shadowColor = 13;
|
||||
string strokeColor = 14;
|
||||
int32 strokeWidth = 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message LikeMessage {
|
||||
Common common = 1;
|
||||
int64 count = 2;
|
||||
int64 total = 3;
|
||||
int64 color = 4;
|
||||
User user = 5;
|
||||
string icon = 6;
|
||||
}
|
||||
|
||||
message ChatMessage {
|
||||
Common common = 1;
|
||||
User user = 2;
|
||||
string content = 3;
|
||||
bool visibleToSender = 4;
|
||||
Image backgroundImage = 5;
|
||||
string fullScreenTextColor = 6;
|
||||
Image backgroundImageV2 = 7;
|
||||
PublicAreaCommon publicAreaCommon = 9;
|
||||
Image giftImage = 10;
|
||||
}
|
||||
|
||||
message SocialMessage {
|
||||
Common common = 1;
|
||||
User user = 2;
|
||||
int64 shareType = 3;
|
||||
int64 action = 4;
|
||||
string shareTarget = 5;
|
||||
int64 followCount = 6;
|
||||
PublicAreaCommon publicAreaCommon = 7;
|
||||
}
|
||||
|
||||
message MemberMessage{
|
||||
Common common = 1;
|
||||
User user = 2;
|
||||
int64 memberCount = 3;
|
||||
User operator = 4;
|
||||
bool isSetToAdmin = 5;
|
||||
bool isTopUser = 6;
|
||||
int64 rankScore = 7;
|
||||
int64 topUserNo = 8;
|
||||
int64 enterType = 9;
|
||||
int64 action = 10;
|
||||
string actionDescription = 11;
|
||||
int64 userId = 12;
|
||||
EffectConfig effectConfig = 13;
|
||||
string popStr = 14;
|
||||
EffectConfig enterEffectConfig = 15;
|
||||
Image backgroundImage = 16;
|
||||
Image backgroundImageV2 = 17;
|
||||
Text anchorDisplayText = 18;
|
||||
PublicAreaCommon publicAreaCommon = 19;
|
||||
|
||||
message EffectConfig{
|
||||
int64 type = 1;
|
||||
Image icon = 2;
|
||||
int64 avatarPos = 3;
|
||||
Text text = 4;
|
||||
Image textIcon = 5;
|
||||
int32 stayTime = 6;
|
||||
int64 animAssetId = 7;
|
||||
Image badge = 8;
|
||||
repeated int64 flexSettingArray = 9;
|
||||
Image textIconOverlay = 10;
|
||||
Image animatedBadge = 11;
|
||||
bool hasSweepLight = 12;
|
||||
repeated int64 textFlexSettingArray = 13;
|
||||
int64 centerAnimAssetId = 14;
|
||||
}
|
||||
}
|
||||
|
||||
message ControlMessage {
|
||||
Common common = 1;
|
||||
int32 status = 2;
|
||||
}
|
||||
|
||||
message FansclubMessage {
|
||||
Common commonInfo = 1;
|
||||
// 升级是1,加入是2
|
||||
int32 type = 2;
|
||||
string content = 3;
|
||||
User user = 4;
|
||||
}
|
||||
|
||||
message Common{
|
||||
string method = 1;
|
||||
int64 msgId = 2;
|
||||
int64 roomId = 3;
|
||||
int64 createTime = 4;
|
||||
int32 monitor = 5;
|
||||
bool isShowMsg = 6;
|
||||
string describe = 7;
|
||||
Text displayText = 8;
|
||||
int64 foldType = 9;
|
||||
int64 anchorFoldType = 10;
|
||||
int64 priorityScore = 11;
|
||||
string logId = 12;
|
||||
string msgProcessFilterK = 13;
|
||||
string msgProcessFilterV = 14;
|
||||
User user = 15;
|
||||
Room room = 16;
|
||||
int64 anchorFoldTypeV2 = 17;
|
||||
int64 processAtSeiTimeMs = 18;
|
||||
}
|
||||
|
||||
message Text{
|
||||
string key = 1;
|
||||
string defaultPattern = 2;
|
||||
TextFormat defaultFormat = 3;
|
||||
repeated TextPiece pieces = 4;
|
||||
}
|
||||
|
||||
message Room {
|
||||
int64 id = 1;
|
||||
string idStr = 2;
|
||||
int64 status = 3;
|
||||
int64 ownerUserId = 4;
|
||||
string title = 5;
|
||||
int64 userCount = 6;
|
||||
int64 createTime = 7;
|
||||
int64 linkmicLayout = 8;
|
||||
int64 finishTime = 9;
|
||||
RoomExtra extra = 10;
|
||||
string dynamicCoverUri = 11;
|
||||
map<int64, string> dynamicCoverDict = 12;
|
||||
int64 lastPingTime = 13;
|
||||
int64 liveId = 14;
|
||||
int64 streamProvider = 15;
|
||||
int64 osType = 16;
|
||||
int64 clientVersion = 17;
|
||||
bool withLinkmic = 18;
|
||||
bool enableRoomPerspective = 19;
|
||||
Image cover = 20;
|
||||
Image dynamicCover = 21;
|
||||
Image dynamicCoverLow = 22;
|
||||
string shareUrl = 23;
|
||||
string anchorShareText = 24;
|
||||
string userShareText = 25;
|
||||
int64 streamId = 26;
|
||||
string streamIdStr = 27;
|
||||
StreamUrl streamUrl = 28;
|
||||
int64 mosaicStatus = 29;
|
||||
string mosaicTip = 30;
|
||||
int64 cellStyle = 31;
|
||||
LinkMic linkMic = 32;
|
||||
int64 luckymoneyNum = 33;
|
||||
repeated Decoration decoList = 34;
|
||||
repeated TopFan topFans = 35;
|
||||
RoomStats stats = 36;
|
||||
string sunDailyIconContent = 37;
|
||||
string distance = 38;
|
||||
string distanceCity = 39;
|
||||
string location = 40;
|
||||
string realDistance = 41;
|
||||
Image feedRoomLabel = 42;
|
||||
string commonLabelList = 43;
|
||||
RoomUserAttr livingRoomAttrs = 44;
|
||||
repeated int64 adminUserIds = 45;
|
||||
User owner = 46;
|
||||
string privateInfo = 47;
|
||||
}
|
||||
|
||||
message RoomExtra{
|
||||
|
||||
}
|
||||
|
||||
message RoomStats{
|
||||
|
||||
}
|
||||
|
||||
message RoomUserAttr{
|
||||
|
||||
}
|
||||
|
||||
message StreamUrl{
|
||||
|
||||
}
|
||||
|
||||
message LinkMic {
|
||||
|
||||
}
|
||||
|
||||
message Decoration{
|
||||
|
||||
}
|
||||
|
||||
message TopFan {
|
||||
|
||||
}
|
||||
|
||||
message User{
|
||||
int64 id = 1;
|
||||
int64 shortId = 2;
|
||||
string nickname = 3;
|
||||
int32 gender = 4;
|
||||
string signature = 5;
|
||||
int32 level = 6;
|
||||
int64 birthday = 7;
|
||||
string telephone = 8;
|
||||
Image avatarThumb = 9;
|
||||
Image avatarMedium = 10;
|
||||
Image avatarLarge = 11;
|
||||
bool verified = 12;
|
||||
int32 experience = 13;
|
||||
string city = 14;
|
||||
int32 status = 15;
|
||||
int64 createTime = 16;
|
||||
int64 modifyTime = 17;
|
||||
int32 secret = 18;
|
||||
string shareQrcodeUri = 19;
|
||||
int32 incomeSharePercent = 20;
|
||||
Image badgeImageList = 21;
|
||||
FollowInfo followInfo = 22;
|
||||
PayGrade payGrade = 23;
|
||||
FansClub fansClub = 24;
|
||||
Border border = 25;
|
||||
string specialId = 26;
|
||||
Image avatarBorder = 27;
|
||||
Image medal = 28;
|
||||
repeated Image realTimeIcons = 29;
|
||||
repeated Image newRealTimeIcons = 30;
|
||||
int64 topVipNo = 31;
|
||||
UserAttr userAttr = 32;
|
||||
OwnRoom ownRoom = 33;
|
||||
int64 payScore = 34;
|
||||
int64 ticketCount = 35;
|
||||
AnchorInfo anchorInfo = 36;
|
||||
int32 linkMicStats = 37;
|
||||
string displayId = 38;
|
||||
|
||||
message UserAttr {
|
||||
|
||||
}
|
||||
|
||||
message OwnRoom {
|
||||
|
||||
}
|
||||
|
||||
message AnchorInfo {
|
||||
|
||||
}
|
||||
|
||||
message FollowInfo {
|
||||
int64 followingCount = 1;
|
||||
int64 followerCount = 2;
|
||||
int64 followStatus = 3;
|
||||
int64 pushStatus = 4;
|
||||
string remarkName = 5;
|
||||
}
|
||||
|
||||
message FansClub{
|
||||
FansClubData data = 1;
|
||||
map<int32, FansClubData> preferData = 2;
|
||||
|
||||
message FansClubData {
|
||||
string clubName = 1;
|
||||
int32 level = 2;
|
||||
int32 userFansClubStatus = 3;
|
||||
UserBadge badge = 4;
|
||||
repeated int64 availableGiftIds = 5;
|
||||
int64 anchorId = 6;
|
||||
|
||||
message UserBadge {
|
||||
map<int32, Image> icons = 1;
|
||||
string title = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message Border{
|
||||
|
||||
}
|
||||
|
||||
message GradeBuffInfo {
|
||||
int64 buffLevel = 1;
|
||||
int32 status = 2;
|
||||
int64 endTime = 3;
|
||||
map<int64, int64> statsInfo = 4;
|
||||
Image buffBadge = 5;
|
||||
}
|
||||
|
||||
message PayGrade {
|
||||
int64 totalDiamondCount = 1;
|
||||
Image diamondIcon = 2;
|
||||
string name = 3;
|
||||
Image icon = 4;
|
||||
string nextName = 5;
|
||||
int64 level = 6;
|
||||
Image nextIcon = 7;
|
||||
int64 nextDiamond = 8;
|
||||
int64 nowDiamond = 9;
|
||||
int64 thisGradeMinDiamond = 10;
|
||||
int64 thisGradeMaxDiamond = 11;
|
||||
int64 payDiamondBak = 12;
|
||||
string gradeDescribe = 13;
|
||||
repeated GradeIcon gradeIconList = 14;
|
||||
int64 screenChatType = 15;
|
||||
Image imIcon = 16;
|
||||
Image imIconWithLevel = 17;
|
||||
Image liveIcon = 18;
|
||||
Image newImIconWithLevel = 19;
|
||||
Image newLiveIcon = 20;
|
||||
int64 upgradeNeedConsume = 21;
|
||||
string nextPrivileges = 22;
|
||||
Image background = 23;
|
||||
Image backgroundBack = 24;
|
||||
int64 score = 25;
|
||||
GradeBuffInfo buffInfo = 26;
|
||||
string gradeBanner = 1001;
|
||||
Image profileDialogBg = 1002;
|
||||
Image profileDialogBgBack = 1003;
|
||||
|
||||
message GradeIcon{
|
||||
Image icon = 1;
|
||||
int64 iconDiamond = 2;
|
||||
int64 level = 3;
|
||||
string levelStr = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message TextFormat{
|
||||
string color = 1;
|
||||
bool bold = 2;
|
||||
bool italic = 3;
|
||||
int32 weight = 4;
|
||||
int32 italicAngle = 5;
|
||||
int32 fontSize = 6;
|
||||
bool userHeightLightColor = 7;
|
||||
bool useRemoteClor = 8;
|
||||
}
|
||||
|
||||
message TextPiece{
|
||||
int32 type = 1;
|
||||
TextFormat format = 2;
|
||||
string stringValue = 11;
|
||||
TextPieceUser userValue = 21;
|
||||
}
|
||||
|
||||
message Image{
|
||||
repeated string urlList = 1;
|
||||
string uri = 2;
|
||||
int64 height = 3;
|
||||
int64 width = 4;
|
||||
string avgColor = 5;
|
||||
int32 imageType = 6;
|
||||
string openWebUrl = 7;
|
||||
Content content = 8;
|
||||
bool isAnimated = 9;
|
||||
|
||||
message Content {
|
||||
string name = 1;
|
||||
string fontColor = 2;
|
||||
int64 level = 3;
|
||||
string alternativeText = 4;
|
||||
}
|
||||
}
|
||||
|
||||
message TextPieceUser{
|
||||
User user = 1;
|
||||
bool withColon = 2;
|
||||
}
|
||||
|
||||
message PublicAreaCommon {
|
||||
Image userLabel = 1;
|
||||
int64 userConsumeInRoom = 2;
|
||||
int64 userSendGiftCntInRoom = 3;
|
||||
}
|
||||
|
||||
message GiftIMPriority {
|
||||
repeated int64 queueSizes = 1;
|
||||
int64 selfQueuePriority = 2;
|
||||
int64 priority = 3;
|
||||
}
|
||||
|
||||
message GiftTrayInfo{
|
||||
Text trayDisplayText = 1;
|
||||
Image trayBaseImg = 2;
|
||||
Image trayHeadImg = 3;
|
||||
Image trayRightImg = 4;
|
||||
int64 trayLevel = 5;
|
||||
Image trayDynamicImg = 6;
|
||||
}
|
||||
|
||||
message GiftStruct {
|
||||
Image image = 1;
|
||||
string describe = 2;
|
||||
bool notify = 3;
|
||||
int64 duration = 4;
|
||||
int64 id = 5;
|
||||
GiftStructFansClubInfo fansclubInfo = 6;
|
||||
bool forLinkmic = 7;
|
||||
bool doodle = 8;
|
||||
bool forFansclub = 9;
|
||||
bool combo = 10;
|
||||
int32 type = 11;
|
||||
int32 diamondCount = 12;
|
||||
int32 isDisplayedOnPanel = 13;
|
||||
int64 primaryEffectId = 14;
|
||||
Image giftLabelIcon = 15;
|
||||
string name = 16;
|
||||
string region = 17;
|
||||
string manual = 18;
|
||||
bool forCustom = 19;
|
||||
map<string, int64> specialEffects = 20;
|
||||
Image icon = 21;
|
||||
int32 actionType = 22;
|
||||
int32 watermelonSeeds = 23;
|
||||
string goldEffect = 24;
|
||||
repeated LuckyMoneyGiftMeta subs = 25;
|
||||
int64 goldenBeans = 26;
|
||||
int64 honorLevel = 27;
|
||||
int32 itemType = 28;
|
||||
string schemeUrl = 29;
|
||||
GiftPanelOperation giftOperation = 30;
|
||||
string eventName = 31;
|
||||
int64 nobleLevel = 32;
|
||||
string guideUrl = 33;
|
||||
bool punishMedicine = 34;
|
||||
bool forPortal = 35;
|
||||
string businessText = 36;
|
||||
bool cnyGift = 37;
|
||||
int64 appId = 38;
|
||||
int64 vipLevel = 39;
|
||||
bool isGray = 40;
|
||||
string graySchemeUrl = 41;
|
||||
int64 giftScene = 42;
|
||||
GiftBanner giftBanner = 43;
|
||||
repeated string triggerWords = 44;
|
||||
repeated GiftBuffInfo giftBuffInfos = 45;
|
||||
bool forFirstRecharge = 46;
|
||||
Image dynamicImgForSelected = 47;
|
||||
int32 afterSendAction = 48;
|
||||
int64 giftOfflineTime = 49;
|
||||
string topBarText = 50;
|
||||
Image topRightAvatar = 51;
|
||||
string bannerSchemeUrl = 52;
|
||||
bool isLocked = 53;
|
||||
int64 reqExtraType = 54;
|
||||
repeated int64 assetIds = 55;
|
||||
GiftPreviewInfo giftPreviewInfo = 56;
|
||||
GiftTip giftTip = 57;
|
||||
int32 needSweepLightCount = 58;
|
||||
repeated GiftGroupInfo groupInfo = 59;
|
||||
|
||||
message GiftStructFansClubInfo {
|
||||
int32 minLevel = 1;
|
||||
int32 insertPos = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message AssetEffectMixInfo{
|
||||
|
||||
}
|
||||
|
||||
message LuckyMoneyGiftMeta {
|
||||
|
||||
}
|
||||
|
||||
message GiftPanelOperation {
|
||||
|
||||
}
|
||||
|
||||
message GiftBanner {
|
||||
|
||||
}
|
||||
|
||||
message GiftBuffInfo{
|
||||
|
||||
}
|
||||
|
||||
message GiftPreviewInfo{
|
||||
|
||||
}
|
||||
|
||||
message GiftTip {
|
||||
|
||||
}
|
||||
|
||||
message GiftGroupInfo {
|
||||
|
||||
}
|
||||
|
||||
message EffectMixImageInfo {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message WssResponse{
|
||||
uint64 seqid = 1;
|
||||
uint64 logid = 2;
|
||||
uint64 service = 3;
|
||||
uint64 method = 4;
|
||||
map<string,string> headers = 5;
|
||||
string payloadEncoding = 6;
|
||||
string payloadType = 7;
|
||||
bytes payload = 8;
|
||||
}
|
||||
Reference in New Issue
Block a user