Skip to content

Commit 5022842

Browse files
authored
添加gRPC支持 (Richasy#1)
* 添加gRPC定义及请求逻辑 * 修改排行榜显示行为
1 parent 32334b6 commit 5022842

59 files changed

Lines changed: 13528 additions & 205 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

App.ruleset

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<RuleSet Name="Rules for App" Description="Code analysis rules for App.csproj." ToolsVersion="16.0">
2+
<RuleSet Name="Rules for App" Description="Code analysis rules for App.csproj." ToolsVersion="17.0">
33
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
44
<Rule Id="CA1001" Action="Warning" />
55
<Rule Id="CA1009" Action="Warning" />
@@ -78,6 +78,7 @@
7878
<Rule Id="SA1101" Action="None" />
7979
<Rule Id="SA1309" Action="None" />
8080
<Rule Id="SA1402" Action="None" />
81+
<Rule Id="SA1518" Action="None" />
8182
<Rule Id="SA1623" Action="None" />
8283
<Rule Id="SA1642" Action="None" />
8384
</Rules>

Bili.UWP.sln

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.31321.278
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31410.414
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App", "src\App\App.csproj", "{1C288BC0-72F3-4C4C-90AD-A05B52E937B0}"
77
EndProject
@@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Controller.Uwp", "src\Contr
4747
EndProject
4848
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Controller.Uwp.UnitTests", "src\Controller\Controller.Uwp.UnitTests\Controller.Uwp.UnitTests.csproj", "{3B66D3B1-4B4C-4AAF-8556-B3B51999F177}"
4949
EndProject
50+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models.gRPC", "src\Models\Models.gRPC\Models.gRPC.csproj", "{0187840F-8D1A-4198-B5BF-8B05CADB4554}"
51+
EndProject
5052
Global
5153
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5254
Debug|Any CPU = Debug|Any CPU
@@ -351,6 +353,26 @@ Global
351353
{3B66D3B1-4B4C-4AAF-8556-B3B51999F177}.Release|x86.ActiveCfg = Release|x86
352354
{3B66D3B1-4B4C-4AAF-8556-B3B51999F177}.Release|x86.Build.0 = Release|x86
353355
{3B66D3B1-4B4C-4AAF-8556-B3B51999F177}.Release|x86.Deploy.0 = Release|x86
356+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
357+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|Any CPU.Build.0 = Debug|Any CPU
358+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|ARM.ActiveCfg = Debug|Any CPU
359+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|ARM.Build.0 = Debug|Any CPU
360+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|ARM64.ActiveCfg = Debug|Any CPU
361+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|ARM64.Build.0 = Debug|Any CPU
362+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|x64.ActiveCfg = Debug|Any CPU
363+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|x64.Build.0 = Debug|Any CPU
364+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|x86.ActiveCfg = Debug|Any CPU
365+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Debug|x86.Build.0 = Debug|Any CPU
366+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|Any CPU.ActiveCfg = Release|Any CPU
367+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|Any CPU.Build.0 = Release|Any CPU
368+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|ARM.ActiveCfg = Release|Any CPU
369+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|ARM.Build.0 = Release|Any CPU
370+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|ARM64.ActiveCfg = Release|Any CPU
371+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|ARM64.Build.0 = Release|Any CPU
372+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|x64.ActiveCfg = Release|Any CPU
373+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|x64.Build.0 = Release|Any CPU
374+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|x86.ActiveCfg = Release|Any CPU
375+
{0187840F-8D1A-4198-B5BF-8B05CADB4554}.Release|x86.Build.0 = Release|Any CPU
354376
EndGlobalSection
355377
GlobalSection(SolutionProperties) = preSolution
356378
HideSolutionNode = FALSE
@@ -372,6 +394,7 @@ Global
372394
{CAE9B987-6DB2-42A8-B3F2-3BB700CC4DD8} = {45B5DFF9-9F13-4BF3-B561-8ABBDFE5C237}
373395
{5213E830-43F5-491E-A8EF-D75083578EF3} = {65F17D44-343F-4B87-A726-3BE3E48168B4}
374396
{3B66D3B1-4B4C-4AAF-8556-B3B51999F177} = {65F17D44-343F-4B87-A726-3BE3E48168B4}
397+
{0187840F-8D1A-4198-B5BF-8B05CADB4554} = {232C0E31-606A-48CD-B860-2E9155EAB4C6}
375398
EndGlobalSection
376399
GlobalSection(ExtensibilityGlobals) = postSolution
377400
SolutionGuid = {563225C5-4D56-446B-9ADE-09D3F0DE7963}

src/Controller/Controller.Uwp/BiliController.Rank.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Copyright (c) Richasy. All rights reserved.
22

3+
using System.Collections.Generic;
34
using System.Threading.Tasks;
4-
using Richasy.Bili.Models.BiliBili;
5-
using Richasy.Bili.Models.Enums;
5+
using Bilibili.App.Show.V1;
66

77
namespace Richasy.Bili.Controller.Uwp
88
{
@@ -15,13 +15,12 @@ public partial class BiliController
1515
/// 获取排行榜信息.
1616
/// </summary>
1717
/// <param name="partitionId">分区Id.</param>
18-
/// <param name="scope">排行榜范围.</param>
1918
/// <returns>排行榜信息.</returns>
20-
public async Task<RankInfo> GetRankAsync(int partitionId, RankScope scope)
19+
public async Task<List<RankItem>> GetRankAsync(int partitionId)
2120
{
2221
try
2322
{
24-
var rank = await _rankProvider.GetRankDetailAsync(partitionId, scope);
23+
var rank = await _rankProvider.GetRankDetailAsync(partitionId);
2524
return rank;
2625
}
2726
catch

src/Controller/Controller.Uwp/Controller.Uwp.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
<Project>{88314412-b020-415b-aeab-57adc43b273e}</Project>
5050
<Name>Models.Enums</Name>
5151
</ProjectReference>
52+
<ProjectReference Include="..\..\Models\Models.gRPC\Models.gRPC.csproj">
53+
<Project>{0187840F-8D1A-4198-B5BF-8B05CADB4554}</Project>
54+
<Name>Models.gRPC</Name>
55+
</ProjectReference>
5256
<ProjectReference Include="..\..\Utilities\Locator\Locator.Uwp\Locator.Uwp.csproj">
5357
<Project>{793ec923-d704-4c6f-9506-eb6a32bfbb8d}</Project>
5458
<Name>Locator.Uwp</Name>

src/Lib/Lib.Interfaces/IHttpProvider.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Net.Http;
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using Google.Protobuf;
89
using Richasy.Bili.Models.Enums;
910

1011
namespace Richasy.Bili.Lib.Interfaces
@@ -30,6 +31,14 @@ public interface IHttpProvider
3031
/// <returns><see cref="HttpRequestMessage"/>.</returns>
3132
Task<HttpRequestMessage> GetRequestMessageAsync(HttpMethod method, string url, Dictionary<string, string> queryParams = null, RequestClientType type = RequestClientType.Android, bool needToken = false);
3233

34+
/// <summary>
35+
/// 获取 <see cref="HttpRequestMessage"/>.
36+
/// </summary>
37+
/// <param name="url">请求地址.</param>
38+
/// <param name="grpcMessage">gRPC信息.</param>
39+
/// <returns><see cref="HttpRequestMessage"/>.</returns>
40+
Task<HttpRequestMessage> GetRequestMessageAsync(string url, IMessage grpcMessage);
41+
3342
/// <summary>
3443
/// 发送请求.
3544
/// </summary>
@@ -52,5 +61,15 @@ public interface IHttpProvider
5261
/// <typeparam name="T">需要转换的目标类型.</typeparam>
5362
/// <returns>转换结果.</returns>
5463
Task<T> ParseAsync<T>(HttpResponseMessage response);
64+
65+
/// <summary>
66+
/// 解析响应.
67+
/// </summary>
68+
/// <param name="response">得到的 <see cref="HttpResponseMessage"/>.</param>
69+
/// <param name="parser">对应gRPC类型的转换器.</param>
70+
/// <typeparam name="T">需要转换的gRPC目标类型.</typeparam>
71+
/// <returns>转换结果.</returns>
72+
Task<T> ParseAsync<T>(HttpResponseMessage response, MessageParser<T> parser)
73+
where T : IMessage<T>;
5574
}
5675
}

src/Lib/Lib.Interfaces/IRankProvider.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Copyright (c) Richasy. All rights reserved.
22

3+
using System.Collections.Generic;
34
using System.Threading.Tasks;
4-
using Richasy.Bili.Models.BiliBili;
5-
using Richasy.Bili.Models.Enums;
5+
using Bilibili.App.Show.V1;
66

77
namespace Richasy.Bili.Lib.Interfaces
88
{
@@ -15,8 +15,7 @@ public interface IRankProvider
1515
/// 获取排行榜详情.
1616
/// </summary>
1717
/// <param name="partitionId">分区Id. 如果是全区则为0.</param>
18-
/// <param name="rankScope">排行榜范围.</param>
1918
/// <returns>排行榜信息.</returns>
20-
Task<RankInfo> GetRankDetailAsync(int partitionId, RankScope rankScope);
19+
Task<List<RankItem>> GetRankDetailAsync(int partitionId);
2120
}
2221
}

src/Lib/Lib.Interfaces/Lib.Interfaces.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@
129129
<EmbeddedResource Include="Properties\Lib.Interfaces.rd.xml" />
130130
</ItemGroup>
131131
<ItemGroup>
132+
<PackageReference Include="Google.Protobuf">
133+
<Version>3.17.3</Version>
134+
</PackageReference>
132135
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
133136
<Version>6.2.12</Version>
134137
</PackageReference>
@@ -146,6 +149,10 @@
146149
<Project>{88314412-B020-415B-AEAB-57ADC43B273E}</Project>
147150
<Name>Models.Enums</Name>
148151
</ProjectReference>
152+
<ProjectReference Include="..\..\Models\Models.gRPC\Models.gRPC.csproj">
153+
<Project>{0187840F-8D1A-4198-B5BF-8B05CADB4554}</Project>
154+
<Name>Models.gRPC</Name>
155+
</ProjectReference>
149156
</ItemGroup>
150157
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
151158
<VisualStudioVersion>14.0</VisualStudioVersion>

src/Lib/Lib.Uwp/HttpProvider/HttpProvider.Extension.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,26 @@ private async Task ThrowIfHasExceptionAsync(HttpResponseMessage response)
110110
ServerResponse errorResponse = null;
111111
try
112112
{
113-
var errorResponseStr = await response.Content.ReadAsStringAsync();
114113
if (response.Content.Headers.ContentType?.MediaType.Contains("image") ?? false)
115114
{
116115
if (response.IsSuccessStatusCode)
117116
{
118117
return;
119118
}
120119
}
120+
else if (response.Content.Headers.ContentType?.MediaType == ServiceConstants.Headers.GRPCContentType)
121+
{
122+
var bytes = await response.Content.ReadAsByteArrayAsync();
123+
if (bytes.Length <= 5)
124+
{
125+
errorResponse = new ServerResponse { Message = ServiceConstants.Messages.NoData };
126+
throw new ServiceException(errorResponse, response.Headers, response.StatusCode);
127+
}
128+
129+
return;
130+
}
121131

132+
var errorResponseStr = await response.Content.ReadAsStringAsync();
122133
errorResponse = JsonConvert.DeserializeObject<ServerResponse>(errorResponseStr);
123134
if (errorResponse?.Code == 0 || string.IsNullOrEmpty(errorResponseStr))
124135
{

src/Lib/Lib.Uwp/HttpProvider/HttpProvider.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@
22

33
using System;
44
using System.Collections.Generic;
5+
using System.Linq;
56
using System.Net.Http;
7+
using System.Net.Http.Headers;
68
using System.Threading;
79
using System.Threading.Tasks;
10+
using Google.Protobuf;
811
using Newtonsoft.Json;
912
using Richasy.Bili.Lib.Interfaces;
1013
using Richasy.Bili.Models.App.Constants;
1114
using Richasy.Bili.Models.App.Other;
1215
using Richasy.Bili.Models.Enums;
16+
using Richasy.Bili.Models.gRPC;
17+
using static Richasy.Bili.Models.App.Constants.ServiceConstants;
1318

1419
namespace Richasy.Bili.Lib.Uwp
1520
{
@@ -79,6 +84,50 @@ public async Task<HttpRequestMessage> GetRequestMessageAsync(
7984
return requestMessage;
8085
}
8186

87+
/// <inheritdoc/>
88+
public async Task<HttpRequestMessage> GetRequestMessageAsync(string url, IMessage grpcMessage)
89+
{
90+
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
91+
var token = await _authenticationProvider.GetTokenAsync();
92+
var grpcConfig = new GRPCConfig(token);
93+
var userAgent = $"bili-universal/62800300 "
94+
+ $"os/ios model/{GRPCConfig.Model} mobi_app/iphone "
95+
+ $"osVer/{GRPCConfig.OSVersion} "
96+
+ $"network/{GRPCConfig.NetworkType} "
97+
+ $"grpc-objc/1.32.0 grpc-c/12.0.0 (ios; cronet_http)";
98+
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(Headers.Identify, token);
99+
requestMessage.Headers.Add(Headers.UserAgent, userAgent);
100+
requestMessage.Headers.Add(Headers.AppKey, GRPCConfig.MobileApp);
101+
requestMessage.Headers.Add(Headers.BiliDevice, grpcConfig.GetDeviceBin());
102+
requestMessage.Headers.Add(Headers.BiliFawkes, grpcConfig.GetFawkesreqBin());
103+
requestMessage.Headers.Add(Headers.BiliLocale, grpcConfig.GetLocaleBin());
104+
requestMessage.Headers.Add(Headers.BiliMeta, grpcConfig.GetMetadataBin());
105+
requestMessage.Headers.Add(Headers.BiliNetwork, grpcConfig.GetNetworkBin());
106+
requestMessage.Headers.Add(Headers.BiliRestriction, grpcConfig.GetRestrictionBin());
107+
requestMessage.Headers.Add(Headers.GRPCAcceptEncodingKey, Headers.GRPCAcceptEncodingValue);
108+
requestMessage.Headers.Add(Headers.GRPCTimeOutKey, Headers.GRPCTimeOutValue);
109+
requestMessage.Headers.Add(Headers.Envoriment, GRPCConfig.Envorienment);
110+
requestMessage.Headers.Add(Headers.TransferEncodingKey, Headers.TransferEncodingValue);
111+
requestMessage.Headers.Add(Headers.TEKey, Headers.TEValue);
112+
113+
var messageBytes = grpcMessage.ToByteArray();
114+
115+
// 校验用?第五位为数组长度
116+
var stateBytes = new byte[] { 0, 0, 0, 0, (byte)messageBytes.Length };
117+
118+
// 合并两个字节数组
119+
var bodyBytes = new byte[5 + messageBytes.Length];
120+
stateBytes.CopyTo(bodyBytes, 0);
121+
messageBytes.CopyTo(bodyBytes, 5);
122+
123+
var byteArrayContent = new ByteArrayContent(bodyBytes);
124+
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue(Headers.GRPCContentType);
125+
byteArrayContent.Headers.ContentLength = bodyBytes.Length;
126+
127+
requestMessage.Content = byteArrayContent;
128+
return requestMessage;
129+
}
130+
82131
/// <inheritdoc/>
83132
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
84133
{
@@ -107,5 +156,13 @@ public async Task<T> ParseAsync<T>(HttpResponseMessage response)
107156
var responseString = await response.Content.ReadAsStringAsync();
108157
return JsonConvert.DeserializeObject<T>(responseString);
109158
}
159+
160+
/// <inheritdoc/>
161+
public async Task<T> ParseAsync<T>(HttpResponseMessage response, MessageParser<T> parser)
162+
where T : IMessage<T>
163+
{
164+
var bytes = await response.Content.ReadAsByteArrayAsync();
165+
return parser.ParseFrom(bytes.Skip(5).ToArray());
166+
}
110167
}
111168
}

src/Lib/Lib.Uwp/Lib.Uwp.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
<Content Include="Properties\Lib.Uwp.rd.xml" />
3030
</ItemGroup>
3131
<ItemGroup>
32+
<PackageReference Include="Google.Protobuf">
33+
<Version>3.17.3</Version>
34+
</PackageReference>
3235
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
3336
<Version>6.2.12</Version>
3437
</PackageReference>
@@ -52,6 +55,10 @@
5255
<Project>{88314412-B020-415B-AEAB-57ADC43B273E}</Project>
5356
<Name>Models.Enums</Name>
5457
</ProjectReference>
58+
<ProjectReference Include="..\..\Models\Models.gRPC\Models.gRPC.csproj">
59+
<Project>{0187840F-8D1A-4198-B5BF-8B05CADB4554}</Project>
60+
<Name>Models.gRPC</Name>
61+
</ProjectReference>
5562
<ProjectReference Include="..\..\Utilities\Locator\Locator.Uwp\Locator.Uwp.csproj">
5663
<Project>{793EC923-D704-4C6F-9506-EB6A32BFBB8D}</Project>
5764
<Name>Locator.Uwp</Name>

0 commit comments

Comments
 (0)