From 6ced93d8762d6a884c9266f5c9348ac3b94c05b1 Mon Sep 17 00:00:00 2001
From: GD-Slime <82302542+GD-Slime@users.noreply.github.com>
Date: Sat, 2 Dec 2023 17:06:51 +0800
Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=8C=E7=BB=B4?=
=?UTF-8?q?=E7=A0=81=E7=99=BB=E5=BD=95=E4=B8=8B=E6=97=A0=E6=92=AD=E6=94=BE?=
=?UTF-8?q?=E5=88=97=E8=A1=A8=E7=9A=84=E9=97=AE=E9=A2=98=20(#420)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 修复二维码登录下无播放列表的问题
---
.../Common/Video/VideoUgcSeasonSectionEpisode.cs | 14 ++++++++++++--
src/BiliLite.UWP/Pages/VideoDetailPage.xaml | 9 +++------
.../ViewModels/Video/VideoDetailPageViewModel.cs | 16 ++++++++++++++++
3 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/src/BiliLite.UWP/Models/Common/Video/VideoUgcSeasonSectionEpisode.cs b/src/BiliLite.UWP/Models/Common/Video/VideoUgcSeasonSectionEpisode.cs
index f8d128d44..265ccb946 100644
--- a/src/BiliLite.UWP/Models/Common/Video/VideoUgcSeasonSectionEpisode.cs
+++ b/src/BiliLite.UWP/Models/Common/Video/VideoUgcSeasonSectionEpisode.cs
@@ -1,9 +1,12 @@
-using Newtonsoft.Json;
+using BiliLite.Models.Common.Video.Detail;
+using Newtonsoft.Json;
namespace BiliLite.Models.Common.Video
{
public class VideoUgcSeasonSectionEpisode
{
+ private string m_cover;
+
public long Id { get; set; }
public string Aid { get; set; }
@@ -12,7 +15,11 @@ public class VideoUgcSeasonSectionEpisode
public string Title { get; set; }
- public string Cover { get; set; }
+ public string Cover
+ {
+ get => m_cover ?? Arc.Pic;
+ set => m_cover = value;
+ }
[JsonProperty("cover_right_text")]
public string CovverRightText { get; set; }
@@ -34,5 +41,8 @@ public class VideoUgcSeasonSectionEpisode
[JsonProperty("first_frame")]
public string FirstFrame { get; set; }
+
+ [JsonProperty("arc")]
+ public VideoDetailModel Arc { get; set; } // 简单复用一下
}
}
diff --git a/src/BiliLite.UWP/Pages/VideoDetailPage.xaml b/src/BiliLite.UWP/Pages/VideoDetailPage.xaml
index 4b5089276..f54b6d3d0 100644
--- a/src/BiliLite.UWP/Pages/VideoDetailPage.xaml
+++ b/src/BiliLite.UWP/Pages/VideoDetailPage.xaml
@@ -38,11 +38,9 @@
-
+
-
-
-
+
@@ -53,8 +51,7 @@
diff --git a/src/BiliLite.UWP/ViewModels/Video/VideoDetailPageViewModel.cs b/src/BiliLite.UWP/ViewModels/Video/VideoDetailPageViewModel.cs
index 65bc9414a..46963aa99 100644
--- a/src/BiliLite.UWP/ViewModels/Video/VideoDetailPageViewModel.cs
+++ b/src/BiliLite.UWP/ViewModels/Video/VideoDetailPageViewModel.cs
@@ -224,6 +224,7 @@ public async Task LoadVideoDetail(string id, bool isbvid = false)
var data = await results.GetJson>();
+ // 通过web获取, 作为后备使用
if (!data.success)
{
// 通过web获取视频详情
@@ -252,6 +253,21 @@ public async Task LoadVideoDetail(string id, bool isbvid = false)
throw new CustomizedErrorException(data.message);
}
+ var webResults = await videoAPI.DetailWebInterface(id, isbvid).Request();
+ if (!webResults.status)
+ {
+ throw new CustomizedErrorException(webResults.message);
+ }
+ var webData = await webResults.GetJson>();
+ if (!webData.success)
+ {
+ throw new CustomizedErrorException(webData.message);
+ }
+ if (data.data.UgcSeason == null && webData.data.UgcSeason != null)
+ {
+ data.data.UgcSeason = webData.data.UgcSeason;
+ }
+
var videoInfoViewModel = m_mapper.Map(data.data);
VideoInfo = videoInfoViewModel;
if (needGetUserReq)
From ed655be4213414e1bfd302831cf5f9e5615b5377 Mon Sep 17 00:00:00 2001
From: GD-Slime <82302542+GD-Slime@users.noreply.github.com>
Date: Sat, 2 Dec 2023 18:20:18 +0800
Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=8C=E6=9B=B4?=
=?UTF-8?q?=E6=94=B9=EF=BC=8C=E6=96=B0=E5=A2=9E=E7=9B=B4=E6=92=AD=E9=97=B4?=
=?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=86=85=E5=AE=B9=20(#410)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
修复:
- 修复仅有黄豆表情时错位
- 修复送礼物功能
- 修复右侧栏收到礼物时右侧栏停止自动滚动的问题
- 修复进场通知
- 修复人气值(改为新的“看过”)
- 修复在加载舰长列表时的无限加载最后几位的问题
- 修复了同一时间接收弹幕量过高时视频上的弹幕堆积的问题
- 修复榜单(更改为现在的高能用户贡献榜单)
- 修正一些typo
更改:
- 互动区自动清理现在为队列式(queue)
- 丰富了用户进入舰队时的显示内容
- 更改了右侧栏内容的字重与颜色
- 更改了大航海用户的名字颜色
- 用户名现在可以被选中和复制
- 更改了天选抽奖的布局并使体验更好
- 为大航海下的列表加入了头像显示
新增:
- 新增用户被直播间禁言提示
- 新增直播间被警告提示
- 新增直播间被切断提示
- ToRichText方法现在可以更改对象的颜色和字重(有默认值)
- 新增直播间开始直播提示,并重新会加载播放Url
- 新增人气红包功能
---
src/BiliLite.UWP/Assets/Live/RedPocket.png | Bin 0 -> 21902 bytes
src/BiliLite.UWP/BiliLite.UWP.csproj | 8 +-
.../Extensions/StringExtensions.cs | 16 +-
src/BiliLite.UWP/Models/Common/Enumerates.cs | 49 +++--
.../Models/Common/Live/DanmuMsgModel.cs | 20 +-
.../Models/Common/Live/InteractWordModel.cs | 21 ++
.../Live/LiveMessageHandleActionsMap.cs | 152 +++++++++----
.../Live/LiveRoomAnchorLotteryInfoModel.cs | 52 +++++
.../Live/LiveRoomEndAnchorLotteryInfoModel.cs | 57 ++++-
.../LiveRoomEndRedPocketLotteryInfoModel.cs | 117 ++++++++++
.../Common/Live/LiveRoomRankItemModel.cs | 15 +-
.../Live/LiveRoomRedPocketLotteryInfoModel.cs | 193 +++++++++++++++++
.../Models/Common/Live/RoomBlockMsgModel.cs | 9 +
.../Common/Live/WarningOrCutOffMsgModel.cs | 9 +
.../Models/Common/Live/WelcomeMsgModel.cs | 11 -
.../Models/Requests/Api/Live/LiveRoomAPI.cs | 34 +--
src/BiliLite.UWP/Modules/Live/LiveMessage.cs | 152 +++++++++----
src/BiliLite.UWP/Pages/LiveDetailPage.xaml | 201 ++++++++++++++++--
src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs | 102 +++++++--
.../Live/LiveRoomAnchorLotteryViewModel.cs | 116 ----------
.../Live/LiveRoomLotteryViewModel.cs | 191 +++++++++++++++++
.../ViewModels/Live/LiveRoomRankViewModel.cs | 32 +--
.../ViewModels/Live/LiveRoomViewModel.cs | 98 +++++----
23 files changed, 1317 insertions(+), 338 deletions(-)
create mode 100644 src/BiliLite.UWP/Assets/Live/RedPocket.png
create mode 100644 src/BiliLite.UWP/Models/Common/Live/InteractWordModel.cs
create mode 100644 src/BiliLite.UWP/Models/Common/Live/LiveRoomEndRedPocketLotteryInfoModel.cs
create mode 100644 src/BiliLite.UWP/Models/Common/Live/LiveRoomRedPocketLotteryInfoModel.cs
create mode 100644 src/BiliLite.UWP/Models/Common/Live/RoomBlockMsgModel.cs
create mode 100644 src/BiliLite.UWP/Models/Common/Live/WarningOrCutOffMsgModel.cs
delete mode 100644 src/BiliLite.UWP/Models/Common/Live/WelcomeMsgModel.cs
delete mode 100644 src/BiliLite.UWP/ViewModels/Live/LiveRoomAnchorLotteryViewModel.cs
create mode 100644 src/BiliLite.UWP/ViewModels/Live/LiveRoomLotteryViewModel.cs
diff --git a/src/BiliLite.UWP/Assets/Live/RedPocket.png b/src/BiliLite.UWP/Assets/Live/RedPocket.png
new file mode 100644
index 0000000000000000000000000000000000000000..f698eb6bedd08c6d1aaa212a1db947d8c635d0a1
GIT binary patch
literal 21902
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
literal 0
HcmV?d00001
diff --git a/src/BiliLite.UWP/BiliLite.UWP.csproj b/src/BiliLite.UWP/BiliLite.UWP.csproj
index 90f5d19d8..d3c850557 100644
--- a/src/BiliLite.UWP/BiliLite.UWP.csproj
+++ b/src/BiliLite.UWP/BiliLite.UWP.csproj
@@ -137,7 +137,12 @@
+
+
+
+
+
@@ -218,13 +223,12 @@
+
-
-
diff --git a/src/BiliLite.UWP/Extensions/StringExtensions.cs b/src/BiliLite.UWP/Extensions/StringExtensions.cs
index 42ca7152d..c16da0ede 100644
--- a/src/BiliLite.UWP/Extensions/StringExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/StringExtensions.cs
@@ -79,7 +79,7 @@ public static string TraditionalToSimplified(this string input)
///
///
///
- public static RichTextBlock ToRichTextBlock(this string txt, JObject emote, bool isLive = false)
+ public static RichTextBlock ToRichTextBlock(this string txt, JObject emote, bool isLive = false, string color = null, string fontWeight = "Normal")
{
var input = txt;
try
@@ -105,11 +105,14 @@ public static RichTextBlock ToRichTextBlock(this string txt, JObject emote, bool
if (!isLive) { input = HandelVideoID(input); }
//生成xaml
- var xaml = string.Format(@"
+ xmlns:mc = ""http://schemas.openxmlformats.org/markup-compatibility/2006"" LineHeight=""{1}"" {2} {3}>
{0}
- ", input, isLive ? 22 : 20);
+ ", input,
+ isLive ? 22 : 20,
+ color == null ? "" : $"Foreground=\"{color}\"",
+ $"FontWeight=\"{fontWeight}\"");
var p = (RichTextBlock)XamlReader.Load(xaml);
return p;
}
@@ -340,6 +343,9 @@ private static string HandelEmoji(string input, JObject emote)
return input;
}
+ ///
+ /// 处理直播黄豆表情
+ ///
private static string HandleLiveEmoji(string input, JObject emotes)
{
if (emotes == null) return input;
@@ -349,7 +355,7 @@ private static string HandleLiveEmoji(string input, JObject emotes)
if (!emotes.TryGetValue(emojiCode, out var emote)) continue;
var replacement = string.Format(
- @"",
+ @"",
emote["url"], emote["width"], emote["height"]);
input = input.Replace(emojiCode, replacement);
diff --git a/src/BiliLite.UWP/Models/Common/Enumerates.cs b/src/BiliLite.UWP/Models/Common/Enumerates.cs
index 024c476b9..1a5abb626 100644
--- a/src/BiliLite.UWP/Models/Common/Enumerates.cs
+++ b/src/BiliLite.UWP/Models/Common/Enumerates.cs
@@ -306,10 +306,10 @@ public enum MessageType
///
ConnectSuccess,
- ///
- /// 在线人数
- ///
- Online,
+ /////
+ ///// 在线人数(即人气值, 已弃用)
+ /////
+ //Online,
///
/// 弹幕
@@ -324,12 +324,12 @@ public enum MessageType
///
/// 欢迎信息
///
- Welcome,
+ InteractWord,
///
- /// 系统消息
+ /// 系统消息 (未做实现), 先注释
///
- SystemMsg,
+ //SystemMsg,
///
/// 醒目留言
@@ -346,12 +346,7 @@ public enum MessageType
///
AnchorLotteryStart,
- ///
- /// 抽奖结束
- ///
- AnchorLotteryEnd,
- ///
/// 抽奖结果
///
AnchorLotteryAward,
@@ -370,5 +365,35 @@ public enum MessageType
/// 房间信息更新
///
RoomChange,
+
+ ///
+ /// 指定观众禁言
+ ///
+ RoomBlock,
+
+ ///
+ /// 超管警告或切断
+ ///
+ WaringOrCutOff,
+
+ ///
+ /// 开始直播
+ ///
+ StartLive,
+
+ ///
+ /// 看过直播的人数变化(代替人气值)
+ ///
+ WatchedChange,
+
+ ///
+ /// 红包抽奖开始
+ ///
+ RedPocketLotteryStart,
+
+ ///
+ /// 红包抽奖赢家
+ ///
+ RedPocketLotteryWinner,
}
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/Live/DanmuMsgModel.cs b/src/BiliLite.UWP/Models/Common/Live/DanmuMsgModel.cs
index 36b6222e0..fa4ac5fa4 100644
--- a/src/BiliLite.UWP/Models/Common/Live/DanmuMsgModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Live/DanmuMsgModel.cs
@@ -29,10 +29,15 @@ public class DanmuMsgModel
public string UserName { get; set; }
///
- /// 用户名颜色,默认灰色
+ /// 用户名颜色, 默认灰色
///
public string UserNameColor { get; set; } = "#FF808080";
+ ///
+ /// 用户名字重, 默认Normal
+ ///
+ public string UserNameFontWeight { get; set; } = "Normal";
+
/////
///// 等级
/////
@@ -81,12 +86,21 @@ public class DanmuMsgModel
///
/// 用户上的舰的图片
///
- public string UserCaptainImage { get; set; }
+ public string UserCaptainImage
+ {
+ get => UserCaptain switch
+ {
+ "舰长" => "/Assets/Live/ic_live_guard_3.png",
+ "提督" => "/Assets/Live/ic_live_guard_2.png",
+ "总督" => "/Assets/Live/ic_live_guard_1.png",
+ _ => null,
+ };
+ }
///
/// 黄豆表情
///
- public JContainer Emoji { get; set; }
+ public JObject Emoji { get; set; }
///
/// 各类大表情
diff --git a/src/BiliLite.UWP/Models/Common/Live/InteractWordModel.cs b/src/BiliLite.UWP/Models/Common/Live/InteractWordModel.cs
new file mode 100644
index 000000000..5a46eba77
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/Live/InteractWordModel.cs
@@ -0,0 +1,21 @@
+using Windows.UI.Xaml;
+
+namespace BiliLite.Models.Common.Live
+{
+ public class InteractWordModel
+ {
+ public string UserName { get; set; }
+
+ public string UserID { get; set; }
+
+ public int MsgType { get; set; }
+
+ public string MedalName { get; set; }
+
+ public string MedalLevel { get; set; }
+
+ public string MedalColor { get; set; }
+
+ public Visibility ShowMedal { get; set; } = Visibility.Collapsed;
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs b/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs
index 4208c55a3..b765667dc 100644
--- a/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs
+++ b/src/BiliLite.UWP/Models/Common/Live/LiveMessageHandleActionsMap.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using BiliLite.Modules.Live;
using Windows.UI.Xaml;
using BiliLite.ViewModels.Live;
using Newtonsoft.Json;
+using BiliLite.Extensions;
+using BiliLite.Services;
namespace BiliLite.Models.Common.Live
{
@@ -15,19 +16,23 @@ public LiveMessageHandleActionsMap()
Map = new Dictionary>
{
{ MessageType.ConnectSuccess, ConnectSuccess },
- { MessageType.Online, Online },
+ //{ MessageType.Online, Online },
{ MessageType.Danmu, Danmu },
{ MessageType.Gift, Gift },
- { MessageType.Welcome, Welcome },
- { MessageType.WelcomeGuard, WelcomeGuard },
- { MessageType.SystemMsg, SystemMsg },
+ { MessageType.InteractWord, InteractWord },
+ //{ MessageType.SystemMsg, SystemMsg },
{ MessageType.SuperChat, SuperChat },
{ MessageType.SuperChatJpn, SuperChat },
{ MessageType.AnchorLotteryStart, AnchorLotteryStart },
- { MessageType.AnchorLotteryEnd, AnchorLotteryEnd },
{ MessageType.AnchorLotteryAward, AnchorLotteryAward },
{ MessageType.GuardBuy, GuardBuy },
{ MessageType.RoomChange, RoomChange },
+ { MessageType.RoomBlock, RoomBlock },
+ { MessageType.WaringOrCutOff, WaringOrCutOff },
+ { MessageType.StartLive, StartLive },
+ { MessageType.WatchedChange, WatchedChange },
+ { MessageType.RedPocketLotteryStart, RedPocketLotteryStart},
+ { MessageType.RedPocketLotteryWinner, RedPocketLotteryWinner},
};
}
@@ -35,7 +40,11 @@ public LiveMessageHandleActionsMap()
public event EventHandler AddNewDanmu;
- public event EventHandler LotteryEnd;
+ public event EventHandler AnchorLotteryEnd;
+
+ public event EventHandler RedPocketLotteryEnd;
+
+ public event EventHandler AnchorInfoLiveInfo;
private void ConnectSuccess(LiveRoomViewModel viewModel, object message)
{
@@ -45,18 +54,17 @@ private void ConnectSuccess(LiveRoomViewModel viewModel, object message)
});
}
- private void Online(LiveRoomViewModel viewModel, object message)
+ private void WatchedChange(LiveRoomViewModel viewModel, object message)
{
- viewModel.Online = (int)message;
+ viewModel.WatchedNum = (string)message;
}
private void Danmu(LiveRoomViewModel viewModel, object message)
{
var m = message as DanmuMsgModel;
- m.ShowUserLevel = Visibility.Visible;
if (viewModel.Messages.Count >= viewModel.CleanCount)
{
- viewModel.Messages.Clear();
+ viewModel.Messages.RemoveAt(0);
}
viewModel.Messages.Add(m);
AddNewDanmu?.Invoke(null, m);
@@ -83,34 +91,45 @@ private void Gift(LiveRoomViewModel viewModel, object message)
}
}
- private void Welcome(LiveRoomViewModel viewModel, object message)
+ private void InteractWord(LiveRoomViewModel viewModel, object message)
{
- var info = message as WelcomeMsgModel;
+ var info = message as InteractWordModel;
if (!viewModel.ReceiveWelcomeMsg) return;
- viewModel.Messages.Add(new DanmuMsgModel()
+ var msg = new DanmuMsgModel()
{
UserName = info.UserName,
- UserNameColor = "#FFFF69B4",//Colors.HotPink
- Text = " 进入直播间"
- });
- }
+ // UserNameColor = "#FFFF69B4",//Colors.HotPink
+ RichText = info.MsgType == 1 ? "进入直播间".ToRichTextBlock(null, color: "Gray") : "关注了主播".ToRichTextBlock(null, color: "Gray")
+ };
- private void WelcomeGuard(LiveRoomViewModel viewModel, object message)
- {
- var info = message as WelcomeMsgModel;
- if (!viewModel.ReceiveWelcomeMsg) return;
- viewModel.Messages.Add(new DanmuMsgModel()
+ if (info.ShowMedal == Visibility.Visible)
{
- UserName = info.UserName,
- UserNameColor = "#FFFF69B4",//Colors.HotPink
- Text = " (舰长)进入直播间"
- });
- }
+ msg.MedalColor = info.MedalColor;
+ msg.MedalName = info.MedalName;
+ msg.MedalLevel = info.MedalLevel;
+ msg.ShowMedal = info.ShowMedal;
+ }
- private void SystemMsg(LiveRoomViewModel viewModel, object message)
- {
+ viewModel.Messages.Add(msg);
}
+ // 已被b站弃用
+ //private void WelcomeGuard(LiveRoomViewModel viewModel, object message)
+ //{
+ // var info = message as InteractWordModel;
+ // if (!viewModel.ReceiveWelcomeMsg) return;
+ // viewModel.Messages.Add(new DanmuMsgModel()
+ // {
+ // UserName = info.UserName,
+ // UserNameColor = "#FFFF69B4",//Colors.HotPink
+ // RichText = " (舰长)进入直播间".ToRichTextBlock(null)
+ // });
+ //}
+
+ //private void SystemMsg(LiveRoomViewModel viewModel, object message)
+ //{
+ //}
+
private void SuperChat(LiveRoomViewModel viewModel, object message)
{
viewModel.SuperChats.Add(message as SuperChatMsgViewModel);
@@ -120,29 +139,48 @@ private void AnchorLotteryStart(LiveRoomViewModel viewModel, object message)
{
if (!viewModel.ReceiveLotteryMsg) return;
var info = message.ToString();
- viewModel.AnchorLotteryViewModel.SetLotteryInfo(JsonConvert.DeserializeObject(info));
+ viewModel.LotteryViewModel.SetAnchorLotteryInfo(JsonConvert.DeserializeObject(info));
+
}
- private void AnchorLotteryEnd(LiveRoomViewModel viewModel, object message)
+ private void RedPocketLotteryStart(LiveRoomViewModel viewModel, object message)
{
+ if (!viewModel.ReceiveLotteryMsg) return;
+ var info = message.ToString();
+ viewModel.LotteryViewModel.SetRedPocketLotteryInfo(JsonConvert.DeserializeObject(info));
+
+ viewModel.ShowRedPocketLotteryWinnerList = false;
+ viewModel.RedPocketSendDanmuBtnText = viewModel.Attention ? "一键发送弹幕" : "一键关注并发送弹幕";
+ }
+
+ private void RedPocketLotteryWinner(LiveRoomViewModel viewModel, object message)
+ {
+ if (!viewModel.ReceiveLotteryMsg) return;
+ var info = JsonConvert.DeserializeObject(message.ToString());
+ RedPocketLotteryEnd?.Invoke(this, info);
}
private void AnchorLotteryAward(LiveRoomViewModel viewModel, object message)
{
if (!viewModel.ReceiveLotteryMsg) return;
var info = JsonConvert.DeserializeObject(message.ToString());
- LotteryEnd?.Invoke(this, info);
+ AnchorLotteryEnd?.Invoke(this, info);
}
private void GuardBuy(LiveRoomViewModel viewModel, object message)
{
var info = message as GuardBuyMsgModel;
- viewModel.Messages.Add(new DanmuMsgModel()
+ var msg = new DanmuMsgModel
{
UserName = info.UserName,
UserNameColor = "#FFFF69B4",//Colors.HotPink
- Text = $"成为了{info.GiftName}"
- });
+ RichText = $"成为了主播的{info.GiftName}🎉".ToRichTextBlock(null, fontWeight: "Medium"),
+ UserCaptain = info.GiftName,
+ ShowCaptain = Visibility.Visible,
+ UserNameFontWeight = "SemiBold", // 字重调大, 防止与进场弹幕混淆
+ };
+
+ viewModel.Messages.Add(msg);
// 刷新舰队列表
_ = viewModel.GetGuardList();
}
@@ -152,5 +190,47 @@ private void RoomChange(LiveRoomViewModel viewModel, object message)
var info = message as RoomChangeMsgModel;
viewModel.RoomTitle = info.Title;
}
+
+ private void RoomBlock(LiveRoomViewModel viewModel, object message)
+ {
+ var info = message as RoomBlockMsgModel;
+ var msg = new DanmuMsgModel()
+ {
+ UserName = info.UserName,
+ RichText = "被直播间禁言🚫".ToRichTextBlock(null, fontWeight: "Medium"), // 字重调大, 防止与进场弹幕混淆)
+ UserNameFontWeight = "SemiBold",
+ };
+
+ viewModel.Messages.Add(msg);
+ }
+
+ private void WaringOrCutOff(LiveRoomViewModel viewModel, object message)
+ {
+ var info = message as WarningOrCutOffMsgModel;
+ var msg = new DanmuMsgModel()
+ {
+ UserName = info.Command switch
+ {
+ "WARNING" => "⛔直播间警告",
+ "CUT_OFF" => "⛔直播间切断",
+ _ => null,
+ },
+ UserNameColor = "FFFF0000",
+ RichText = info.Message.ToRichTextBlock(null, color: "Red", fontWeight: "Medium"), // 字重调大, 防止与进场弹幕混淆
+ UserNameFontWeight = "SemiBold",
+ };
+
+ viewModel.Messages.Add(msg);
+ }
+
+ private async void StartLive(LiveRoomViewModel viewModel, object room_Id)
+ {
+ await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(3)); // 挂起三秒再获取, 否则很大可能一直卡加载而不缓冲
+ viewModel.GetPlayUrls(room_Id.ToInt32(), SettingService.GetValue(SettingConstants.Live.DEFAULT_QUALITY, 10000)).RunWithoutAwait();
+ viewModel.Messages.Add(new DanmuMsgModel()
+ {
+ UserName = $"{room_Id} 直播间开始直播",
+ });
+ }
}
}
diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveRoomAnchorLotteryInfoModel.cs b/src/BiliLite.UWP/Models/Common/Live/LiveRoomAnchorLotteryInfoModel.cs
index a6810a8de..8881fe2b0 100644
--- a/src/BiliLite.UWP/Models/Common/Live/LiveRoomAnchorLotteryInfoModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Live/LiveRoomAnchorLotteryInfoModel.cs
@@ -1,4 +1,6 @@
using Newtonsoft.Json;
+using System.Collections.ObjectModel;
+using Windows.UI.Xaml.Controls;
namespace BiliLite.Models.Common.Live
{
@@ -7,15 +9,35 @@ public class LiveRoomAnchorLotteryInfoModel
[JsonProperty("asset_icon")]
public string AssetIcon { get; set; }
+ ///
+ /// 奖品的图片(因为有可能只是b站礼物)
+ ///
[JsonProperty("award_image")]
public string AwardImage { get; set; }
+ ///
+ /// 奖品名称
+ ///
[JsonProperty("award_name")]
public string AwardName { get; set; }
+ ///
+ /// 奖品个数
+ ///
[JsonProperty("award_num")]
public int AwardNum { get; set; }
+ ///
+ /// 中奖的用户信息
+ ///
+ [JsonProperty("award_users")]
+ public ObservableCollection AwardUsers { get; set; }
+
+ public StackPanel WinnerList => AwardUsers == null ? new StackPanel() : new LiveRoomEndAnchorLotteryInfoModel().GenerateWinnerList(AwardUsers);
+
+ ///
+ /// 未知...
+ ///
[JsonProperty("cur_gift_num")]
public int CurGiftNum { get; set; }
@@ -24,21 +46,36 @@ public class LiveRoomAnchorLotteryInfoModel
public string Danmu { get; set; }
+ ///
+ /// 次级礼物信息? 因为有可能是b站礼物所以有id
+ ///
[JsonProperty("gift_id")]
public int GiftId { get; set; }
[JsonProperty("show_gift")]
public bool ShowGift => GiftId != 0;
+ ///
+ /// 次级礼物名称
+ ///
[JsonProperty("gift_name")]
public string GiftName { get; set; }
+ ///
+ /// 次级礼物数量
+ ///
[JsonProperty("gift_num")]
public int GiftNum { get; set; }
+ ///
+ /// 次级礼物价格
+ ///
[JsonProperty("gift_price")]
public int GiftPrice { get; set; }
+ ///
+ /// 待调查... 可能用于控制抽奖结束后按钮的关闭时间?
+ ///
[JsonProperty("goaway_time")]
public int GoawayTime { get; set; }
@@ -47,18 +84,30 @@ public class LiveRoomAnchorLotteryInfoModel
[JsonProperty("join_type")]
public int JoinType { get; set; }
+ ///
+ /// 抽奖的状态, 1为正在倒计时, 2为已开奖
+ ///
[JsonProperty("lot_status")]
public int LotStatus { get; set; }
[JsonProperty("max_time")]
public int MaxTime { get; set; }
+ ///
+ /// 参与抽奖的需求
+ ///
[JsonProperty("require_text")]
public string RequireText { get; set; }
+ ///
+ /// 参与抽奖的需求类型?
+ ///
[JsonProperty("require_type")]
public int RequireType { get; set; }
+ ///
+ /// 参与抽奖的需求等级? 可能和粉丝牌等级有关? 待调查
+ ///
[JsonProperty("require_value")]
public int RequireValue { get; set; }
@@ -73,6 +122,9 @@ public class LiveRoomAnchorLotteryInfoModel
public int Status { get; set; }
+ ///
+ /// 剩余时间
+ ///
public int Time { get; set; }
public string Url { get; set; }
diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveRoomEndAnchorLotteryInfoModel.cs b/src/BiliLite.UWP/Models/Common/Live/LiveRoomEndAnchorLotteryInfoModel.cs
index 4dfda51ea..dbb76ec31 100644
--- a/src/BiliLite.UWP/Models/Common/Live/LiveRoomEndAnchorLotteryInfoModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Live/LiveRoomEndAnchorLotteryInfoModel.cs
@@ -1,5 +1,12 @@
-using System.Collections.Generic;
+using System;
using Newtonsoft.Json;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Media.Imaging;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Shapes;
+using Windows.UI.Xaml;
+using System.Collections.ObjectModel;
+using System.Linq;
namespace BiliLite.Models.Common.Live
{
@@ -25,6 +32,52 @@ public class LiveRoomEndAnchorLotteryInfoModel
public string WebUrl { get; set; }
[JsonProperty("award_users")]
- public List AwardUsers { get; set; }
+ public ObservableCollection AwardUsers { get; set; }
+
+ public StackPanel WinnerList => AwardUsers == null ? new StackPanel() : GenerateWinnerList(AwardUsers);
+
+ public StackPanel GenerateWinnerList(ObservableCollection awardUsers)
+ {
+ var result = new StackPanel()
+ {
+ //
+ Orientation = Orientation.Vertical,
+ };
+ if (awardUsers == null || awardUsers.ToArray().Length <= 0) return result;
+ foreach (var awardUser in awardUsers)
+ {
+ var awardUserItemPanel = new StackPanel()
+ {
+ //
+ Orientation = Orientation.Horizontal,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ Margin = new Thickness(0, 4, 0, 4),
+ };
+ var userFaceImage = new Ellipse()
+ {
+ Width = 30,
+ Height = 30,
+ Fill = new ImageBrush()
+ {
+ //
+ ImageSource = new BitmapImage(new Uri(awardUser.Face + "@30h")),
+ Stretch = Stretch.UniformToFill,
+ }
+ };
+ var userNameText = new TextBlock()
+ {
+ //
+ Margin = new Thickness(4, 0, 4, 0),
+ TextWrapping = TextWrapping.Wrap,
+ Text = awardUser.Uname,
+ VerticalAlignment = VerticalAlignment.Center,
+ };
+
+ awardUserItemPanel.Children.Add(userFaceImage);
+ awardUserItemPanel.Children.Add(userNameText);
+ result.Children.Add(awardUserItemPanel);
+ }
+ return result;
+ }
}
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveRoomEndRedPocketLotteryInfoModel.cs b/src/BiliLite.UWP/Models/Common/Live/LiveRoomEndRedPocketLotteryInfoModel.cs
new file mode 100644
index 000000000..c047567d5
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/Live/LiveRoomEndRedPocketLotteryInfoModel.cs
@@ -0,0 +1,117 @@
+using BiliLite.Extensions;
+using BiliLite.Models.Exceptions;
+using BiliLite.Services;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Documents;
+using Windows.UI.Xaml.Markup;
+
+namespace BiliLite.Models.Common.Live
+{
+ public class LiveRoomEndRedPocketLotteryInfoModel
+ {
+ ///
+ /// 抽奖的id号
+ ///
+ [JsonProperty("lot_id")]
+ public string LotId { get; set; }
+
+ ///
+ /// 总中奖人数
+ ///
+ [JsonProperty("total_num")]
+ public int TotalNumber { get; set; }
+
+ ///
+ /// 中奖者详细信息
+ ///
+ [JsonProperty("winner_info")]
+ public ObservableCollection> Winners { get; set; }
+
+ public RichTextBlock WinnersList => WinnerToRichTextBlock();
+
+ ///
+ /// 中奖的礼物信息
+ ///
+ [JsonProperty("awards")]
+ public IDictionary Awards { get; set; }
+
+ ///
+ /// 版本号? 待调查, 可能用于区别不同版本的Json反馈
+ ///
+ [JsonProperty("version")]
+ public int Version { get; set; }
+
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+
+ private RichTextBlock WinnerToRichTextBlock()
+ {
+ try
+ {
+ //var result = (RichTextBlock)XamlReader.Load("");
+ var result = new RichTextBlock() { LineHeight = 28 };
+ if (Winners == null) throw new CustomizedErrorException("红包中奖名单为空");
+ foreach (var winner in Winners)
+ {
+ var name = winner[1];
+ var giftId = winner[3];
+ var p = $@"
+ {winner[1]} 获得
+
+
+
+ {Awards[giftId].AwardName}
+ ";
+
+ var paragraph = (Paragraph)XamlReader.Load(p);
+ result.Blocks.Add(paragraph);
+ }
+ return result;
+ }
+ catch (Exception ex)
+ {
+ Notify.ShowMessageToast("红包中奖名单富文本转换失败");
+ _logger.Error("红包中奖名单富文本转换失败", ex);
+ var text = new RichTextBlock();
+ var paragraph = new Paragraph();
+ var run = new Run();
+ paragraph.Inlines.Add(run);
+ text.Blocks.Add(paragraph);
+ return text;
+ }
+ }
+ }
+
+ public class LiveRoomEndRedPocketLotteryInfoAwardModel
+ {
+ ///
+ /// 奖品类型? 待调查
+ ///
+ [JsonProperty("award_type")]
+ public int AwardType { get; set; }
+
+ ///
+ /// 奖品名字
+ ///
+ [JsonProperty("award_name")]
+ public string AwardName { get; set; }
+
+ ///
+ /// 奖品图片
+ ///
+ [JsonProperty("award_pic")]
+ public string AwardPic { get; set; }
+
+ ///
+ /// 奖品价格(以金瓜子计算)
+ ///
+ [JsonProperty("award_price")]
+ public int AwardPrice { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveRoomRankItemModel.cs b/src/BiliLite.UWP/Models/Common/Live/LiveRoomRankItemModel.cs
index b502c4715..f18269a19 100644
--- a/src/BiliLite.UWP/Models/Common/Live/LiveRoomRankItemModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Live/LiveRoomRankItemModel.cs
@@ -4,11 +4,24 @@ namespace BiliLite.Models.Common.Live
{
public class LiveRoomRankItemModel
{
+ private string m_name;
+
public int Rank { get; set; }
public long Uid { get; set; }
- public string Uname { get; set; }
+ public string Uname
+ {
+ get => m_name;
+ set => m_name = value;
+ }
+
+ [JsonProperty("name")]
+ public string Name
+ {
+ get => m_name;
+ set => m_name = value;
+ }
public string Face { get; set; }
diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveRoomRedPocketLotteryInfoModel.cs b/src/BiliLite.UWP/Models/Common/Live/LiveRoomRedPocketLotteryInfoModel.cs
new file mode 100644
index 000000000..212aa31ee
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/Live/LiveRoomRedPocketLotteryInfoModel.cs
@@ -0,0 +1,193 @@
+using BiliLite.Extensions;
+using BiliLite.Models.Exceptions;
+using BiliLite.Services;
+using Newtonsoft.Json;
+using System;
+using System.Collections.ObjectModel;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Documents;
+using Windows.UI.Xaml.Markup;
+
+namespace BiliLite.Models.Common.Live
+{
+ public class LiveRoomRedPocketLotteryInfoModel
+ {
+ ///
+ /// 红包id
+ ///
+ [JsonProperty("lot_id")]
+ public string LotteryId { get; set; }
+
+ ///
+ /// 发送者名称
+ ///
+ [JsonProperty("sender_name")]
+ public string SenderName { get; set; }
+
+ ///
+ /// 发送者UID
+ ///
+ [JsonProperty("sender_uid")]
+ public string SenderUid { get; set; }
+
+ ///
+ /// 发送者头像
+ ///
+ [JsonProperty("sender_face")]
+ public string SenderFace { get; set; }
+
+ ///
+ /// 抽取条件? 未知
+ ///
+ [JsonProperty("join_requirement")]
+ public int JoinRequirement { get; set; }
+
+ ///
+ /// 抽取红包所发送的弹幕
+ ///
+ [JsonProperty("danmu")]
+ public string Danmu { get; set; }
+
+ ///
+ /// 礼物列表
+ ///
+ [JsonProperty("awards")]
+ public ObservableCollection Awards { get; set; }
+
+ public RichTextBlock AwardsList => AwardsToRichTextBlock();
+
+ ///
+ /// 红包开始时间
+ ///
+ [JsonProperty("start_time")]
+ public int StartTime { get; set; }
+
+ ///
+ /// 红包结束时间
+ ///
+ [JsonProperty("end_time")]
+ public int EndTime { get; set; }
+
+ ///
+ /// 红包持续时间(即EndTime - StartTime)
+ ///
+ [JsonProperty("last_time")]
+ public int LastTime { get; set; }
+
+ ///
+ /// 红包按钮移除时间
+ ///
+ [JsonProperty("remove_time")]
+ public int RemoveTime { get; set; }
+
+ ///
+ /// ?待研究
+ ///
+ [JsonProperty("replace_time")]
+ public int ReplaceTime { get; set; }
+
+ ///
+ /// 目前时间
+ ///
+ [JsonProperty("current_time")]
+ public int CurrentTime { get; set; }
+
+ ///
+ /// 抽奖状态 1为正在倒计时 2为已经开奖
+ ///
+ [JsonProperty("lot_status")]
+ public int LotteryStatus { get; set; }
+
+ ///
+ /// 用户状态(可能是是否可以参与)? 待研究
+ ///
+ [JsonProperty("user_status")]
+ public int UserStatus { get; set; }
+
+ ///
+ /// 红包总共金额
+ ///
+ [JsonProperty("total_price")]
+ public int TotalPrice { get; set; }
+
+ ///
+ /// 可能是用于多个红包排队? 待研究
+ ///
+ [JsonProperty("wait_num")]
+ public int WaitNumber { get; set; }
+
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+
+ private RichTextBlock AwardsToRichTextBlock()
+ {
+ try
+ {
+ //var result = (RichTextBlock)XamlReader.Load("");
+ var result = new RichTextBlock() { LineHeight = 28 };
+ if (Awards != null)
+ {
+ foreach (var item in Awards)
+ {
+ var p = string.Format(
+ @"
+
+
+
+
+ ",
+ item.GiftPicture, 24, item.GiftName, item.GiftNumber);
+
+ var paragraph = (Paragraph)XamlReader.Load(p);
+ result.Blocks.Add(paragraph);
+ }
+ return result;
+ }
+ else
+ {
+ throw new CustomizedErrorException("红包奖品为空");
+ }
+ }
+ catch (Exception ex)
+ {
+ Notify.ShowMessageToast("红包奖品富文本转换失败");
+ _logger.Error("红包奖品富文本转换失败", ex);
+ var tx = new RichTextBlock();
+ Paragraph paragraph = new Paragraph();
+ Run run = new Run();
+ paragraph.Inlines.Add(run);
+ tx.Blocks.Add(paragraph);
+ return tx;
+ }
+ }
+ }
+
+ public class LiveRoomRedPocketLotteryAwardInfoModel
+ {
+ ///
+ /// 礼物ID
+ ///
+ [JsonProperty("gift_id")]
+ public string GiftId { get; set; }
+
+ ///
+ /// 礼物名字
+ ///
+ [JsonProperty("gift_name")]
+ public string GiftName { get; set; }
+
+ ///
+ /// 礼物图片
+ ///
+ [JsonProperty("gift_pic")]
+ public string GiftPicture { get; set; }
+
+ ///
+ /// 礼物数量
+ ///
+ [JsonProperty("num")]
+ public int GiftNumber { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/Live/RoomBlockMsgModel.cs b/src/BiliLite.UWP/Models/Common/Live/RoomBlockMsgModel.cs
new file mode 100644
index 000000000..5fd5e4ee5
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/Live/RoomBlockMsgModel.cs
@@ -0,0 +1,9 @@
+namespace BiliLite.Models.Common.Live
+{
+ public class RoomBlockMsgModel
+ {
+ public string UserID { get; set; }
+
+ public string UserName { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/Live/WarningOrCutOffMsgModel.cs b/src/BiliLite.UWP/Models/Common/Live/WarningOrCutOffMsgModel.cs
new file mode 100644
index 000000000..2907881d1
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/Live/WarningOrCutOffMsgModel.cs
@@ -0,0 +1,9 @@
+namespace BiliLite.Models.Common.Live
+{
+ public class WarningOrCutOffMsgModel
+ {
+ public string Message { get; set; }
+
+ public string Command { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/Live/WelcomeMsgModel.cs b/src/BiliLite.UWP/Models/Common/Live/WelcomeMsgModel.cs
deleted file mode 100644
index 11c61ba2a..000000000
--- a/src/BiliLite.UWP/Models/Common/Live/WelcomeMsgModel.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace BiliLite.Models.Common.Live
-{
- public class WelcomeMsgModel
- {
- public string UserName { get; set; }
-
- public string IsAdmin { get; set; }
-
- public string UserID { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs b/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs
index f0c69531d..29a287c13 100644
--- a/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs
+++ b/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs
@@ -137,16 +137,17 @@ public ApiModel GetFreeSilver()
/// 赠送背包礼物
///
///
- public ApiModel SendBagGift(long ruid, int gift_id, int num, int bag_id, int roomId)
+ public ApiModel SendBagGift(long ruid, int giftId, int num, int bagId, int roomId)
{
var api = new ApiModel()
{
method = RestSharp.Method.Post,
- baseUrl = $"https://api.live.bilibili.com/gift/v2/live/bag_send",
- parameter = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey",
- body = $"uid={SettingService.Account.UserID}&ruid={ruid}&send_ruid=0&gift_id={gift_id}&gift_num={num}&bag_id={bag_id}&biz_id={roomId}&rnd={new Random().Next(1000, 999999).ToString("000000")}&biz_code=live&data_behavior_id=&data_source_id="
+ baseUrl = $"https://api.live.bilibili.com/xlive/revenue/v1/gift/sendBag",
+ body = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey",
+ need_cookie = true,
};
- api.parameter += ApiHelper.GetSign(api.parameter, AppKey);
+ 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;
}
@@ -154,16 +155,18 @@ public ApiModel SendBagGift(long ruid, int gift_id, int num, int bag_id, int roo
/// 赠送礼物
///
///
- public ApiModel SendGift(long ruid, int gift_id, int num, int roomId, string coin_type, int price)
+ public ApiModel SendGift(long ruid, int giftId, string coinType, int num, int roomId, int price)
{
var api = new ApiModel()
{
method = RestSharp.Method.Post,
- baseUrl = $"https://api.live.bilibili.com/gift/v2/live/send",
+ baseUrl = $"https://api.live.bilibili.com/xlive/revenue/v1/gift/send{char.ToUpper(coinType[0]) + coinType.Substring(1)}",
body = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey",
+ need_cookie = true,
};
- api.body += $"&biz_code=live&biz_id={roomId}&coin_type={coin_type}&gift_id={gift_id}&gift_num={num}&mobi_app=android&platform=android&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;
}
@@ -245,16 +248,16 @@ public ApiModel FansList(long ruid, int roomId, int page)
///
/// 主播ID
/// 房间号
- ///
- /// gold-rank=金瓜子排行,today-rank=今日礼物排行,seven-rank=7日礼物排行
+ /// 目前仅发现为online_rank
+ /// 目前仅发现为contribution_rank
///
- public ApiModel RoomRankList(long ruid, int roomId, string rank_type, int next_offset = 0)
+ public ApiModel RoomRankList(long ruid, int roomId, string rank_type, string switch_type)
{
var api = new ApiModel()
{
method = RestSharp.Method.Get,
- baseUrl = $"https://api.live.bilibili.com/rankdb/v1/RoomRank/tabRanks",
- parameter = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey&next_offset={next_offset}&room_id={roomId}&ruid={ruid}&rank_type={rank_type}",
+ baseUrl = $"https://api.live.bilibili.com/xlive/general-interface/v1/rank/queryContributionRank",
+ parameter = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey&room_id={roomId}&ruid={ruid}&type={rank_type}&switch={switch_type}",
};
api.parameter += ApiHelper.GetSign(api.parameter, AppKey);
return api;
@@ -272,13 +275,14 @@ public ApiModel RoomLotteryInfo(int roomId)
method = RestSharp.Method.Get,
baseUrl = $"https://api.live.bilibili.com/xlive/lottery-interface/v1/lottery/getLotteryInfo",
parameter = ApiHelper.MustParameter(AppKey, true) + $"&actionKey=appkey&roomid={roomId}",
+ need_cookie = true,
};
api.parameter += ApiHelper.GetSign(api.parameter, AppKey);
return api;
}
///
- /// 直播间抽奖信息
+ /// 直播间超级留言(SuperChat)信息
///
///
///
@@ -310,7 +314,7 @@ public ApiModel RoomEntryAction(int roomId)
return api;
}
- public ApiModel GetDanmukuInfo(int roomId)
+ public ApiModel GetDanmuInfo(int roomId)
{
var api = new ApiModel()
{
diff --git a/src/BiliLite.UWP/Modules/Live/LiveMessage.cs b/src/BiliLite.UWP/Modules/Live/LiveMessage.cs
index dd6c01d8e..afe98119d 100644
--- a/src/BiliLite.UWP/Modules/Live/LiveMessage.cs
+++ b/src/BiliLite.UWP/Modules/Live/LiveMessage.cs
@@ -67,7 +67,7 @@ public async Task Connect(int roomID, int uid, string token, string buvid, strin
var receivedData = new byte[ms.Length];
ms.Read(receivedData, 0, receivedData.Length);
- ParseData(receivedData);
+ await ParseData(receivedData);
}
catch (Exception ex)
{
@@ -121,7 +121,7 @@ private async Task SendHeartBeatAsync()
/// 解析内容
///
///
- private void ParseData(byte[] data)
+ private async Task ParseData(byte[] data)
{
//协议版本。
//0为JSON,可以直接解析;
@@ -147,9 +147,13 @@ private void ParseData(byte[] data)
var text = Encoding.UTF8.GetString(body);
//可能有多条数据,做个分割
var textLines = Regex.Split(text, "[\x00-\x1f]+").Where(x => x.Length > 2 && x[0] == '{').ToArray();
+
+ var delay = textLines.Length > 30 ? 0.1 : 0.05; // 大概3秒来一波
+ delay = textLines.Length > 60 ? 0.2 : delay;
foreach (var item in textLines)
{
ParseMessage(item);
+ await Task.Delay(TimeSpan.FromSeconds(delay));
}
}
}
@@ -160,7 +164,7 @@ private void ParseMessage(string jsonMessage)
{
var obj = JObject.Parse(jsonMessage);
var cmd = obj["cmd"].ToString();
- if (cmd.Contains("DANMU_MSG"))
+ if (cmd == ("DANMU_MSG"))
{
var msg = new DanmuMsgModel();
if (obj["info"] != null && obj["info"].ToArray().Length != 0)
@@ -171,7 +175,7 @@ private void ParseMessage(string jsonMessage)
var extra = JObject.Parse(obj["info"][0][15]["extra"].ToString());
if (extra["emots"].ToArray().Length != 0)
{
- msg.Emoji = (JContainer)extra["emots"];
+ msg.Emoji = (JObject)extra["emots"];
}
}
@@ -183,17 +187,19 @@ private void ParseMessage(string jsonMessage)
msg.BigSticker = new DanmuMsgModel.BigStickerInfo
{
Url = (string)obj["info"][0][13]["url"],
- Height = (int)obj["info"][0][13]["height"],
- Width = (int)obj["info"][0][13]["width"],
+ Height = (int)obj["info"][0][13]["height"],
+ Width = (int)obj["info"][0][13]["width"],
};
//有的表情特别大 :(
- msg.BigSticker.Height = (msg.BigSticker.Height * 60 / msg.BigSticker.Width).ToInt32();
+ msg.BigSticker.Height = (msg.BigSticker.Height * 60 / msg.BigSticker.Width).ToInt32();
msg.BigSticker.Width = 60;
}
// 弹幕内容
msg.Text = obj["info"][1].ToString();
- msg.RichText = StringExtensions.ToRichTextBlock(msg.Text, (JObject)msg.Emoji, true);
+ // 字重调大, 防止与进场弹幕混淆
+ msg.UserNameFontWeight = "SemiBold";
+ msg.RichText = msg.Text.ToRichTextBlock(msg.Emoji, true, fontWeight: "Medium");
// 弹幕颜色
var color = obj["info"][0][3].ToInt32();
@@ -216,18 +222,19 @@ private void ParseMessage(string jsonMessage)
// 是否为舰长
if (obj["info"][3][10] != null && Convert.ToInt32(obj["info"][3][10].ToString()) != 0)
{
- switch (Convert.ToInt32(obj["info"][3][10].ToString())){
+ switch (Convert.ToInt32(obj["info"][3][10].ToString()))
+ {
case 3:
msg.UserCaptain = "舰长";
- msg.UserCaptainImage = "/Assets/Live/ic_live_guard_3.png";
+ msg.UserNameColor = "#FF23709E";
break;
case 2:
msg.UserCaptain = "提督";
- msg.UserCaptainImage = "/Assets/Live/ic_live_guard_2.png";
+ msg.UserNameColor = "#FF7B166F";
break;
case 1:
msg.UserCaptain = "总督";
- msg.UserCaptainImage = "/Assets/Live/ic_live_guard_1.png";
+ msg.UserNameColor = "#FFC01039";
break;
}
msg.ShowCaptain = Visibility.Visible;
@@ -241,7 +248,6 @@ private void ParseMessage(string jsonMessage)
msg.MedalColor = obj["info"][3][4].ToString();
msg.ShowMedal = Visibility.Visible;
}
-
// 用户直播等级(已经被b站弃用)
//if (obj["info"][4] != null && obj["info"][4].ToArray().Length != 0)
//{
@@ -260,7 +266,7 @@ private void ParseMessage(string jsonMessage)
return;
}
}
- if (cmd == "SEND_GIFT")
+ else if (cmd == "SEND_GIFT" || cmd == "POPULARITY_RED_POCKET_NEW")
{
var msg = new GiftMsgModel();
if (obj["data"] != null)
@@ -275,7 +281,7 @@ private void ParseMessage(string jsonMessage)
}
return;
}
- if (cmd == "COMBO_SEND")
+ else if (cmd == "COMBO_SEND")
{
var msg = new GiftMsgModel();
if (obj["data"] != null)
@@ -290,63 +296,86 @@ private void ParseMessage(string jsonMessage)
}
return;
}
- if (cmd == "WELCOME")
+ else if (cmd == "INTERACT_WORD")
{
- var w = new WelcomeMsgModel();
+ var w = new InteractWordModel();
if (obj["data"] != null)
{
w.UserName = obj["data"]["uname"].ToString();
w.UserID = obj["data"]["uid"].ToString();
+ w.MsgType = obj["data"]["msg_type"].ToInt32();
- NewMessage?.Invoke(MessageType.Welcome, w);
- }
+ if (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"].ToString();
+ w.MedalColor = obj["data"]["fans_medal"]["medal_color"].ToString();
+ w.ShowMedal = Visibility.Visible;
+ }
+ NewMessage?.Invoke(MessageType.InteractWord, w);
+ }
return;
}
- if (cmd == "SYS_MSG")
+ // 没写相关实现, 先注释掉
+ //if (cmd == "SYS_MSG")
+ //{
+ // NewMessage?.Invoke(MessageType.SystemMsg, obj["msg"].ToString());
+ // return;
+ //}
+ else if (cmd == "ANCHOR_LOT_START")
{
- NewMessage?.Invoke(MessageType.SystemMsg, obj["msg"].ToString());
+ if (obj["data"] != null)
+ {
+ NewMessage?.Invoke(MessageType.AnchorLotteryStart, obj["data"].ToString());
+ }
return;
}
- if (cmd == "ANCHOR_LOT_START")
+ else if (cmd == "ANCHOR_LOT_AWARD")
{
if (obj["data"] != null)
{
- NewMessage?.Invoke(MessageType.AnchorLotteryStart, obj["data"].ToString());
+ NewMessage?.Invoke(MessageType.AnchorLotteryAward, obj["data"].ToString());
}
return;
}
- if (cmd == "ANCHOR_LOT_AWARD")
+ else if (cmd == "POPULARITY_RED_POCKET_START")
{
if (obj["data"] != null)
{
- NewMessage?.Invoke(MessageType.AnchorLotteryAward, obj["data"].ToString());
+ NewMessage?.Invoke(MessageType.RedPocketLotteryStart, obj["data"].ToString());
}
return;
}
- if (cmd == "SUPER_CHAT_MESSAGE")
+ else if (cmd == "POPULARITY_RED_POCKET_WINNER_LIST")
{
- SuperChatMsgViewModel msgView = new SuperChatMsgViewModel();
if (obj["data"] != null)
{
- msgView.BackgroundBottomColor = obj["data"]["background_bottom_color"].ToString();
- msgView.BackgroundColor = obj["data"]["background_color"].ToString();
- msgView.BackgroundImage = obj["data"]["background_image"].ToString();
- msgView.EndTime = obj["data"]["end_time"].ToInt32();
- msgView.StartTime = obj["data"]["start_time"].ToInt32();
- msgView.Time = obj["data"]["time"].ToInt32();
- msgView.MaxTime = msgView.EndTime - msgView.StartTime;
- msgView.Face = obj["data"]["user_info"]["face"].ToString();
- msgView.FaceFrame = obj["data"]["user_info"]["face_frame"].ToString();
- msgView.FontColor = obj["data"]["message_font_color"].ToString();
- msgView.Message = obj["data"]["message"].ToString();
- msgView.Price = obj["data"]["price"].ToInt32();
- msgView.Username = obj["data"]["user_info"]["uname"].ToString();
- NewMessage?.Invoke(MessageType.SuperChat, msgView);
+ NewMessage?.Invoke(MessageType.RedPocketLotteryWinner, obj["data"].ToString());
}
return;
}
- if (cmd == "ROOM_CHANGE")
+ else if (cmd == "SUPER_CHAT_MESSAGE")
+ {
+ var msgView = new SuperChatMsgViewModel();
+ if (obj["data"] == null) return;
+ msgView.BackgroundBottomColor = obj["data"]["background_bottom_color"].ToString();
+ msgView.BackgroundColor = obj["data"]["background_color"].ToString();
+ msgView.BackgroundImage = obj["data"]["background_image"].ToString();
+ msgView.EndTime = obj["data"]["end_time"].ToInt32();
+ msgView.StartTime = obj["data"]["start_time"].ToInt32();
+ msgView.Time = obj["data"]["time"].ToInt32();
+ msgView.MaxTime = msgView.EndTime - msgView.StartTime;
+ msgView.Face = obj["data"]["user_info"]["face"].ToString();
+ msgView.FaceFrame = obj["data"]["user_info"]["face_frame"].ToString();
+ msgView.FontColor = obj["data"]["message_font_color"].ToString();
+ msgView.Message = obj["data"]["message"].ToString();
+ msgView.Price = obj["data"]["price"].ToInt32();
+ msgView.Username = obj["data"]["user_info"]["uname"].ToString();
+ NewMessage?.Invoke(MessageType.SuperChat, msgView);
+ return;
+ }
+ else if (cmd == "ROOM_CHANGE")
{
if (obj["data"] != null)
{
@@ -361,7 +390,7 @@ private void ParseMessage(string jsonMessage)
}
return;
}
- if (cmd == "GUARD_BUY")
+ else if (cmd == "GUARD_BUY")
{
if (obj["data"] != null)
{
@@ -378,6 +407,42 @@ private void ParseMessage(string jsonMessage)
}
return;
}
+ else if (cmd == "ROOM_BLOCK_MSG")
+ {
+ if (obj["data"] != null)
+ {
+ NewMessage?.Invoke(MessageType.RoomBlock, new RoomBlockMsgModel()
+ {
+ UserID = obj["data"]["uid"].ToString(),
+ UserName = obj["data"]["uname"].ToString(),
+ });
+ }
+ }
+ else if (cmd == "WARNING" || cmd == "CUT_OFF")
+ {
+ if (obj["msg"] != null)
+ {
+ NewMessage?.Invoke(MessageType.WaringOrCutOff, new WarningOrCutOffMsgModel()
+ {
+ Message = obj["msg"].ToString(),
+ Command = cmd,
+ });
+ }
+ }
+ else if (cmd == "LIVE" || cmd == "REENTER_LIVE_ROOM")
+ {
+ if (obj["roomid"] != null)
+ {
+ NewMessage?.Invoke(MessageType.StartLive, obj["roomid"].ToString());
+ }
+ }
+ else if (cmd == "WATCHED_CHANGE")
+ {
+ if (obj["data"] != null)
+ {
+ NewMessage?.Invoke(MessageType.WatchedChange, obj["data"]["text_large"].ToString());
+ }
+ }
}
catch (Exception ex)
{
@@ -386,7 +451,6 @@ private void ParseMessage(string jsonMessage)
logger.Error("直播解析JSON包出错", ex);
}
}
-
}
///
diff --git a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml
index d27eb71cf..c0edd2ab5 100644
--- a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml
+++ b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml
@@ -316,7 +316,7 @@
-->
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -859,7 +1014,7 @@
- 人气: 粉丝:
+ 粉丝:
关注
已关注
@@ -1041,7 +1196,14 @@
-
+
+
@@ -1065,7 +1227,7 @@
-
+
@@ -1108,8 +1270,13 @@
-
-
+
+
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs
index 80f585555..4b6e26dcf 100644
--- a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs
@@ -35,6 +35,7 @@
using BiliLite.Player.States.PlayStates;
using BiliLite.Player.States.ScreenStates;
using BiliLite.ViewModels.Live;
+using Windows.UI.Xaml.Documents;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -94,7 +95,10 @@ public LiveDetailPage()
m_liveRoomViewModel = new LiveRoomViewModel();
m_liveRoomViewModel.ChangedPlayUrl += LiveRoomViewModelChangedPlayUrl;
m_liveRoomViewModel.AddNewDanmu += LiveRoomViewModelAddNewDanmu;
- m_liveRoomViewModel.LotteryEnd += LiveRoomViewModelLotteryEnd;
+ m_liveRoomViewModel.AnchorLotteryEnd += LiveRoomViewModelAnchorLotteryEnd;
+ m_liveRoomViewModel.RedPocketLotteryEnd += LiveRoomViewModelRedPocketLotteryEnd;
+ m_liveRoomViewModel.ChatScrollToEnd += LiveRoomViewModelChatScrollToEnd;
+ m_liveRoomViewModel.LotteryViewModel.AnchorLotteryStart += LiveRoomViewModelAnchorLotteryStart;
this.Loaded += LiveDetailPage_Loaded;
this.Unloaded += LiveDetailPage_Unloaded;
}
@@ -125,12 +129,46 @@ private void Timer_focus_Tick(object sender, object e)
}
}
- private void LiveRoomViewModelLotteryEnd(object sender, LiveRoomEndAnchorLotteryInfoModel e)
+ private void LiveRoomViewModelAnchorLotteryStart(object sender, LiveRoomAnchorLotteryInfoModel e)
+ {
+ AnchorLotteryWinnerList.Content = e.WinnerList;
+ if (e.WinnerList.Children.Count != 0)
+ {
+ m_liveRoomViewModel.ShowAnchorLotteryWinnerList = true;
+ }
+ }
+
+ private void LiveRoomViewModelAnchorLotteryEnd(object sender, LiveRoomEndAnchorLotteryInfoModel e)
{
var str = e.AwardUsers.Aggregate("", (current, item) => current + (item.Uname + "、"));
str = str.TrimEnd('、');
+ var msg = $"天选时刻 开奖信息:\r\n奖品: {e.AwardName} \r\n中奖用户:{str}";
+ foreach(var awardUser in e.AwardUsers)
+ {
+ if (awardUser.Uid == SettingService.Account.UserID)
+ {
+ msg += $"\r\n你已抽中奖品: {e.AwardName}, 恭喜欧皇~";
+ }
+ }
+ Notify.ShowMessageToast(msg, new List(), 10);
+ AnchorLotteryWinnerList.Content = e.WinnerList;
+ m_liveRoomViewModel.ShowAnchorLotteryWinnerList = true;
+ m_liveRoomViewModel.LoadBag().RunWithoutAwait();
+ }
- Notify.ShowMessageToast($"开奖信息:\r\n奖品:{e.AwardName}\r\n中奖用户:{str}", new List() { }, 10);
+ private void LiveRoomViewModelRedPocketLotteryEnd(object sender, LiveRoomEndRedPocketLotteryInfoModel e)
+ {
+ var winners = e.Winners;
+ var awards = e.Awards;
+ redPocketWinnerList.Content = e.WinnersList;
+ m_liveRoomViewModel.ShowRedPocketLotteryWinnerList = true;
+ foreach (var winner in winners)
+ {
+ if (winner[0] == (SettingService.Account.UserID).ToString()) {
+ Notify.ShowMessageToast($"你已在人气红包抽中 {awards[winner[3]].AwardName} , 赶快查看吧~");
+ }
+ }
+ m_liveRoomViewModel.LoadBag().RunWithoutAwait();
}
private void LiveRoomViewModelAddNewDanmu(object sender, DanmuMsgModel e)
@@ -151,6 +189,11 @@ private void LiveRoomViewModelAddNewDanmu(object sender, DanmuMsgModel e)
}
}
+ private void LiveRoomViewModelChatScrollToEnd(object sender, EventArgs e)
+ {
+ list_chat.ScrollIntoView(list_chat.Items[list_chat.Items.Count - 1]);
+ }
+
#region 页面生命周期
private void LiveDetailPage_Unloaded(object sender, RoutedEventArgs e)
@@ -465,8 +508,8 @@ private void PreLoadSetting()
};
// 播放器优先模式
m_viewModel.LivePlayerMode = (LivePlayerMode)SettingService.GetValue(
- SettingConstants.Player.DEFAULT_LIVE_PLAYER_MODE,
- (int)DefaultPlayerModeOptions.DEFAULT_LIVE_PLAYER_MODE);
+ SettingConstants.Player.DEFAULT_LIVE_PLAYER_MODE,
+ (int)DefaultPlayerModeOptions.DEFAULT_LIVE_PLAYER_MODE);
m_playerConfig.PlayMode = m_viewModel.LivePlayerMode;
}
@@ -707,10 +750,20 @@ private async void BottomBtnRefresh_Click(object sender, RoutedEventArgs e)
await m_liveRoomViewModel.LoadLiveRoomDetail(roomid);
}
- private void btnSendGift_Click(object sender, RoutedEventArgs e)
+ private async void btnSendGift_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is Button { DataContext: LiveGiftItem giftInfo })
+ {
+ await m_liveRoomViewModel.SendGift(giftInfo);
+ }
+ }
+
+ private async void btnSendBagGift_Click(object sender, RoutedEventArgs e)
{
- var giftInfo = (sender as Button).DataContext as LiveGiftItem;
- m_liveRoomViewModel.SendGift(giftInfo).RunWithoutAwait();
+ if (sender is Button { DataContext: LiveGiftItem giftInfo })
+ {
+ await m_liveRoomViewModel.SendBagGift(giftInfo);
+ }
}
private async void TopBtnScreenshot_Click(object sender, RoutedEventArgs e)
@@ -871,16 +924,39 @@ private void ListView_ItemClick(object sender, ItemClickEventArgs e)
private async void BtnSendLotteryDanmu_Click(object sender, RoutedEventArgs e)
{
- if (m_liveRoomViewModel.AnchorLotteryViewModel != null && m_liveRoomViewModel.AnchorLotteryViewModel.LotteryInfo != null && !string.IsNullOrEmpty(m_liveRoomViewModel.AnchorLotteryViewModel.LotteryInfo.Danmu))
+ if (m_liveRoomViewModel.LotteryViewModel != null &&
+ m_liveRoomViewModel.LotteryViewModel.AnchorLotteryInfo != null &&
+ !string.IsNullOrEmpty(m_liveRoomViewModel.LotteryViewModel.AnchorLotteryInfo.Danmu))
{
- var result = await m_liveRoomViewModel.SendDanmu(m_liveRoomViewModel.AnchorLotteryViewModel.LotteryInfo.Danmu);
+ var result = await m_liveRoomViewModel.SendDanmu(m_liveRoomViewModel.LotteryViewModel.AnchorLotteryInfo.Danmu);
if (result)
{
Notify.ShowMessageToast("弹幕发送成功");
FlyoutLottery.Hide();
}
+ }
+ }
+ private async void BtnSendRedPocketLotteryDanmu_Click(object sender, RoutedEventArgs e)
+ {
+ if (m_liveRoomViewModel.LotteryViewModel == null ||
+ m_liveRoomViewModel.LotteryViewModel.RedPocketLotteryInfo == null ||
+ string.IsNullOrEmpty(m_liveRoomViewModel.LotteryViewModel.RedPocketLotteryInfo.Danmu)) return;
+ var msg = "";
+ var result = await m_liveRoomViewModel.SendDanmu(m_liveRoomViewModel.LotteryViewModel.RedPocketLotteryInfo.Danmu);
+ if (result)
+ {
+ FlyoutRedPocketLottery.Hide();
+ msg += "弹幕发送成功";
}
+
+ if (!m_liveRoomViewModel.Attention)
+ {
+ BtnAttention_Click(sender, e);
+ msg += ", 关注主播成功";
+ }
+
+ Notify.ShowMessageToast(msg, 4);
}
private void BottomBtnMiniWindows_Click(object sender, RoutedEventArgs e)
@@ -1092,12 +1168,6 @@ private void Grid_ManipulationCompleted(object sender, ManipulationCompletedRout
}
#endregion
- private async void btnSendBagGift_Click(object sender, RoutedEventArgs e)
- {
- var giftInfo = (sender as Button).DataContext as LiveGiftItem;
- await Task.Run(() => m_liveRoomViewModel.SendBagGift(giftInfo)).ConfigureAwait(false);
- }
-
private void DataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
DataRequest request = args.Request;
diff --git a/src/BiliLite.UWP/ViewModels/Live/LiveRoomAnchorLotteryViewModel.cs b/src/BiliLite.UWP/ViewModels/Live/LiveRoomAnchorLotteryViewModel.cs
deleted file mode 100644
index 183e5c4e1..000000000
--- a/src/BiliLite.UWP/ViewModels/Live/LiveRoomAnchorLotteryViewModel.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using System.Timers;
-using BiliLite.Extensions;
-using BiliLite.Models.Common;
-using BiliLite.Models.Common.Live;
-using BiliLite.Models.Exceptions;
-using BiliLite.Models.Requests.Api.Live;
-using BiliLite.Services;
-using BiliLite.ViewModels.Common;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using PropertyChanged;
-
-namespace BiliLite.ViewModels.Live
-{
- public class LiveRoomAnchorLotteryViewModel : BaseViewModel
- {
- #region Fields
-
- private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
- private readonly LiveRoomAPI m_liveRoomApi;
-
- #endregion
-
- #region Constructors
-
- public LiveRoomAnchorLotteryViewModel()
- {
- m_liveRoomApi = new LiveRoomAPI();
- Timer = new Timer(1000);
- Timer.Elapsed += Timer_Elapsed;
- }
-
- #endregion
-
- #region Properties
-
- [DoNotNotify]
- public Timer Timer { get; set; }
-
- public LiveRoomAnchorLotteryInfoModel LotteryInfo { get; set; }
-
- public string DownTime { get; set; } = "--:--";
-
- public bool End { get; set; }
-
- public bool Show { get; set; }
-
- #endregion
-
- #region Private Methods
-
- private async void Timer_Elapsed(object sender, ElapsedEventArgs e)
- {
- await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
- {
- if (LotteryInfo == null) return;
- if (LotteryInfo.Time <= 0)
- {
- End = false;
- Timer.Stop();
- DownTime = "已开奖";
- Show = false;
- LotteryInfo = null;
- return;
- }
- var time = TimeSpan.FromSeconds(LotteryInfo.Time);
- DownTime = time.ToString(@"mm\:ss");
- LotteryInfo.Time--;
- });
- }
-
- #endregion
-
- #region Public Methods
-
- public async Task LoadLotteryInfo(int roomId)
- {
- try
- {
- var result = await m_liveRoomApi.RoomLotteryInfo(roomId).Request();
- if (!result.status)
- {
- throw new CustomizedErrorException(result.message);
- }
-
- var obj = await result.GetData();
- if (!obj.success)
- {
- throw new CustomizedErrorException(obj.message);
- }
-
- var data = JsonConvert.DeserializeObject(obj.data["anchor"]
- .ToString());
-
- LotteryInfo = data ?? throw new CustomizedErrorException("result data is null");
- Show = true;
- Timer.Start();
- }
- catch (Exception ex)
- {
- _logger.Log("加载主播抽奖信息失败", LogType.Error, ex);
- }
- }
-
- public void SetLotteryInfo(LiveRoomAnchorLotteryInfoModel info)
- {
- LotteryInfo = info;
- Show = true;
- Timer.Start();
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/ViewModels/Live/LiveRoomLotteryViewModel.cs b/src/BiliLite.UWP/ViewModels/Live/LiveRoomLotteryViewModel.cs
new file mode 100644
index 000000000..0d3e9150e
--- /dev/null
+++ b/src/BiliLite.UWP/ViewModels/Live/LiveRoomLotteryViewModel.cs
@@ -0,0 +1,191 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Timers;
+using BiliLite.Extensions;
+using BiliLite.Models.Common;
+using BiliLite.Models.Common.Live;
+using BiliLite.Models.Exceptions;
+using BiliLite.Models.Requests.Api.Live;
+using BiliLite.Services;
+using BiliLite.ViewModels.Common;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PropertyChanged;
+
+namespace BiliLite.ViewModels.Live
+{
+ public class LiveRoomLotteryViewModel : BaseViewModel
+ {
+ #region Fields
+
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+ private readonly LiveRoomAPI m_liveRoomApi;
+
+ #endregion
+
+ #region Constructors
+
+ public LiveRoomLotteryViewModel()
+ {
+ m_liveRoomApi = new LiveRoomAPI();
+ AnchorLotteryTimer = new Timer(1000);
+ AnchorLotteryTimer.Elapsed += AnchorLottery_Timer_Elapsed;
+ RedPocketLotteryTimer = new Timer(1000);
+ RedPocketLotteryTimer.Elapsed += RedPocket_Timer_Elapsed;
+ }
+
+ #endregion
+
+ #region Properties
+
+ // 天选时刻相关
+ [DoNotNotify]
+ public Timer AnchorLotteryTimer { get; set; }
+
+ public LiveRoomAnchorLotteryInfoModel AnchorLotteryInfo { get; set; }
+
+ public string AnchorLotteryDownTime { get; set; } = "--:--";
+
+ public bool AnchorLotteryShow { get; set; }
+
+ // 人气红包相关
+ [DoNotNotify]
+ public Timer RedPocketLotteryTimer { get; set; }
+
+ public LiveRoomRedPocketLotteryInfoModel RedPocketLotteryInfo { get; set; }
+
+ public string RedPocketLotteryDownTime { get; set; } = "--:--";
+
+ public bool RedPocketLotteryShow { get; set; }
+
+ public event EventHandler AnchorLotteryStart;
+
+ #endregion
+
+ #region Private Methods
+
+ private async void AnchorLottery_Timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
+ {
+ if (AnchorLotteryInfo == null) return;
+
+ if (AnchorLotteryInfo.Time <= 0)
+ {
+ AnchorLotteryDownTime = "已开奖";
+ AnchorLotteryInfo.GoawayTime--;
+ }
+
+ if (AnchorLotteryInfo.GoawayTime <= 0)
+ {
+ AnchorLotteryTimer.Stop();
+ AnchorLotteryShow = false;
+ AnchorLotteryInfo = null;
+ return;
+ }
+
+ if (AnchorLotteryInfo.Time > 0)
+ {
+ AnchorLotteryDownTime = TimeSpan.FromSeconds(AnchorLotteryInfo.Time).ToString(@"mm\:ss");
+ }
+
+ AnchorLotteryInfo.Time--;
+ });
+ }
+
+ private async void RedPocket_Timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
+ {
+ if (RedPocketLotteryInfo == null) return;
+
+ var nowTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
+ var runningTime = RedPocketLotteryInfo.CurrentTime - RedPocketLotteryInfo.StartTime;
+
+ if (RedPocketLotteryInfo.LotteryStatus == 2 ||
+ runningTime >= RedPocketLotteryInfo.LastTime ||
+ nowTime >= RedPocketLotteryInfo.EndTime)
+ {
+ RedPocketLotteryDownTime = "已开奖";
+ }
+
+ if (nowTime >= RedPocketLotteryInfo.RemoveTime)
+ {
+ RedPocketLotteryInfo = null;
+ RedPocketLotteryTimer.Stop();
+ RedPocketLotteryShow = false;
+ return;
+ }
+
+ if (runningTime < RedPocketLotteryInfo.LastTime &&
+ nowTime < RedPocketLotteryInfo.EndTime)
+ {
+ RedPocketLotteryDownTime = TimeSpan.FromSeconds(RedPocketLotteryInfo.EndTime - nowTime).ToString(@"mm\:ss");
+ }
+ });
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public async Task LoadLotteryInfo(int roomId)
+ {
+ try
+ {
+ var result = await m_liveRoomApi.RoomLotteryInfo(roomId).Request();
+ if (!result.status)
+ {
+ throw new CustomizedErrorException(result.message);
+ }
+
+ var obj = await result.GetData();
+ if (!obj.success)
+ {
+ throw new CustomizedErrorException(obj.message);
+ }
+
+ if (obj.data["anchor"].ToArray().Length > 0)
+ {
+ var data = JsonConvert.DeserializeObject(obj.data["anchor"].ToString());
+ AnchorLotteryInfo = data ?? throw new CustomizedErrorException("Anchor lottery data is null");
+ AnchorLotteryStart?.Invoke(this, AnchorLotteryInfo);
+ AnchorLotteryShow = true;
+ AnchorLotteryTimer.Start();
+ }
+
+ if (obj.data["popularity_red_pocket"].ToArray().Length > 0)
+ {
+ var data = JsonConvert.DeserializeObject>(obj.data["popularity_red_pocket"].ToString());
+ RedPocketLotteryInfo = data?[0] ?? throw new CustomizedErrorException("RedPocket lottery data is null");
+
+ RedPocketLotteryShow = true;
+ RedPocketLotteryTimer.Start();
+ }
+ }
+ catch (Exception ex)
+ {
+ Notify.ShowMessageToast("加载主播抽奖信息失败");
+ _logger.Log("加载主播抽奖信息失败", LogType.Error, ex);
+ }
+ }
+
+ public void SetAnchorLotteryInfo(LiveRoomAnchorLotteryInfoModel info)
+ {
+ AnchorLotteryInfo = info;
+ AnchorLotteryShow = true;
+ AnchorLotteryTimer.Start();
+ }
+
+ public void SetRedPocketLotteryInfo(LiveRoomRedPocketLotteryInfoModel info)
+ {
+ RedPocketLotteryInfo = info;
+ RedPocketLotteryShow = true;
+ RedPocketLotteryTimer.Start();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/ViewModels/Live/LiveRoomRankViewModel.cs b/src/BiliLite.UWP/ViewModels/Live/LiveRoomRankViewModel.cs
index 72ffcc086..c8a58dbc3 100644
--- a/src/BiliLite.UWP/ViewModels/Live/LiveRoomRankViewModel.cs
+++ b/src/BiliLite.UWP/ViewModels/Live/LiveRoomRankViewModel.cs
@@ -68,8 +68,8 @@ public LiveRoomRankViewModel(int roomId, long uid, string title, string type)
private void LoadDataCore(JObject data)
{
- var list = JsonConvert.DeserializeObject>(data["data"]["list"]
- .ToString());
+ var position = RankType == "fans" ? data["data"]["list"] : data["data"]["item"];
+ var list = JsonConvert.DeserializeObject>(position.ToString());
if (list != null)
{
foreach (var item in list)
@@ -77,21 +77,11 @@ private void LoadDataCore(JObject data)
Items.Add(item);
}
}
-
- if (RankType != "fans")
- {
- Next = data["data"]["next_offset"].ToInt32();
- CanLoadMore = Next != 0;
- }
- else
- {
- var total = data["data"]["total_page"].ToInt32();
- if (Page < total)
- {
- CanLoadMore = true;
- Page++;
- }
- }
+ if (RankType != "fans") return;
+ var total = data["data"]["total_page"].ToInt32();
+ if (Page >= total) return;
+ CanLoadMore = true;
+ Page++;
}
#endregion
@@ -113,11 +103,9 @@ public async Task LoadData()
{
Loading = true;
CanLoadMore = false;
- var api = m_liveRoomApi.FansList(Uid, RoomID, Page);
- if (RankType != "fans")
- {
- api = m_liveRoomApi.RoomRankList(Uid, RoomID, RankType, Next);
- }
+ var api = RankType == "fans" ?
+ m_liveRoomApi.FansList(Uid, RoomID, Page) :
+ m_liveRoomApi.RoomRankList(Uid, RoomID, "online_rank", "contribution_rank");
var result = await api.Request();
if (!result.status)
diff --git a/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs b/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs
index 45af7dc8f..63c28ed4c 100644
--- a/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs
+++ b/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs
@@ -46,7 +46,7 @@ public LiveRoomViewModel()
m_liveRoomApi = new LiveRoomAPI();
m_playerApi = new PlayerAPI();
//liveMessage = new Live.LiveMessage();
- AnchorLotteryViewModel = new LiveRoomAnchorLotteryViewModel();
+ LotteryViewModel = new LiveRoomLotteryViewModel();
MessageCenter.LoginedEvent += MessageCenter_LoginedEvent;
MessageCenter.LogoutedEvent += MessageCenter_LogoutedEvent;
Logined = SettingService.Account.Logined;
@@ -87,7 +87,7 @@ public LiveRoomViewModel()
[DoNotNotify]
public Timer TimerAutoHideGift { get; private set; }
- public LiveRoomAnchorLotteryViewModel AnchorLotteryViewModel { get; set; }
+ public LiveRoomLotteryViewModel LotteryViewModel { get; set; }
[DoNotNotify]
public static List Titles { get; set; }
@@ -126,9 +126,9 @@ public LiveRoomViewModel()
public bool ShowGiftMessage { get; set; }
///
- /// 人气值
+ /// 看过的人数(替代人气值)
///
- public int Online { get; set; }
+ public string WatchedNum { get; set; }
public bool Loading { get; set; } = true;
@@ -193,16 +193,28 @@ public LiveRoomViewModel()
[DoNotNotify]
public bool AutoReceiveFreeSilver { get; set; }
+ public bool ShowRedPocketLotteryWinnerList { get; set; } = false;
+
+ public bool ShowAnchorLotteryWinnerList { get; set; } = false;
+
+ public string RedPocketSendDanmuBtnText { get; set; } = "一键关注并发送弹幕";
+
#endregion
#region Events
public event EventHandler ChangedPlayUrl;
- public event EventHandler LotteryEnd;
+ public event EventHandler AnchorLotteryEnd;
public event EventHandler AddNewDanmu;
+ public event EventHandler ChatScrollToEnd;
+
+ public event EventHandler RedPocketLotteryEnd;
+
+ public event EventHandler AnchorLotteryStart;
+
#endregion
#region Private Methods
@@ -214,9 +226,13 @@ private LiveMessageHandleActionsMap InitLiveMessageHandleActionMap()
{
AddNewDanmu?.Invoke(this, e);
};
- actionMap.LotteryEnd += (_, e) =>
+ actionMap.AnchorLotteryEnd += (_, e) =>
+ {
+ AnchorLotteryEnd?.Invoke(this, e);
+ };
+ actionMap.RedPocketLotteryEnd += (_, e) =>
{
- LotteryEnd?.Invoke(this, e);
+ RedPocketLotteryEnd?.Invoke(this, e);
};
return actionMap;
}
@@ -227,7 +243,7 @@ private void LiveMessage_NewMessage(MessageType type, object message)
var success = m_messageHandleActionsMap.Map.TryGetValue(type, out var handler);
if (!success) return;
-
+
handler(this, message);
}
@@ -244,6 +260,7 @@ await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatch
else
{
HideGiftFlag++;
+ ChatScrollToEnd?.Invoke(null, null);
}
});
}
@@ -318,10 +335,10 @@ private async void ReceiveMessage(int roomId)
var buvidData = await buvidResults.GetJson>();
var buvid = buvidData.data.B3;
- var danmukuResults = await m_liveRoomApi.GetDanmukuInfo(roomId).Request();
- var danmukuData = await danmukuResults.GetJson>();
- var token = danmukuData.data.Token;
- var host = danmukuData.data.HostList[0].Host;
+ var danmuResults = await m_liveRoomApi.GetDanmuInfo(roomId).Request();
+ var danmuData = await danmuResults.GetJson>();
+ var token = danmuData.data.Token;
+ var host = danmuData.data.HostList[0].Host;
await m_liveMessage.Connect(roomId, uid, token, buvid, host, m_cancelSource.Token);
}
@@ -533,16 +550,17 @@ public async Task LoadLiveRoomDetail(string id)
RoomID = data.data.RoomInfo.RoomId;
RoomTitle = data.data.RoomInfo.Title;
- Online = data.data.RoomInfo.Online;
+ //WatchedNum = data.data.RoomInfo.Online;
Liveing = data.data.RoomInfo.LiveStatus == 1;
LiveInfo = data.data;
if (Ranks == null)
{
Ranks = new List()
{
- new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "金瓜子榜", "gold-rank"),
- new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "今日礼物榜", "today-rank"),
- new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "七日礼物榜", "seven-rank"),
+ //new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "金瓜子榜", "gold-rank"),
+ //new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "今日礼物榜", "today-rank"),
+ //new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "七日礼物榜", "seven-rank"),
+ new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "高能用户贡献榜", "contribution-rank"),
new LiveRoomRankViewModel(RoomID, data.data.RoomInfo.Uid, "粉丝榜", "fans"),
};
SelectRank = Ranks[0];
@@ -559,7 +577,9 @@ await GetPlayUrls(RoomID,
await LoadSuperChat();
if (ReceiveLotteryMsg)
{
- AnchorLotteryViewModel.LoadLotteryInfo(RoomID).RunWithoutAwait();
+ // 抽奖
+ LotteryViewModel.LoadLotteryInfo(RoomID).RunWithoutAwait();
+ RedPocketSendDanmuBtnText = Attention ? "一键发送弹幕" : "一键关注并发送弹幕";
}
}
@@ -849,8 +869,11 @@ public async Task GetGuardList()
if (!result.status) return;
var data = await result.GetData();
if (!data.success) return;
+ var guardNum = data.data["info"]["num"].ToInt32();
+ LiveInfo.GuardInfo.Count = guardNum; // 更新显示数字(似乎不生效...)
+
var top3 = JsonConvert.DeserializeObject>(data.data["top3"].ToString());
- if (Guards.Count == 0 && top3 != null && top3.Count != 0)
+ if (Guards.Count == 0 && top3 != null && top3.Count != 0 && Guards.Count < guardNum)
{
foreach (var item in top3)
{
@@ -859,7 +882,7 @@ public async Task GetGuardList()
}
var list = JsonConvert.DeserializeObject>(data.data["list"].ToString());
- if (list != null && list.Count != 0)
+ if (list != null && list.Count != 0 && Guards.Count < guardNum)
{
foreach (var item in list)
{
@@ -965,18 +988,19 @@ public async Task SendGift(LiveGiftItem liveGiftItem)
}
try
{
- var result = await m_liveRoomApi.SendGift(LiveInfo.RoomInfo.Uid, liveGiftItem.Id, liveGiftItem.Num, RoomID, liveGiftItem.CoinType, liveGiftItem.Price).Request();
+ var result = await m_liveRoomApi.SendGift(LiveInfo.RoomInfo.Uid, liveGiftItem.Id, liveGiftItem.CoinType, liveGiftItem.Num, RoomID, liveGiftItem.Price).Request();
if (!result.status)
{
throw new CustomizedErrorException(result.message);
}
- var data = await result.GetData