diff --git a/src/BiliLite.UWP/BiliLite.UWP.csproj b/src/BiliLite.UWP/BiliLite.UWP.csproj index f6330b65e..4c7dc8ac6 100644 --- a/src/BiliLite.UWP/BiliLite.UWP.csproj +++ b/src/BiliLite.UWP/BiliLite.UWP.csproj @@ -207,6 +207,7 @@ + diff --git a/src/BiliLite.UWP/Extensions/TimeExtensions.cs b/src/BiliLite.UWP/Extensions/TimeExtensions.cs index a835428dd..400803f38 100644 --- a/src/BiliLite.UWP/Extensions/TimeExtensions.cs +++ b/src/BiliLite.UWP/Extensions/TimeExtensions.cs @@ -85,10 +85,10 @@ public static long GetTimestampS() } /// - /// 生成时间戳/豪秒 + /// 生成时间戳/毫秒 /// /// - public static long GetTimestampMS() + public static long GetTimestampMs() { return Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 8, 0, 0, 0)).TotalMilliseconds); } diff --git a/src/BiliLite.UWP/Models/Common/Enumerates.cs b/src/BiliLite.UWP/Models/Common/Enumerates.cs index 46011dc68..7261b8cff 100644 --- a/src/BiliLite.UWP/Models/Common/Enumerates.cs +++ b/src/BiliLite.UWP/Models/Common/Enumerates.cs @@ -424,6 +424,11 @@ public enum MessageType /// 直播间等级禁言 /// ChatLevelMute, + + /// + /// 直播间观看人数变动 + /// + OnlineCountChange, } public enum MessageDelayType { diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs b/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs index 35c85b282..4d195e567 100644 --- a/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs +++ b/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs @@ -40,6 +40,7 @@ public LiveMessageHandleActionsMap() { MessageType.OnlineRankChange, OnlineRankChange }, { MessageType.StopLive, StopLive }, { MessageType.ChatLevelMute, ChatLevelMute }, + { MessageType.OnlineCountChange, OnlineCountChange } }; } @@ -71,7 +72,12 @@ private void ConnectSuccess(LiveRoomViewModel viewModel, object message) private void WatchedChange(LiveRoomViewModel viewModel, object message) { - viewModel.WatchedNum = (string)message; + viewModel.ViewerNumCount = (string)message; + } + + private void OnlineCountChange(LiveRoomViewModel viewModel, object message) + { + viewModel.ViewerNumCount = (string)message + "人在看"; } private void Danmu(LiveRoomViewModel viewModel, object message) @@ -251,7 +257,7 @@ private void GuardBuyNew(LiveRoomViewModel viewModel, object message) if (match.Success) accompanyDays = match.Groups[1].Value.ToInt32(); var text = info.UserName + - (isNewGuard ? "\n新开通了" : "\n续费了") + + (isNewGuard ? "\n开通了" : "\n续费了") + $"主播的{info.GiftName}" + (info.Num > 1 ? $"×{info.Num}个{info.Unit}" : "") + "🎉" + @@ -268,6 +274,8 @@ private void GuardBuyNew(LiveRoomViewModel viewModel, object message) viewModel.Messages.Add(msg); if (isNewGuard) viewModel.ReloadGuardList().RunWithoutAwait(); + + if (info.UserID == SettingService.Account.UserID.ToString()) viewModel.GetEmoticons().RunWithoutAwait(); // 自己开通了舰长, 有些表情即可解锁 } private void RoomChange(LiveRoomViewModel viewModel, object message) diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveRoomEmoticon.cs b/src/BiliLite.UWP/Models/Common/Live/LiveRoomEmoticon.cs new file mode 100644 index 000000000..580460fda --- /dev/null +++ b/src/BiliLite.UWP/Models/Common/Live/LiveRoomEmoticon.cs @@ -0,0 +1,99 @@ +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace BiliLite.Models.Common.Live +{ + public class LiveRoomEmoticonPackage + { + [JsonProperty("pkg_id")] + public int Id { get; set; } + + [JsonProperty("pkg_name")] + public string Name { get; set; } + + /// + /// 表情包类型 + /// 已知:3为黄豆表情包, 2为房间表情包,5为全站表情包 + /// + [JsonProperty("pkg_type")] + public int Type { get; set; } + + /// + /// 表情包封面图 + /// + [JsonProperty("current_cover")] + public string Cover { get; set; } + + [JsonProperty("unlock_identity")] + public int UnlockIdentity { get; set; } + + [JsonProperty("unlock_need_gift")] + public int UnlockNeedGift { get; set; } + + [JsonProperty("emoticons")] + public ObservableCollection Emoticons { get; set; } + } + + public class LiveRoomEmoticon + { + [JsonProperty("bulge_display")] + public int BulgeDisplay { get; set; } + + [JsonProperty("width")] + public int Width { get; set; } + + /// + /// 是否为大表情 + /// + public bool IsBigSticker => Width > 0; + + [JsonProperty("emoticon_id")] + public int Id { get; set; } + + /// + /// 表情包ID, 似乎可以唯一标识一个表情 + /// + [JsonProperty("emoticon_unique")] + public string Unique { get; set; } + + [JsonProperty("descript")] + public string Descript { get; set; } + + [JsonProperty("url")] + public string Url { get; set; } + + /// + /// 表情文本, 用于显示至弹幕 + /// + [JsonProperty("emoji")] + public string Text { get; set; } + + /// + /// 表情文本 + 解锁需要条件(如有) + /// + public string ShowText => Text + (UnlockShowText.Length > 0 ? "\n[" + UnlockShowText + "]" : ""); + + /// + /// 0: 未解锁, 1: 已解锁 + /// + [JsonProperty("perm")] + public int Perm { get; set; } + + /// + /// 显示的图片透明度, 未解锁为0.5 + /// + public double Opacity => Perm == 0 ? 0.5 : 1.0; + + /// + /// 是否显示上锁图标 + /// + public bool LockIconVisibility => Perm == 0; + + /// + /// 解锁需要的条件 + /// + [JsonProperty("unlock_show_text")] + public string UnlockShowText { get; set; } + } +} diff --git a/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs b/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs index bdff23e0c..6e57918e0 100644 --- a/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs +++ b/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; using BiliLite.Models.Common; +using BiliLite.Models.Common.Live; +using Newtonsoft.Json; namespace BiliLite.Models.Requests.Api.Live { @@ -156,7 +158,7 @@ public ApiModel SendBagGift(long ruid, int giftId, int num, int bagId, int roomI body = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey", need_cookie = true, }; - api.body += $"&biz_code=live&biz_id={roomId}&gift_id={giftId}&gift_num={num}&price=0&bag_id={bagId}&rnd={TimeExtensions.GetTimestampMS()}&ruid={ruid}&uid={SettingService.Account.UserID}"; + api.body += $"&biz_code=live&biz_id={roomId}&gift_id={giftId}&gift_num={num}&price=0&bag_id={bagId}&rnd={TimeExtensions.GetTimestampMs()}&ruid={ruid}&uid={SettingService.Account.UserID}"; api.body += ApiHelper.GetSign(api.body, AppKey); return api; } @@ -174,7 +176,7 @@ public ApiModel SendGift(long ruid, int giftId, string coinType, int num, int ro body = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey", need_cookie = true, }; - api.body += $"&biz_code=live&biz_id={roomId}&gift_id={giftId}&gift_num={num}&price={price}&rnd={TimeExtensions.GetTimestampMS()}&ruid={ruid}&uid={SettingService.Account.UserID}"; + api.body += $"&biz_code=live&biz_id={roomId}&gift_id={giftId}&gift_num={num}&price={price}&rnd={TimeExtensions.GetTimestampMs()}&ruid={ruid}&uid={SettingService.Account.UserID}"; api.body += ApiHelper.GetSign(api.body, AppKey); return api; @@ -192,7 +194,35 @@ public ApiModel SendDanmu(string text, int roomId) baseUrl = $"https://api.live.bilibili.com/api/sendmsg", parameter = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey", }; - api.body = $"cid={roomId}&mid={SettingService.Account.UserID}&msg={Uri.EscapeDataString(text)}&rnd={TimeExtensions.GetTimestampMS()}&mode=1&pool=0&type=json&color=16777215&fontsize=25&playTime=0.0"; + api.body = $"cid={roomId}&mid={SettingService.Account.UserID}&msg={Uri.EscapeDataString(text)}&rnd={TimeExtensions.GetTimestampMs()}&mode=1&pool=0&type=json&color=16777215&fontsize=25&playTime=0.0"; + api.parameter += ApiHelper.GetSign(api.body, AppKey); + return api; + } + + /// + /// ios端使用的发送弹幕api + /// 更加高级, 可用于发送大表情等 + /// + /// 直播间号 + /// 表情信息 + /// + public ApiModel SendDanmu(int roomId, LiveRoomEmoticon emoji) + { + var jsonObj = new + { + content = $"{emoji.Text}", + emoticon_unique = $"{emoji.Unique}", + dm_type = 1, + }; + var extra = JsonConvert.SerializeObject(jsonObj); + + var api = new ApiModel + { + method = HttpMethods.Post, + baseUrl = $"https://api.live.bilibili.com/xlive/app-room/v1/dM/sendmsg", + parameter = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey", + body = $"msg={emoji.Unique}&dm_type=1&extra={extra}&cid={roomId}&mid={SettingService.Account.UserID}&ts={TimeExtensions.GetTimestampS()}&rnd={TimeExtensions.GetTimestampMs()}&mode=1&pool=0&type=json&color=16777215&fontsize=25" + }; api.parameter += ApiHelper.GetSign(api.body, AppKey); return api; } @@ -400,5 +430,22 @@ public ApiModel JoinRedPocketLottery(long uid, int room_id, long ruid, int lot_i }; return api; } + + /// + /// 获取直播间表情 + /// + /// 房间号 + /// + public ApiModel GetLiveRoomEmoticon(int room_id) + { + var api = new ApiModel() + { + method = HttpMethods.Get, + baseUrl = $"https://api.live.bilibili.com/xlive/web-ucenter/v2/emoticon/GetEmoticons", + parameter = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey&room_id={room_id}", + }; + api.parameter += ApiHelper.GetSign(api.parameter, AppKey); + return api; + } } } diff --git a/src/BiliLite.UWP/Modules/Live/LiveMessage.cs b/src/BiliLite.UWP/Modules/Live/LiveMessage.cs index 1fea8e3b7..f58b4b7f0 100644 --- a/src/BiliLite.UWP/Modules/Live/LiveMessage.cs +++ b/src/BiliLite.UWP/Modules/Live/LiveMessage.cs @@ -332,7 +332,7 @@ private MessageDelayType ParseMessage(string jsonMessage) w.UserID = obj["data"]["uid"].ToString(); w.MsgType = obj["data"]["msg_type"].ToInt32(); - if (obj["data"]["fans_medal"]["medal_level"].ToInt32() != 0) + if (obj["data"]["fans_medal"].ToString().Length != 0 && obj["data"]["fans_medal"]["medal_level"].ToInt32() != 0) { w.MedalName = obj["data"]["fans_medal"]["medal_name"].ToString(); w.MedalLevel = obj["data"]["fans_medal"]["medal_level"].ToInt32(); @@ -502,6 +502,13 @@ private MessageDelayType ParseMessage(string jsonMessage) } return MessageDelayType.SystemMessage; } + else if (cmd == "ONLINE_RANK_COUNT") // 在线人数变动, 即网页端的"房间观众()括号中的数字" + { + if (obj["data"] != null) + { + NewMessage?.Invoke(MessageType.OnlineCountChange, obj["data"]["online_count_text"].ToString()); + } + } else if (cmd == "ONLINE_RANK_V2") { if (obj["data"] != null && obj["data"]["list"] != null) diff --git a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml index 3811f02fc..9ec7ce62c 100644 --- a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml +++ b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml @@ -302,7 +302,7 @@ - + @@ -350,7 +350,7 @@ - + @@ -362,7 +362,7 @@ - + @@ -372,6 +372,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -660,9 +695,28 @@ --> - - - + + + + @@ -878,7 +932,7 @@ - + @@ -1105,13 +1159,13 @@ - + - 粉丝: + 粉丝: @@ -1145,11 +1199,11 @@ - + - + - + @@ -1169,9 +1223,9 @@ - + - + @@ -1233,7 +1287,19 @@ - + + @@ -1246,7 +1312,7 @@ - + @@ -1326,7 +1392,7 @@ - + @@ -1374,7 +1440,7 @@ - + diff --git a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs index 5c0f1045f..653e85a8c 100644 --- a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs +++ b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs @@ -121,6 +121,12 @@ public LiveDetailPage() BottomBtnGiftRow.Visibility = Visibility.Collapsed; BottomGiftBar.Visibility = Visibility.Collapsed; }; + m_liveRoomViewModel.RefreshGuardNum += (_, e) => + { + var temp = pivot.SelectedIndex; + pivot.SelectedIndex = 3; + pivot.SelectedIndex = temp; + }; this.Loaded += LiveDetailPage_Loaded; this.Unloaded += LiveDetailPage_Unloaded; @@ -752,10 +758,14 @@ private async void SetFullWindow(bool e) if (e) { await m_playerController.ContentState.FullWindow(); + BottomBtnSendDanmakuWide.Visibility = Visibility.Visible; + BottomBtnGiftRow.Visibility = Visibility.Collapsed; } else { await m_playerController.ContentState.CancelFullWindow(); + BottomBtnGiftRow.Visibility = Visibility.Visible; + BottomBtnSendDanmakuWide.Visibility = Visibility.Collapsed; } } @@ -765,10 +775,14 @@ private async void SetFullScreen(bool e) if (e) { await m_playerController.ScreenState.Fullscreen(); + BottomBtnSendDanmakuWide.Visibility = Visibility.Visible; + BottomBtnGiftRow.Visibility = Visibility.Collapsed; } else { await m_playerController.ScreenState.CancelFullscreen(); + BottomBtnGiftRow.Visibility = Visibility.Visible; + BottomBtnSendDanmakuWide.Visibility = Visibility.Collapsed; } } @@ -783,6 +797,7 @@ private async void btnSendGift_Click(object sender, RoutedEventArgs e) if (sender is Button { DataContext: LiveGiftItem giftInfo }) { await m_liveRoomViewModel.SendGift(giftInfo); + await m_liveRoomViewModel.GetEmoticons(); // 送礼物有可能解锁权限,刷新表情包 } } @@ -791,6 +806,7 @@ private async void btnSendBagGift_Click(object sender, RoutedEventArgs e) if (sender is Button { DataContext: LiveGiftItem giftInfo }) { await m_liveRoomViewModel.SendBagGift(giftInfo); + await m_liveRoomViewModel.GetEmoticons(); // 送礼物有可能解锁权限,刷新表情包 } } @@ -972,17 +988,15 @@ private void BtnOpenDanmuSpace_Click(object sender, RoutedEventArgs e) private async void DanmuText_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) { - if (string.IsNullOrEmpty(DanmuText.Text)) + if (string.IsNullOrEmpty(sender.Text)) { Notify.ShowMessageToast("弹幕内容不能为空"); return; } - var result = await m_liveRoomViewModel.SendDanmu(DanmuText.Text); - if (result) - { - DanmuText.Text = ""; - } + var result = await m_liveRoomViewModel.SendDanmu(sender.Text); + if(result) sender.Text = ""; + await m_liveRoomViewModel.GetEmoticons(); // 长期不看的观众即使在粉丝团也无法发表情, 此时发弹幕即可解锁 } private async void BtnAttention_Click(object sender, RoutedEventArgs e) @@ -1441,5 +1455,43 @@ private void RootGrid_PointerEntered(object sender, PointerRoutedEventArgs e) } private void RootGrid_PointerExited(object sender, PointerRoutedEventArgs e) => isPointerInThisPage = false; + + private async void EmojiButton_Click(object sender, RoutedEventArgs e) + { + if (sender is not Button button) return; + EmojiFlyout.ShowAt(button); + if(m_liveRoomViewModel.EmoticonsPackages.Count == 0) + { + await m_liveRoomViewModel.GetEmoticons(); + } + } + + private void Danmu_TextChanged(object sender, AutoSuggestBoxTextChangedEventArgs e) + { + if (sender is not AutoSuggestBox obj) return; + switch (obj.Name) + { + case "DanmuText": + DanmuTextWide.Text = obj.Text; + break; + case "DanmuTextWide": + DanmuText.Text = obj.Text; + break; + } + } + + private async void EmojiItem_Click(object sender, ItemClickEventArgs e) + { + if (e.ClickedItem is not LiveRoomEmoticon emoji) return; + if (!emoji.IsBigSticker) + { + DanmuText.Text += emoji.Text; + } + else + { + await m_liveRoomViewModel.SendDanmu(emoji); + EmojiFlyout.Hide(); + } + } } } diff --git a/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs b/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs index 4817e60da..9b541b84a 100644 --- a/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs +++ b/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs @@ -145,9 +145,9 @@ public LiveRoomViewModel() public bool ShowGiftMessage { get; set; } /// - /// 看过的人数(替代人气值) + /// 房间在线观众数量与看过的人数(替代人气值) /// - public string WatchedNum { get; set; } + public string ViewerNumCount { get; set; } /// /// 舰长数 @@ -173,6 +173,8 @@ public LiveRoomViewModel() [DoNotNotify] public LiveRoomWebUrlQualityDescriptionItemModel CurrentQn { get; set; } + public ObservableCollection EmoticonsPackages { get; set; } + public List Qualites { get; set; } public List Gifts { get; set; } @@ -201,7 +203,7 @@ public LiveRoomViewModel() [DoNotNotify] public int GuardPage { get; set; } = 1; - public bool LoadingGuard { get; set; } = true; + public bool LoadingGuard { get; set; } = false; public bool LoadMoreGuard { get; set; } @@ -255,6 +257,8 @@ public LiveRoomViewModel() public event EventHandler SpecialLiveRoomHideElements; + public event EventHandler RefreshGuardNum; + #endregion #region Private Methods @@ -373,7 +377,7 @@ await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatch } } - private async void ReceiveMessage(int roomId) + private async Task ReceiveMessage(int roomId) { try { @@ -471,8 +475,8 @@ private List GetSpecialPlayUrls(LiveRoomPlayUrlModel liveRoomPl routeIndex++; } - // 暂时不使用hevc流 - var codec = codecList.FirstOrDefault(item => item.CodecName == "avc"); + // 暂时不使用hevc流, 但无法保证avc流一定存在 + var codec = codecList.Count > 1 ? codecList.FirstOrDefault(item => item.CodecName == "avc") : codecList[0]; var acceptQnList = codec.AcceptQn; Qualites ??= liveRoomPlayUrlModel.PlayUrlInfo.PlayUrl.GQnDesc.Where(item => acceptQnList.Contains(item.Qn)).ToList(); @@ -668,8 +672,10 @@ public async Task LoadLiveRoomDetail(string id) m_liveMessage = new LiveMessage(); m_liveMessage.NewMessage += LiveMessage_NewMessage; m_cancelSource = new System.Threading.CancellationTokenSource(); + m_timer.Start(); Loading = true; + var result = await m_liveRoomApi.LiveRoomInfo(id).Request(); if (!result.status) { @@ -682,38 +688,51 @@ public async Task LoadLiveRoomDetail(string id) throw new CustomizedErrorException("加载直播间失败:" + data.message); } - if (data.data.GuardInfo == null) + LiveInfo = data.data; + RoomID = LiveInfo.RoomInfo.RoomId; + RoomTitle = LiveInfo.RoomInfo.Title; + Live = LiveInfo.RoomInfo.LiveStatus == 1; + AnchorUid = LiveInfo.RoomInfo.Uid; + + var buvidResults = await m_liveRoomApi.GetBuvid().Request(); + var buvidData = await buvidResults.GetJson>(); + Buvid3 = buvidData.data.B3; + + if (Live) + { + await GetPlayUrls(RoomID, SettingService.GetValue(SettingConstants.Live.DEFAULT_QUALITY, 10000)); + } + + ReceiveMessage(LiveInfo.RoomInfo.RoomId).RunWithoutAwait(); // 连接弹幕优先级提高 + + await GetEmoticons(); + + await LoadSuperChat(); + + if (LiveInfo.GuardInfo == null) { IsSpecialLiveRoom = true; SpecialLiveRoomHideElements?.Invoke(this, null); - }; - - RoomID = data.data.RoomInfo.RoomId; - RoomTitle = data.data.RoomInfo.Title; - Live = data.data.RoomInfo.LiveStatus == 1; - GuardNum = !IsSpecialLiveRoom ? data.data.GuardInfo.Count : 0; - AnchorUid = data.data.RoomInfo.Uid; - LiveInfo = data.data; + } + else + { + GuardNum = !IsSpecialLiveRoom ? LiveInfo.GuardInfo.Count : 0; + await GetGuardList(); + } if (Ranks == null) { - Ranks = new List() - { + Ranks = + [ new LiveRoomRankViewModel(RoomID, AnchorUid, "高能用户贡献榜", "contribution-rank"), new LiveRoomRankViewModel(RoomID, AnchorUid, "粉丝榜", "fans"), - }; + ]; SelectRank = Ranks[0]; } - await LoadAnchorProfile(); - m_timer.Start(); - if (Live) - { - await GetPlayUrls(RoomID, SettingService.GetValue(SettingConstants.Live.DEFAULT_QUALITY, 10000)); - } + //GetFreeSilverTime(); - await LoadSuperChat(); if (ReceiveLotteryMsg) { // 天选抽奖和红包抽奖 @@ -729,12 +748,7 @@ public async Task LoadLiveRoomDetail(string id) await GetTitles(); } - var buvidResults = await m_liveRoomApi.GetBuvid().Request(); - var buvidData = await buvidResults.GetJson>(); - Buvid3 = buvidData.data.B3; - - EntryRoom(); - ReceiveMessage(data.data.RoomInfo.RoomId); + await EntryRoom(); } catch (CustomizedErrorException ex) { @@ -813,7 +827,7 @@ public async Task LoadSuperChat() /// /// 进入房间 /// - public async void EntryRoom() + public async Task EntryRoom() { try { @@ -1077,6 +1091,7 @@ public async Task ReloadGuardList() Guards?.Clear(); GuardPage = 1; await GetGuardList(); + RefreshGuardNum?.Invoke(null, null); } public async Task GetFreeSilverTime() @@ -1245,6 +1260,44 @@ public async Task SendDanmu(string text) } } + public async Task SendDanmu(LiveRoomEmoticon emoji) + { + if (!Logined && !await Notify.ShowLoginDialog()) + { + Notify.ShowMessageToast("请先登录"); + return; + } + if (emoji.Perm != 1) + { + Notify.ShowMessageToast("权限不足哦~\n" + $"需要: {emoji.UnlockShowText}"); + return; + } + try + { + var result = await m_liveRoomApi.SendDanmu(RoomID, emoji).Request(); + if (!result.status) + { + throw new CustomizedErrorException(result.message); + } + + var data = await result.GetData(); + if (!data.success) + { + throw new CustomizedErrorException(data.message); + } + } + catch (CustomizedErrorException ex) + { + Notify.ShowMessageToast(ex.Message); + _logger.Error(ex.Message, ex); + } + catch (Exception ex) + { + _logger.Log("发送表情弹幕出现错误", LogType.Error, ex); + Notify.ShowMessageToast("发送表情弹幕出现错误"); + } + } + public async Task JoinAnchorLottery() { try @@ -1314,6 +1367,35 @@ public async Task JoinRedPocketLottery() } + public async Task GetEmoticons() + { + if (!Logined && !await Notify.ShowLoginDialog()) + { + Notify.ShowMessageToast("请先登录"); + return; + } + try + { + var result = await m_liveRoomApi.GetLiveRoomEmoticon(RoomID).Request(); + if (!result.status) throw new CustomizedErrorException(result.message); + var data = await result.GetData(); + if (!data.success) throw new CustomizedErrorException(data.message); + + if (EmoticonsPackages?.Count > 0) EmoticonsPackages?.Clear(); + EmoticonsPackages = JsonConvert.DeserializeObject>(data.data["data"].ToString()); + } + catch (CustomizedErrorException ex) + { + Notify.ShowMessageToast(ex.Message); + _logger.Error(ex.Message, ex); + } + catch (Exception ex) + { + _logger.Log("获取表情包出现错误", LogType.Error, ex); + Notify.ShowMessageToast("获取表情包出现错误"); + } + } + public void CheckClearMessages() { if (Messages.Count >= CleanCount) Messages.RemoveAt(0);