添加项目文件。

This commit is contained in:
小白猿
2022-10-06 17:44:08 +08:00
parent 7df99405db
commit 9b077cc3f3
16 changed files with 3501 additions and 0 deletions
+9
View File
@@ -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>
+29
View File
@@ -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"]); }
}
}
+139
View File
@@ -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;
}
}
}
}
+131
View File
@@ -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; }
}
}
+58
View File
@@ -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;
}
}
}
+36
View File
@@ -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")]
+73
View File
@@ -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
+51
View File
@@ -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
}
+220
View File
@@ -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;
}
}
}
}
+216
View File
@@ -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;
}
}
}
}
+122
View File
@@ -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>
+14
View File
@@ -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>
+582
View File
@@ -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 {
}
+12
View File
@@ -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;
}