/// <summary> /// 初始化Cos /// </summary> private static void InitCos() { enableCos = MMPU.读取exe默认配置文件("EnableCos", "0"); InfoLog.InfoPrintf($"配置文件初始化任务[EnableCos]:{enableCos}", InfoLog.InfoClass.Debug); if (enableCos != "0") { UploadOrderTemp.Add(int.Parse(enableCos), "Cos"); CheckEnableUpload = true; InfoLog.InfoPrintf($"已检测到Cos上传任务,上传顺序为{enableCos}", InfoLog.InfoClass.必要提示); cosSecretId = MMPU.读取exe默认配置文件("CosSecretId", ""); InfoLog.InfoPrintf($"配置文件初始化任务[CosSecretId]:敏感信息,隐藏内容,信息长度:{cosSecretId.Length}", InfoLog.InfoClass.Debug); cosSecretKey = MMPU.读取exe默认配置文件("CosSecretKey", ""); InfoLog.InfoPrintf($"配置文件初始化任务[CosSecretKey]:敏感信息,隐藏内容,信息长度:{cosSecretKey.Length}", InfoLog.InfoClass.Debug); cosRegion = MMPU.读取exe默认配置文件("CosRegion", ""); InfoLog.InfoPrintf($"配置文件初始化任务[CosRegion]:{cosRegion}", InfoLog.InfoClass.Debug); cosBucket = MMPU.读取exe默认配置文件("CosBucket", ""); InfoLog.InfoPrintf($"配置文件初始化任务[CosBucket]:{cosBucket}", InfoLog.InfoClass.Debug); cosPath = MMPU.读取exe默认配置文件("CosPath", "/"); MMPU.CheckPath(ref cosPath); InfoLog.InfoPrintf($"配置文件初始化任务[CosPath]:{cosPath}", InfoLog.InfoClass.Debug); } }
public void UploadVideo() { if (uploadInfo != null && Uploader.enableUpload)//成功获取待上传文件的信息 且 开启上传 { new Task(() => { foreach (var item in Uploader.UploadOrder) //遍历上传目标 { uploadInfo.type = item.Value; //指定当前上传目标 switch (uploadInfo.type) //根据不同上传目标执行不同上传函数 { case "OneDrive": InfoLog.InfoPrintf("OneDrive上传任务已提交", InfoLog.InfoClass.载必要提示); Upload(new OneDriveUpload().doUpload); break; case "Cos": InfoLog.InfoPrintf("Cos上传任务已提交", InfoLog.InfoClass.载必要提示); Upload(new CosUpload().doUpload); break; default: break; } } if (Uploader.deleteAfterUpload == "1" && uploadInfo.status[uploadInfo.type].statusCode == 0 && System.IO.File.Exists(uploadInfo.srcFile)) //设定上传后删除的参数 且 最后一个上传目标上传成功 且 当前文件存在,则删除文件 { System.IO.File.Delete(uploadInfo.srcFile); } }).Start(); } }
/// <summary> /// 上传配置初始化 /// </summary> public static void InitUpload() { try { enableUpload = MMPU.读取exe默认配置文件("EnableUpload", "0") == "1" ? true : false; InfoLog.InfoPrintf($"配置文件初始化任务[EnableUpload]:{enableUpload}", InfoLog.InfoClass.Debug); } catch { enableUpload = false; deleteAfterUpload = "0"; InfoLog.InfoPrintf($"上传模块初始化错误,已关闭自动上传", InfoLog.InfoClass.系统错误信息); return; } if (enableUpload) { try { deleteAfterUpload = MMPU.读取exe默认配置文件("DeleteAfterUpload", "0"); InfoLog.InfoPrintf($"配置文件初始化任务[DeleteAfterUpload]:{deleteAfterUpload}", InfoLog.InfoClass.Debug); InitOneDrive(); InitCos(); enableUpload &= CheckEnableUpload; //配置文件中EnableUpload开启 且 至少成功配置一个上传目标 UploadOrder = UploadOrderTemp.OrderBy(p => p.Key).ToDictionary(p => p.Key, o => o.Value); } catch (System.ArgumentException) { InfoLog.InfoPrintf($"上传顺序出现重复,已自动关闭上传", InfoLog.InfoClass.系统错误信息); enableUpload = false; return; } } }
private void _parse(string jsonBody) { var obj = new JObject(); try { jsonBody = ReplaceString(jsonBody); obj = JObject.Parse(jsonBody); ///JsonMapper.ToObject(jsonBody); } catch (Exception e) { ; } //Debug.Log(jsonBody); string cmd = (string)obj["cmd"]; InfoLog.InfoPrintf("LiveChatListener收到数据,类型为:" + cmd, InfoLog.InfoClass.杂项提示); //Console.WriteLine(cmd); switch (cmd) { case "DANMU_MSG": MessageReceived(this, new DanmuMessageEventArgs(obj)); break; case "SEND_GIFT": MessageReceived(this, new SendGiftEventArgs(obj)); break; case "GUARD_BUY": //Debug.Log("guraddd\n"+obj); MessageReceived(this, new GuardBuyEventArgs(obj)); break; case "WELCOME": MessageReceived(this, new WelcomeEventArgs(obj)); break; case "ACTIVITY_BANNER_UPDATE_V2": MessageReceived(this, new ActivityBannerEventArgs(obj)); break; case "LiveP": MessageReceived(this, new LivePopularity(obj)); break; case "WARNING": MessageReceived(this, new WarningEventArg(obj)); break; default: //Debug.Log("Unknow\n"+obj); MessageReceived(this, new MessageEventArgs(obj)); break; } }
/// <summary> /// 初始化OneDrive /// </summary> private static void InitOneDrive() { enableOneDrive = MMPU.读取exe默认配置文件("EnableOneDrive", "0"); InfoLog.InfoPrintf($"配置文件初始化任务[EnableOneDrive]:{enableOneDrive}", InfoLog.InfoClass.Debug); if (enableOneDrive != "0") { UploadOrderTemp.Add(int.Parse(enableOneDrive), "OneDrive"); CheckEnableUpload = true; InfoLog.InfoPrintf($"已检测到OneDrive上传任务,上传顺序为{enableOneDrive}", InfoLog.InfoClass.必要提示); oneDriveConfig = MMPU.读取exe默认配置文件("OneDriveConfig", ""); InfoLog.InfoPrintf($"配置文件初始化任务[oneDriveConfig]:{oneDriveConfig}", InfoLog.InfoClass.Debug); oneDrivePath = MMPU.读取exe默认配置文件("OneDrivePath", "/"); MMPU.CheckPath(ref oneDrivePath); InfoLog.InfoPrintf($"配置文件初始化任务[oneDrivePath]:{oneDrivePath}", InfoLog.InfoClass.Debug); } }
public static void 根据CDN更新VTBS_Url() { new Task(() => { string CDN_Url = MMPU.返回网页内容("https://api.tokyo.vtbs.moe/meta/cdn"); JArray JO = string.IsNullOrEmpty(CDN_Url) ? (JArray)JsonConvert.DeserializeObject("[]") : (JArray)JsonConvert.DeserializeObject(CDN_Url); List <延迟对象> PING = new List <延迟对象>(); foreach (var item in JO) { PING.Add(new 延迟对象() { CDN_URL = item.ToString() }); } VTBS_Url = 返回延迟最低的连接(PING, 5); InfoLog.InfoPrintf("获取到VTBS当前可用CDN为:" + VTBS_Url, InfoLog.InfoClass.Debug); }).Start(); }
static void Main(string[] args) { Auxiliary.VTBS.API.VTBS服务器CDN.根据CDN更新VTBS_Url(); MMPU.配置文件初始化(1); new Task(() => { DDTVLiveRecWebServer.Program.Main(new string[] { }); }).Start(); new Task(() => { while (true) { try { string 务器版本号 = MMPU.TcpSend(Server.RequestCode.GET_VER, "{}", true, 50); if (!string.IsNullOrEmpty(务器版本号)) { bool 检测状态 = true; foreach (var item in MMPU.检测的版本号) { if (务器版本号 == item) { 检测状态 = false; } } if (MMPU.版本号 != 务器版本号 && 检测状态) { MMPU.更新公告 = MMPU.TcpSend(Server.RequestCode.GET_UPDATE_ANNOUNCEMENT, "{}", true, 100); MMPU.是否有新版本 = true; InfoLog.InfoPrintf("检测到版本更新,更新内容:\n" + MMPU.TcpSend(Server.RequestCode.GET_VERTEXT, "{}", true, 100) + "\n\n", InfoLog.InfoClass.载必要提示); } } } catch (Exception) { } Thread.Sleep(3600 * 1000); } }).Start(); MMPU.缓存路径 = MMPU.载储存目录; InfoLog.InfoPrintf(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ": " + "DDTVLiveRec启动完成", InfoLog.InfoClass.载必要提示); while (true) { Thread.Sleep(10); } }
/// <summary> /// 上传到OneDrive /// </summary> /// <param name="uploadInfo">传入上传信息</param> public void doUpload(UploadInfo uploadInfo) { Process proc = new Process(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { proc.StartInfo.FileName = @".\OneDriveUploader.exe"; //windows下的程序位置 } else { proc.StartInfo.FileName = "OneDriveUploader"; } DateTime showTime = DateTime.Now; proc.StartInfo.Arguments = $"-f -c \"{configFile}\" -s \"{uploadInfo.srcFile}\" -r \"{Uploader.oneDrivePath+uploadInfo.remotePath}\""; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.CreateNoWindow = true; // 不显示窗口。 proc.EnableRaisingEvents = true; proc.StartInfo.StandardOutputEncoding = Encoding.UTF8; proc.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { string stringResults = e.Data; if (stringResults == "" || stringResults == null) { return; } uploadInfo.status["OneDrive"].comments = System.Text.RegularExpressions.Regex.Replace(stringResults, @"(.*\[)(.*)(\].*)", "$2"); InfoLog.InfoPrintf($"Onedrive: {stringResults}", InfoLog.InfoClass.必要提示); }; // 捕捉的信息 proc.Start(); proc.BeginOutputReadLine(); // 开始异步读取 proc.Exited += Process_Exited; proc.WaitForExit(); proc.Close(); GC.Collect(); if (exitCode != 0) { throw new UploadFailure("fail to upload"); } }
static void Main(string[] args) { #if false 载("14275133"); #else Auxiliary.VTBS.API.VTBS服务器CDN.根据CDN更新VTBS_Url(); MMPU.配置文件初始化(1); new Task(() => { DDTVLiveRecWebServer.Program.Main(new string[] { }); }).Start(); #endif new Task(() => { try { string 务器版本号 = MMPU.TcpSend(20013, "{}", true, 50); if (!string.IsNullOrEmpty(务器版本号)) { bool 检测状态 = true; foreach (var item in MMPU.检测的版本号) { if (务器版本号 == item) { 检测状态 = false; } } if (MMPU.版本号 != 务器版本号 && 检测状态) { MMPU.是否有新版本 = true; InfoLog.InfoPrintf("检测到版本更新,更新公告:\n" + MMPU.TcpSend(20014, "{}", true, 100) + "\n\n", InfoLog.InfoClass.载必要提示); //Console.ReadKey(); } } } catch (Exception) { } }).Start(); MMPU.载储存目录 = MMPU.缓存路径; InfoLog.InfoPrintf(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ": " + "DDTVLiveRec启动完成", InfoLog.InfoClass.载必要提示); while (true) { Thread.Sleep(10); } }
/// <summary> /// 初始化上传信息 /// </summary> /// <param name="downIofo">下载信息</param> public UploadInfo(DownIofoData downIofo) { try { streamerName = downIofo.主播名称; streamTitle = downIofo.标题; srcFile = downIofo.文件保存路径; fileName = System.IO.Path.GetFileName(srcFile); fileSize = (double)new FileInfo(srcFile).Length; remotePath = $"{downIofo.主播名称}_{downIofo.房间_频道号}/{MMPU.Unix转换为DateTime(downIofo.开始时间.ToString()).ToString("yyyyMMdd")}_{downIofo.标题}/"; type = null; retries = 0; } catch { InfoLog.InfoPrintf($"创建{srcFile}上传任务失败,无法获取文件信息", InfoLog.InfoClass.系统错误信息); throw new CreateUploadTaskFailure("fail to ctreate upload task");//处理获取文件名、文件大小的错误 } }
/// 上传一个分片 private void UploadPart(int partNumber, long partSize, string srcPath) { try { UploadPartRequest request = new UploadPartRequest(bucket, key, partNumber, this.uploadId, srcPath, partSize * (partNumber - 1), partSize); //执行请求 UploadPartResult result = cosXml.UploadPart(request); //请求成功 //获取返回分块的eTag,用于后续CompleteMultiUploads partNumberAndETags.Add(partNumber, result.eTag); //Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { //请求失败 Console.WriteLine("CosClientException: " + clientEx); InfoLog.InfoPrintf($"Cos: CosClientException: {clientEx}", InfoLog.InfoClass.系统错误信息); } }
public void Close() { try { bilibili.已经使用的服务器组.Remove(wss_S); } catch (Exception) { } try { m_innerRts.Cancel(); } catch (Exception) {} try { m_client.Dispose(); InfoLog.InfoPrintf($"{TroomId}房间LCL连接已断开,ClientWebSocket对象回收完成:", InfoLog.InfoClass.Debug); } catch (Exception) { InfoLog.InfoPrintf($"×{TroomId}房间LCL连接已断开,ClientWebSocket对象回收失败:", InfoLog.InfoClass.Debug); } try { m_innerRts.Dispose(); InfoLog.InfoPrintf($"{TroomId}房间LCL连接已断开,CancellationTokenSource对象回收完成:", InfoLog.InfoClass.Debug); } catch (Exception) { InfoLog.InfoPrintf($"×{TroomId}房间LCL连接已断开,CancellationTokenSource对象回收失败:", InfoLog.InfoClass.Debug); } try { m_ReceiveBuffer = null; } catch (Exception) { //throw; } }
/// <summary> /// /// </summary> /// <param name="提示内容"></param> /// <param name="来源">真为手动,假为自动</param> public void 刷新播放(string 提示内容, bool 来源) { this.Dispatcher.Invoke(new Action(delegate { 提示框.Visibility = Visibility.Visible; 提示文字.Content = 提示内容; })); switch (DD.DownIofo.平台) { case "bilibili": { if (bilibili.根据房间号获取房间信息.是否正在直播(DD.DownIofo.房间_频道号, true)) { new Task((() => { ///需要DEBUG:CancelAsync过后,刷新播放没有显示出来 DD.DownIofo.WC.CancelAsync(); DD.DownIofo.备注 = "播放刷新"; DD.DownIofo.载状态 = false; DD.DownIofo.结束时间 = Convert.ToInt32((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds); Downloader 载对象 = Downloader.新建下载对象(DD.DownIofo.平台, DD.DownIofo.房间_频道号, bilibili.根据房间号获取房间信息.获取标题(DD.DownIofo.房间_频道号), Guid.NewGuid().ToString(), bilibili.根据房间号获取房间信息.载地址(DD.DownIofo.房间_频道号), "播放缓冲重连", false, DD.DownIofo.主播名称, false, null); MMPU.文件删除委托(DD.DownIofo.文件保存路径, "刷新播放窗口,删除LiveCache过期的缓存文件"); DD = 载对象; for (int i = 0; i < MMPU.播放缓冲时长; i++) { Thread.Sleep(1000); if (载对象.DownIofo.已下载大小bit > 1000) { Thread.Sleep(MMPU.播放缓冲时长 * 1000); try { Play_Open(载对象.DownIofo.文件保存路径); //this.VlcControl.SourceProvider.MediaPlayer.Play(new Uri(下载对象.DownIofo.文件保存路径)); } catch (Exception) { return; } this.Dispatcher.Invoke(new Action(delegate { DD = 载对象; 提示框.Visibility = Visibility.Collapsed; })); return; } else { this.Dispatcher.Invoke(new Action(delegate { 提示文字.Content = "直播源推流停止或卡顿,正在尝试重连,第" + (i + 1) + "次失败/一共尝试" + MMPU.播放缓冲时长 + "次"; if (i >= MMPU.播放缓冲时长 - 1) { 提示文字.Content += "\n请尝试重开播放窗口"; return; } })); } } })).Start(); } else { InfoLog.InfoPrintf(DD.DownIofo.房间_频道号 + "房间:" + DD.DownIofo.主播名称 + " 下播放,录制完成", InfoLog.InfoClass.载必要提示); this.Dispatcher.Invoke(new Action(delegate { 提示文字.Content = "======该房间/频道 直播停止,请关闭播放窗口======"; return; })); } break; } default: System.Windows.MessageBox.Show("发现了与当前版本不支持的平台,请检查更新"); this.Dispatcher.Invoke(new Action(delegate { 提示框.Visibility = Visibility.Collapsed; })); return; } }
public async void WebSocket() { if (MMPU.启动模式 == 1) { InfoLog.InfoPrintf("环境不满足启动DDC采集,取消DDC上传任务", InfoLog.InfoClass.Debug); return; } while (MMPU.DDC采集使能) { try { InfoLog.InfoPrintf("vtbs监听启动", InfoLog.InfoClass.Debug); await _webSocket.ConnectAsync(new Uri( "wss://cluster.vtbs.moe/?uuid=DDTVvtbs" + "&runtime=DDTV" + MMPU.版本号 + "&version=" + MMPU.版本号 + "&platform=" + (MMPU.启动模式 == 0 ? "win64" : "linux") + "&name=" + (MMPU.启动模式 == 0 ? "DDTV|" + Encryption.机器码.获取机器码("1145141919810") : "DDTVLiveRec")), _cancellation); while (MMPU.DDC采集使能) { await _webSocket.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes("DDDhttp")), WebSocketMessageType.Text, true, _cancellation); var result = new byte[1024]; await _webSocket.ReceiveAsync(new ArraySegment <byte>(result), new CancellationToken()); string JsonStr = Encoding.UTF8.GetString(result, 0, result.Length).Trim('\0'); JObject JO = JObject.Parse(JsonStr); switch ((string)JO["data"]["type"]) { case "http": getUrl((string)JO["data"]["url"], (string)JO["key"], out string instr); if (!string.IsNullOrEmpty(instr)) { await _webSocket.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(instr)), WebSocketMessageType.Text, true, _cancellation); InfoLog.InfoPrintf("DDC采集成功\n" + JO + "\n\n" + instr, InfoLog.InfoClass.Debug); 采集次数++; Console.WriteLine("DDC采集{0}次", 采集次数); } break; case "wait": Thread.Sleep(MMPU.DDC采集间隔 * 3); break; default: break; } Thread.Sleep(MMPU.DDC采集间隔); } } catch (Exception ex) { try { _webSocket.Dispose(); _webSocket = new ClientWebSocket(); } catch (Exception) { } InfoLog.InfoPrintf("DDC采集失败:" + ex.ToString(), InfoLog.InfoClass.Debug); } Thread.Sleep(10000); } }
/// <summary> /// 消息拆包 /// </summary> private void DepackDanmakuData(byte[] messages) { byte[] headerBuffer = new byte[16]; //for (int i = 0; i < 16; i++) //{ // headerBuffer[i] = messages[i]; //} Array.Copy(messages, 0, headerBuffer, 0, 16); DanmakuProtocol protocol = new DanmakuProtocol(headerBuffer); //Debug.LogError(protocol.Version + "\\" + protocol.Operation); // if (protocol.PacketLength < 16) { if (TroomId == 21446992) { ; } InfoLog.InfoPrintf($@"协议失败: (L:{protocol.PacketLength})", InfoLog.InfoClass.Debug); InfoLog.InfoPrintf($@"{TroomId}房间收到协议PacketLength长度小于16,作为观测包更新心跳时间处理", InfoLog.InfoClass.Debug); ProcessDanmakuData(99, null, 0); //throw new NotSupportedException($@"协议失败: (L:{protocol.PacketLength})"); return; } int bodyLength = protocol.PacketLength - 16; if (bodyLength == 0) { //continue; return; } byte[] buffer = new byte[bodyLength]; //for (int i = 0; i < bodyLength; i++) //{ // buffer[i] = messages[i + 16]; //} Array.Copy(messages, 16, buffer, 0, bodyLength); switch (protocol.Version) { case 1: ProcessDanmakuData(protocol.Operation, buffer, bodyLength); break; case 2: { var ms = new MemoryStream(buffer, 2, bodyLength - 2); var deflate = new DeflateStream(ms, CompressionMode.Decompress); while (deflate.Read(headerBuffer, 0, 16) > 0) { protocol = new DanmakuProtocol(headerBuffer); bodyLength = protocol.PacketLength - 16; if (bodyLength == 0) { continue; // 没有内容了 } if (buffer.Length < bodyLength) // 不够长再申请 { buffer = new byte[bodyLength]; } deflate.Read(buffer, 0, bodyLength); ProcessDanmakuData(protocol.Operation, buffer, bodyLength); } ms.Dispose(); deflate.Dispose(); break; } case 3: ; break; case 5: ; break; case 7: ; break; case 8: ; break; default: ; break; } }
public async Task ConnectAsync(int roomId, CancellationToken?cancellationToken = null) { if (_disposed) { throw new ObjectDisposedException(""); } m_client = new ClientWebSocket(); m_innerRts = new CancellationTokenSource(); string BB = MMPU.返回网页内容_GET("https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo?id=" + roomId, 20000); JObject JO = (JObject)JsonConvert.DeserializeObject(BB); try { foreach (var item in JO["data"]["host_list"]) { if (!bilibili.已经使用的服务器组.Contains(item["host"].ToString())) { wss_S = item["host"].ToString(); bilibili.已经使用的服务器组.Add(wss_S); break; } } if (string.IsNullOrEmpty(wss_S)) { wss_S = JO["data"]["host_list"][1]["host"].ToString(); bilibili.已经使用的服务器组.Add(wss_S); } await m_client.ConnectAsync(new Uri("wss://" + wss_S + "/sub"), cancellationToken ?? new CancellationTokenSource(30000).Token); //await m_client.ConnectAsync(new Uri("wss://broadcastlv.chat.bilibili.com/sub"), cancellationToken ?? new CancellationTokenSource(300000).Token); } catch (Exception e) { InfoLog.InfoPrintf("WSS连接发生错误:" + e.ToString(), InfoLog.InfoClass.Debug); //Console.WriteLine(e.ToString()); } int realRoomId = roomId;//await _getRealRoomId(roomId); await _sendObject(7, new { uid = 0, roomid = realRoomId, protover = 2, platform = "web", clientver = "1.7.3", type = "1", key = JO["data"]["token"].ToString() }); _ = _innerLoop().ContinueWith((t) => { if (t.IsFaulted) { //UnityEngine.Debug.LogError(t.Exception.); if (!m_innerRts.IsCancellationRequested) { MessageReceived(this, new ExceptionEventArgs(t.Exception.InnerException)); m_innerRts.Cancel(); } } else { //POST-CANCEL InfoLog.InfoPrintf("LiveChatListener连接断开,房间号:" + realRoomId, InfoLog.InfoClass.Debug); //Console.WriteLine("LiveChatListender cancelled."); } try { m_client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait(); } catch (Exception) { Dispose(); } }); _ = _innerHeartbeat(); }
private void _parse(string jsonBody) { var obj = new JObject(); try { jsonBody = ReplaceString(jsonBody); obj = JObject.Parse(jsonBody); ///JsonMapper.ToObject(jsonBody); } catch (Exception) { return; } //Debug.Log(jsonBody); string cmd = (string)obj["cmd"]; if (cmd != "DDTV_T1") { InfoLog.InfoPrintf("LiveChatListener收到数据,类型为:" + cmd, InfoLog.InfoClass.杂项提示); } //Console.WriteLine(cmd); switch (cmd) { //弹幕信息 case "DANMU_MSG": MessageReceived(this, new DanmuMessageEventArgs(obj)); break; case "SEND_GIFT": MessageReceived(this, new SendGiftEventArgs(obj)); break; //舰组信息 case "GUARD_BUY": //Debug.Log("guraddd\n"+obj); MessageReceived(this, new GuardBuyEventArgs(obj)); break; //欢迎 case "WELCOME": MessageReceived(this, new WelcomeEventArgs(obj)); break; case "ACTIVITY_BANNER_UPDATE_V2": MessageReceived(this, new ActivityBannerEventArgs(obj)); break; //从来不准的心跳数据 case "LiveP": MessageReceived(this, new LivePopularity(obj)); break; //管理员警告 case "WARNING": MessageReceived(this, new WarningEventArg(obj)); break; //开播心跳 case "LIVE": MessageReceived(this, new LiveEventArgs(obj)); break; //下播心跳 case "PREPARING": MessageReceived(this, new PreparingpEventArgs(obj)); break; case "INTERACT_WORD": //互动词,暂时不知道作用 break; case "PANEL": //小时榜信息更新 break; case "ONLINE_RANK_COUNT": //不知道是什么“在线等级计数” break; case "ONLINE_RANK_V2": //不知道是啥 break; case "ROOM_BANNER": //房间横幅信息,应该就是置顶的那个跳转广告 break; case "COMBO_SEND": //礼物combo break; case "DDTV_T1": MessageReceived(this, new DDTV_EvenntArg(obj)); break; default: MessageReceived(this, new MessageEventArgs(obj)); break; } return; }
private async Task _innerLoop() { #if DEBUG InfoLog.InfoPrintf("LiveChatListener开始连接,房间号:" + TroomId, InfoLog.InfoClass.Debug); //Console.WriteLine("LiveChatListender start."); #endif while (!m_innerRts.IsCancellationRequested) { try { WebSocketReceiveResult result; int length = 0; do { try { result = await m_client.ReceiveAsync( new ArraySegment <byte>(m_ReceiveBuffer, length, m_ReceiveBuffer.Length - length), m_innerRts.Token); length += result.Count; } catch (Exception e) { string BBB = e.ToString(); throw; } }while(!result.EndOfMessage); DepackDanmakuData(m_ReceiveBuffer); #region 已失效[弃用] //var segments = _depack(new ArraySegment<byte>(m_ReceiveBuffer, 0, length)); //foreach (var segment in segments) //{ // string jsonBody = System.Text.Encoding.UTF8.GetString(segment.Array, segment.Offset, segment.Count); // _parse(jsonBody); //} #endregion } catch (OperationCanceledException) { continue; } catch (ObjectDisposedException) { continue; } catch (WebSocketException we) { throw we; } catch (JsonException) { continue; } catch (Exception e) { //UnityEngine.Debug.LogException(e); throw e; } } }
/// <summary> /// 上传文件 /// </summary> public void doUpload(UploadTask.UploadInfo uploadInfo) { try { this.key = Uploader.cosPath + uploadInfo.remotePath + uploadInfo.fileName; InitMultiUpload(); FileInfo fileInfo = null; long partSize = 50 * 1048576;//初始块大小 50M long sourceLength = 0; int partNum = 0; try { long tmp; fileInfo = new FileInfo(uploadInfo.srcFile); sourceLength = fileInfo.Length; partSize /= 2; do { partSize *= 2; tmp = (sourceLength - 1) / partSize + 1; }while (tmp > 500);//超过500块时自动增加块大小 partNum = (int)tmp; } catch (FileNotFoundException) { InfoLog.InfoPrintf($"Cos: 该文件{uploadInfo.srcFile}不存在", InfoLog.InfoClass.系统错误信息); throw new UploadFailure("file not found"); } startTime = DateTime.Now; for (int i = 1; i <= partNum; i++) { try { UploadPart(i, partSize, uploadInfo.srcFile); int passTime = (int)(DateTime.Now - startTime).TotalSeconds; string content = $"{i}/{partNum} | {i / partNum * 100}% |Time: {passTime}s | Remain: {passTime / i * partNum - passTime}s"; InfoLog.InfoPrintf($"Cos: {content}", InfoLog.InfoClass.必要提示); uploadInfo.status["Cos"].comments = content; } catch (COSXML.CosException.CosServerException) { Thread.Sleep(1000); try { UploadPart(i, partSize, uploadInfo.srcFile); int passTime = (int)(DateTime.Now - startTime).TotalSeconds; string content = $"{i}/{partNum} | {Math.Ceiling((double)(i) / partNum * 100)}% |Time: {passTime}s | Remain: {Math.Ceiling((double)(passTime) * partNum / i - passTime)}s"; InfoLog.InfoPrintf($"Cos: {content}", InfoLog.InfoClass.必要提示); uploadInfo.status["Cos"].comments = content; } catch (COSXML.CosException.CosServerException) { throw new UploadFailure("network error"); } } } CompleteMultiUpload(); } catch (Exception e) { throw new UploadFailure("unexpected error", e); } }
/// <summary> /// 消息拆包 /// </summary> private void DepackDanmakuData(byte[] messages) { byte[] headerBuffer = new byte[16]; //for (int i = 0; i < 16; i++) //{ // headerBuffer[i] = messages[i]; //} Array.Copy(messages, 0, headerBuffer, 0, 16); DanmakuProtocol protocol = new DanmakuProtocol(headerBuffer); //Debug.LogError(protocol.Version + "\\" + protocol.Operation); // if (protocol.PacketLength < 16) { InfoLog.InfoPrintf($@"协议失败: (L:{protocol.PacketLength})", InfoLog.InfoClass.杂项提示); throw new NotSupportedException($@"协议失败: (L:{protocol.PacketLength})"); } int bodyLength = protocol.PacketLength - 16; if (bodyLength == 0) { //continue; return; } byte[] buffer = new byte[bodyLength]; //for (int i = 0; i < bodyLength; i++) //{ // buffer[i] = messages[i + 16]; //} Array.Copy(messages, 16, buffer, 0, bodyLength); switch (protocol.Version) { case 1: //弹幕数据 ProcessDanmakuData(protocol.Operation, buffer, bodyLength); break; case 2: //心跳数据 { var ms = new MemoryStream(buffer, 2, bodyLength - 2); var deflate = new DeflateStream(ms, CompressionMode.Decompress); while (deflate.Read(headerBuffer, 0, 16) > 0) { protocol = new DanmakuProtocol(headerBuffer); bodyLength = protocol.PacketLength - 16; if (bodyLength == 0) { continue; // 没有内容了 } if (buffer.Length < bodyLength) // 不够长再申请 { buffer = new byte[bodyLength]; } deflate.Read(buffer, 0, bodyLength); ProcessDanmakuData(protocol.Operation, buffer, bodyLength); } ms.Dispose(); deflate.Dispose(); break; } case 3: //人气值 ; break; case 5: //命令 ; break; case 7: //认证信息 ; break; case 8: //服务器心跳包 ; break; default: ; break; } }
/// <summary> /// 上传文件 /// </summary> /// <param name="do">委托,传入当前上传目标的特定上传函数</param> private void Upload(doUpload @do) { uploadInfo.retries = 1;//第一次上传 UploadStatus uploadStatus = new UploadStatus(); uploadInfo.status.Add(uploadInfo.type, uploadStatus);//初始化并在该文件上传信息中添加新的上传状态 InfoLog.InfoPrintf($"\r\n==============建立{uploadInfo.type}上传任务================\r\n" + $"主播名:{uploadInfo.streamerName}" + $"\r\n标题:{uploadInfo.streamTitle}" + $"\r\n本地文件:{uploadInfo.srcFile}" + $"\r\n上传路径:{uploadInfo.remotePath}" + $"\r\n网盘类型:{uploadInfo.type}" + $"\r\n开始时间:{MMPU.Unix转换为DateTime(uploadInfo.status[uploadInfo.type].startTime.ToString())}" + $"\r\n===============建立{uploadInfo.type}上传任务===============\r\n", InfoLog.InfoClass.必要提示); uploadInfo.status[uploadInfo.type].comments = "建立上传任务"; uploadInfo.status[uploadInfo.type].statusCode = 1; //第一次上传 while (true) //失败后重试,达到最大次数后退出 { try { InfoLog.InfoPrintf($"{uploadInfo.type}:开始第{uploadInfo.retries}次上传", InfoLog.InfoClass.必要提示); uploadInfo.status[uploadInfo.type].comments = $"开始第{uploadInfo.retries}次上传"; uploadInfo.status[uploadInfo.type].statusCode = uploadInfo.retries; //第n次上传 @do(uploadInfo); //执行指定目标的上传函数,失败则异常被捕获 InfoLog.InfoPrintf($"{uploadInfo.type}:上传完毕", InfoLog.InfoClass.必要提示); uploadInfo.status[uploadInfo.type].endTime = Convert.ToInt32((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds); //更新结束时间 InfoLog.InfoPrintf($"\r\n=============={uploadInfo.type}上传成功================\r\n" + $"主播名:{uploadInfo.streamerName}" + $"\r\n标题:{uploadInfo.streamTitle}" + $"\r\n本地文件:{uploadInfo.srcFile}" + $"\r\n上传路径:{uploadInfo.remotePath}" + $"\r\n网盘类型:{uploadInfo.type}" + $"\r\n开始时间:{MMPU.Unix转换为DateTime(uploadInfo.status[uploadInfo.type].startTime.ToString())}" + $"\r\n结束时间:{MMPU.Unix转换为DateTime(uploadInfo.status[uploadInfo.type].endTime.ToString())}" + $"\r\n==============={uploadInfo.type}上传成功===============\r\n", InfoLog.InfoClass.必要提示); uploadInfo.status[uploadInfo.type].comments = $"上传成功"; uploadInfo.status[uploadInfo.type].statusCode = 0; //上传成功 break; //成功则退出 } catch (UploadFailure) //此次上传失败 { if (uploadInfo.retries == Uploader.RETRY_MAX_TIMES) //最后一次上传 { InfoLog.InfoPrintf($"{uploadInfo.type}:第{uploadInfo.retries}/{Uploader.RETRY_MAX_TIMES}次{uploadInfo.type}上传失败", InfoLog.InfoClass.必要提示); uploadInfo.status[uploadInfo.type].endTime = Convert.ToInt32((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds); InfoLog.InfoPrintf($"\r\n=============={uploadInfo.type}上传失败================\r\n" + $"主播名:{uploadInfo.streamerName}" + $"\r\n标题:{uploadInfo.streamTitle}" + $"\r\n本地文件:{uploadInfo.srcFile}" + $"\r\n上传路径:{uploadInfo.remotePath}" + $"\r\n网盘类型:{uploadInfo.type}" + $"\r\n开始时间:{MMPU.Unix转换为DateTime(uploadInfo.status[uploadInfo.type].startTime.ToString())}" + $"\r\n结束时间:{MMPU.Unix转换为DateTime(uploadInfo.status[uploadInfo.type].endTime.ToString())}" + $"\r\n==============={uploadInfo.type}上传失败===============\r\n", InfoLog.InfoClass.必要提示); uploadInfo.status[uploadInfo.type].comments = $"上传失败"; uploadInfo.status[uploadInfo.type].statusCode = -1; //上传失败 break; //达到最大重试次数,失败,退出 } else//未达到最大重试次数,等待一定时间后重试 { InfoLog.InfoPrintf($"{uploadInfo.type}:第{uploadInfo.retries}/{Uploader.RETRY_MAX_TIMES}次上传失败,{Uploader.RETRY_WAITING_TIME}s后重试", InfoLog.InfoClass.必要提示); uploadInfo.status[uploadInfo.type].comments = $"第{uploadInfo.retries}次上传失败,重试等待中"; uploadInfo.retries++; //重试次数+1 Thread.Sleep(Uploader.RETRY_WAITING_TIME * 1000); //等待RETRY_WAITING_TIME秒 uploadInfo.status[uploadInfo.type].statusCode = uploadInfo.retries; //更新第n次重试 } } } }