From 42574843c4d66176fe78d800784514c66a749701 Mon Sep 17 00:00:00 2001
From: Linwenxuan <116782992+Linwenxuan05@users.noreply.github.com>
Date: Mon, 1 Apr 2024 22:44:22 +0800
Subject: [PATCH] [Kritor] Intrudoce Kritor (#270)
* [Kritor] Introduce Lagrange.Kritor
* [Kritor] Setup structure
---
Lagrange.Core.sln | 6 +
Lagrange.Kritor/Lagrange.Kritor.csproj | 35 +++
Lagrange.Kritor/LagrangeApp.cs | 31 +++
Lagrange.Kritor/LagrangeAppBuilder.cs | 6 +
Lagrange.Kritor/Program.cs | 17 ++
.../Properties/launchSettings.json | 23 ++
.../Protos/auth/authentication.proto | 86 ++++++
Lagrange.Kritor/Protos/common/contact.proto | 31 +++
.../Protos/common/message_data.proto | 42 +++
.../Protos/common/message_element.proto | 257 ++++++++++++++++++
Lagrange.Kritor/Protos/common/request.proto | 31 +++
Lagrange.Kritor/Protos/core/core.proto | 58 ++++
.../Protos/customization/customization.proto | 16 ++
Lagrange.Kritor/Protos/event/event.proto | 37 +++
.../Protos/event/event_notice.proto | 54 ++++
.../Protos/event/event_request.proto | 27 ++
.../Protos/event/notice_data.proto | 161 +++++++++++
.../Protos/event/request_data.proto | 32 +++
Lagrange.Kritor/Protos/file/file_data.proto | 33 +++
Lagrange.Kritor/Protos/file/group_file.proto | 93 +++++++
.../Protos/friend/firend_data.proto | 54 ++++
Lagrange.Kritor/Protos/friend/friend.proto | 101 +++++++
Lagrange.Kritor/Protos/group/group.proto | 210 ++++++++++++++
Lagrange.Kritor/Protos/group/group_data.proto | 75 +++++
Lagrange.Kritor/Protos/message/message.proto | 161 +++++++++++
Lagrange.Kritor/Protos/reverse/reverse.proto | 14 +
Lagrange.Kritor/Protos/web/web.proto | 50 ++++
Lagrange.Kritor/Services/AuthService.cs | 6 +
Lagrange.Kritor/Services/CoreService.cs | 6 +
.../Services/CustomizationService.cs | 6 +
Lagrange.Kritor/Services/EventService.cs | 6 +
Lagrange.Kritor/Services/FriendService.cs | 6 +
Lagrange.Kritor/Services/GroupFileService.cs | 6 +
Lagrange.Kritor/Services/GroupService.cs | 6 +
Lagrange.Kritor/Services/MessageService.cs | 6 +
Lagrange.Kritor/Services/WebService.cs | 6 +
Lagrange.Kritor/appsettings.Development.json | 8 +
Lagrange.Kritor/appsettings.json | 14 +
38 files changed, 1817 insertions(+)
create mode 100644 Lagrange.Kritor/Lagrange.Kritor.csproj
create mode 100644 Lagrange.Kritor/LagrangeApp.cs
create mode 100644 Lagrange.Kritor/LagrangeAppBuilder.cs
create mode 100644 Lagrange.Kritor/Program.cs
create mode 100644 Lagrange.Kritor/Properties/launchSettings.json
create mode 100644 Lagrange.Kritor/Protos/auth/authentication.proto
create mode 100644 Lagrange.Kritor/Protos/common/contact.proto
create mode 100644 Lagrange.Kritor/Protos/common/message_data.proto
create mode 100644 Lagrange.Kritor/Protos/common/message_element.proto
create mode 100644 Lagrange.Kritor/Protos/common/request.proto
create mode 100644 Lagrange.Kritor/Protos/core/core.proto
create mode 100644 Lagrange.Kritor/Protos/customization/customization.proto
create mode 100644 Lagrange.Kritor/Protos/event/event.proto
create mode 100644 Lagrange.Kritor/Protos/event/event_notice.proto
create mode 100644 Lagrange.Kritor/Protos/event/event_request.proto
create mode 100644 Lagrange.Kritor/Protos/event/notice_data.proto
create mode 100644 Lagrange.Kritor/Protos/event/request_data.proto
create mode 100644 Lagrange.Kritor/Protos/file/file_data.proto
create mode 100644 Lagrange.Kritor/Protos/file/group_file.proto
create mode 100644 Lagrange.Kritor/Protos/friend/firend_data.proto
create mode 100644 Lagrange.Kritor/Protos/friend/friend.proto
create mode 100644 Lagrange.Kritor/Protos/group/group.proto
create mode 100644 Lagrange.Kritor/Protos/group/group_data.proto
create mode 100644 Lagrange.Kritor/Protos/message/message.proto
create mode 100644 Lagrange.Kritor/Protos/reverse/reverse.proto
create mode 100644 Lagrange.Kritor/Protos/web/web.proto
create mode 100644 Lagrange.Kritor/Services/AuthService.cs
create mode 100644 Lagrange.Kritor/Services/CoreService.cs
create mode 100644 Lagrange.Kritor/Services/CustomizationService.cs
create mode 100644 Lagrange.Kritor/Services/EventService.cs
create mode 100644 Lagrange.Kritor/Services/FriendService.cs
create mode 100644 Lagrange.Kritor/Services/GroupFileService.cs
create mode 100644 Lagrange.Kritor/Services/GroupService.cs
create mode 100644 Lagrange.Kritor/Services/MessageService.cs
create mode 100644 Lagrange.Kritor/Services/WebService.cs
create mode 100644 Lagrange.Kritor/appsettings.Development.json
create mode 100644 Lagrange.Kritor/appsettings.json
diff --git a/Lagrange.Core.sln b/Lagrange.Core.sln
index 28909c5a2..8f387f979 100644
--- a/Lagrange.Core.sln
+++ b/Lagrange.Core.sln
@@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "SolutionI
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lagrange.Audio", "Lagrange.Audio\Lagrange.Audio.csproj", "{2D462D26-0FD5-40A9-A0C8-F7449117EE0E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lagrange.Kritor", "Lagrange.Kritor\Lagrange.Kritor.csproj", "{FD0A15C0-600E-44A9-BAA8-6FAE0A1CA7EE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -42,6 +44,10 @@ Global
{2D462D26-0FD5-40A9-A0C8-F7449117EE0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D462D26-0FD5-40A9-A0C8-F7449117EE0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D462D26-0FD5-40A9-A0C8-F7449117EE0E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FD0A15C0-600E-44A9-BAA8-6FAE0A1CA7EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FD0A15C0-600E-44A9-BAA8-6FAE0A1CA7EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FD0A15C0-600E-44A9-BAA8-6FAE0A1CA7EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FD0A15C0-600E-44A9-BAA8-6FAE0A1CA7EE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Lagrange.Kritor/Lagrange.Kritor.csproj b/Lagrange.Kritor/Lagrange.Kritor.csproj
new file mode 100644
index 000000000..39dad91e9
--- /dev/null
+++ b/Lagrange.Kritor/Lagrange.Kritor.csproj
@@ -0,0 +1,35 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Lagrange.Kritor/LagrangeApp.cs b/Lagrange.Kritor/LagrangeApp.cs
new file mode 100644
index 000000000..60bc6871a
--- /dev/null
+++ b/Lagrange.Kritor/LagrangeApp.cs
@@ -0,0 +1,31 @@
+namespace Lagrange.Kritor;
+
+public class LagrangeApp : IHost
+{
+ private readonly IHost _hostApp;
+
+ public IServiceProvider Services => _hostApp.Services;
+
+ public ILogger Logger { get; }
+
+ internal LagrangeApp(IHost host)
+ {
+ _hostApp = host;
+ Logger = Services.GetRequiredService>();
+ }
+
+ public void Dispose()
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task StartAsync(CancellationToken cancellationToken = new CancellationToken())
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken = new CancellationToken())
+ {
+ throw new NotImplementedException();
+ }
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/LagrangeAppBuilder.cs b/Lagrange.Kritor/LagrangeAppBuilder.cs
new file mode 100644
index 000000000..faf4f0237
--- /dev/null
+++ b/Lagrange.Kritor/LagrangeAppBuilder.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor;
+
+public sealed class LagrangeAppBuilder
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Program.cs b/Lagrange.Kritor/Program.cs
new file mode 100644
index 000000000..27c123520
--- /dev/null
+++ b/Lagrange.Kritor/Program.cs
@@ -0,0 +1,17 @@
+namespace Lagrange.Kritor;
+
+internal static class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ builder.Services.AddGrpc();
+
+ var app = builder.Build();
+
+ app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
+
+ app.Run();
+ }
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Properties/launchSettings.json b/Lagrange.Kritor/Properties/launchSettings.json
new file mode 100644
index 000000000..35e9b5b9f
--- /dev/null
+++ b/Lagrange.Kritor/Properties/launchSettings.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": false,
+ "applicationUrl": "http://localhost:5211",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": false,
+ "applicationUrl": "https://localhost:7233;http://localhost:5211",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/Lagrange.Kritor/Protos/auth/authentication.proto b/Lagrange.Kritor/Protos/auth/authentication.proto
new file mode 100644
index 000000000..0cb9f2bed
--- /dev/null
+++ b/Lagrange.Kritor/Protos/auth/authentication.proto
@@ -0,0 +1,86 @@
+syntax = "proto3";
+
+package kritor.authentication;
+
+option csharp_namespace = "Kritor.Authentication";
+option java_multiple_files = true;
+option java_package = "io.kritor.authentication";
+option go_package = "grpc/kritor/authentication";
+
+service AuthenticationService {
+ rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse);
+ rpc GetAuthenticationState(GetAuthenticationStateRequest) returns (GetAuthenticationStateResponse);
+
+ rpc GetTicket(GetTicketRequest) returns (GetTicketResponse);
+ rpc AddTicket(AddTicketRequest) returns (AddTicketResponse);
+ rpc DeleteTicket(DeleteTicketRequest) returns (DeleteTicketResponse);
+}
+
+/*
+在某个账号授权成功之后,接下来所有的请求都必须围绕该账号,且禁止再次发送授权包。
+ */
+message AuthenticateRequest {
+ string account = 1; // 客户端连接认证账号
+ string ticket = 2; // 客户端连接认证ticket
+}
+
+message AuthenticateResponse {
+ enum AuthenticateResponseCode {
+ OK = 0;
+ NO_ACCOUNT = 1;
+ NO_TICKET = 2;
+ LOGIC_ERROR = 3;
+ }
+
+ AuthenticateResponseCode code = 1; // 认证结果
+ string msg = 2; // 错误信息
+}
+
+message GetAuthenticationStateRequest {
+ string account = 1; // 客户端连接认证账号
+}
+
+message GetAuthenticationStateResponse {
+ bool is_required = 1; // 是否需要认证
+}
+
+
+/* 所有对认证ticket增删查都需要使用super ticket */
+
+enum TicketOperationResponseCode {
+ OK = 0;
+ ERROR = 1;
+}
+
+message GetTicketRequest {
+ string account = 1; // 客户端连接认证账号
+ string super_ticket = 2; // 客户端连接认证super ticket
+}
+
+message GetTicketResponse {
+ TicketOperationResponseCode code = 1;
+ string msg = 2;
+ repeated string tickets = 3; // 返回的客户端ticket,非super ticket
+}
+
+message AddTicketRequest {
+ string account = 1; // 客户端连接认证账号
+ string super_ticket = 2; // 客户端连接认证super ticket
+ string ticket = 3;
+}
+
+message AddTicketResponse {
+ TicketOperationResponseCode code = 1;
+ string msg = 2;
+}
+
+message DeleteTicketRequest {
+ string account = 1; // 客户端连接认证账号
+ string super_ticket = 2; // 客户端连接认证super ticket
+ string ticket = 3;
+}
+
+message DeleteTicketResponse {
+ TicketOperationResponseCode code = 1;
+ string msg = 2;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/common/contact.proto b/Lagrange.Kritor/Protos/common/contact.proto
new file mode 100644
index 000000000..1c3351292
--- /dev/null
+++ b/Lagrange.Kritor/Protos/common/contact.proto
@@ -0,0 +1,31 @@
+syntax = "proto3";
+
+package kritor.common;
+
+option csharp_namespace = "Kritor.Common";
+option java_multiple_files = true;
+option java_package = "io.kritor.common";
+option go_package = "grpc/kritor/common";
+
+enum Scene {
+ GROUP = 0; // 群聊
+ FRIEND = 1; // 私聊
+ GUILD = 2; // 频道
+ STRANGER_FROM_GROUP = 10; // 群临时会话
+
+ // 以下类型为可选实现
+ NEARBY = 5; // 附近的人
+ STRANGER = 9; // 陌生人
+}
+
+message Contact {
+ Scene scene = 1;
+ string peer = 2; // 群聊则为群号 私聊则为uid 频道消息则为频道号
+ optional string sub_peer = 3; // 群临时聊天则为群号 频道消息则为子频道号 其它情况可不提供
+}
+
+message Sender {
+ string uid = 1;
+ optional uint64 uin = 2;
+ optional string nick = 3;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/common/message_data.proto b/Lagrange.Kritor/Protos/common/message_data.proto
new file mode 100644
index 000000000..6f1c9eccf
--- /dev/null
+++ b/Lagrange.Kritor/Protos/common/message_data.proto
@@ -0,0 +1,42 @@
+syntax = "proto3";
+
+package kritor.common;
+
+option csharp_namespace = "Kritor.Common";
+option java_multiple_files = true;
+option java_package = "io.kritor.common";
+option go_package = "grpc/kritor/common";
+
+import "Protos/common/contact.proto";
+import "Protos/common/message_element.proto";
+
+message PushMessageBody {
+ uint32 time = 1;
+ string message_id = 2;
+ uint64 message_seq = 3;
+ Contact contact = 4; // 从什么地方收到的信息
+ Sender sender = 5; // 发送者详细信息
+ repeated Element elements = 6; // 发的什么东西
+}
+
+message ForwardMessageBody {
+ oneof forward_message {
+ string message_id = 1;
+ PushMessageBody message = 2;
+ }
+}
+
+message EssenceMessageBody {
+ uint32 group_id = 1;
+ string sender_uid = 2;
+ uint64 sender_uin = 3;
+ string sender_nick = 4;
+ uint64 operator_uid = 5;
+ uint64 operator_uin = 6;
+ string operator_nick = 7;
+ uint32 operation_time = 8;
+ uint32 message_time = 9;
+ string message_id = 10;
+ uint64 message_seq = 11;
+ string json_elements = 12;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/common/message_element.proto b/Lagrange.Kritor/Protos/common/message_element.proto
new file mode 100644
index 000000000..331e9fc7b
--- /dev/null
+++ b/Lagrange.Kritor/Protos/common/message_element.proto
@@ -0,0 +1,257 @@
+syntax = "proto3";
+
+package kritor.common;
+
+option csharp_namespace = "Kritor.Common";
+option java_multiple_files = true;
+option java_package = "io.kritor.common";
+option go_package = "grpc/kritor/common";
+
+import "Protos/common/contact.proto";
+
+message Element {
+ enum ElementType {
+ TEXT = 0;
+ AT = 1;
+ FACE = 2;
+ BUBBLE_FACE = 3;
+ REPLY = 4;
+ IMAGE = 5;
+ VOICE = 6;
+ VIDEO = 7;
+ BASKETBALL = 8;
+ DICE = 9;
+ RPS = 10;
+ POKE = 11;
+ MUSIC = 12;
+ WEATHER = 13;
+ LOCATION = 14;
+ SHARE = 15;
+ GIFT = 16;
+ MARKET_FACE = 17;
+ FORWARD = 18;
+ CONTACT = 19;
+ JSON = 20;
+ XML = 21;
+ FILE = 22;
+ MARKDOWN = 23;
+ KEYBOARD = 24;
+ }
+
+ // be friendly to some languages that don't support oneof
+ ElementType type = 1;
+ oneof data {
+ TextElement text = 2;
+ AtElement at = 3;
+ FaceElement face = 4;
+ BubbleFaceElement bubble_face = 5;
+ ReplyElement reply = 6;
+ ImageElement image = 7;
+ VoiceElement voice = 8;
+ VideoElement video = 9;
+ BasketballElement basketball = 10;
+ DiceElement dice = 11;
+ RpsElement rps = 12;
+ PokeElement poke = 13;
+ MusicElement music = 14;
+ WeatherElement weather = 15;
+ LocationElement location = 16;
+ ShareElement share = 17;
+ GiftElement gift = 18;
+ MarketFaceElement market_face = 19;
+ ForwardElement forward = 20;
+ ContactElement contact = 21;
+ JsonElement json = 22;
+ XmlElement xml = 23;
+ FileElement file = 24;
+ MarkdownElement markdown = 25;
+ KeyboardElement keyboard = 26;
+ }
+}
+
+message TextElement {
+ string text = 1; // 文本
+}
+
+message AtElement {
+ string uid = 1; // 全体成员这里请写all
+ optional uint64 uin = 2;
+}
+
+message FaceElement {
+ uint32 id = 1; // 表情id
+ optional bool is_big = 2; // 是否大表情,默认不是
+ optional uint32 result = 3;
+}
+
+message BubbleFaceElement {
+ uint32 id = 1; // 表情id
+ uint32 count = 2; // 表情数量
+}
+
+message ReplyElement {
+ string message_id = 1; // 回复的消息id
+}
+
+message ImageElement {
+ enum ImageType {
+ COMMON = 0;
+ ORIGIN = 1;
+ FLASH = 2;
+ }
+
+ oneof data {
+ bytes file = 1; // 文件内容
+ string file_name = 2; // 文件文件名
+ string file_path = 3; // 文件绝对路径
+ string file_url = 4; // 文件下载地址
+ }
+ optional string file_md5 = 5;
+ optional uint32 sub_type = 6;
+ optional ImageType type = 10;
+}
+
+message VoiceElement {
+ oneof data {
+ bytes file = 1; // 文件内容
+ string file_name = 2; // 文件文件名
+ string file_path = 3; // 文件绝对路径
+ string file_url = 4; // 文件下载地址
+ }
+ optional string file_md5 = 5;
+ optional bool magic = 6; // 是否魔法语音
+}
+
+message VideoElement {
+ oneof data {
+ bytes file = 1; // 文件内容
+ string file_name = 2; // 文件名
+ string file_path = 3; // 文件绝对路径
+ string file_url = 4; // 文件下载地址
+ }
+ optional string file_md5 = 5;
+}
+
+message BasketballElement {
+ uint32 id = 1;
+} // NT改版,这类消息的值由服务器随机生成
+
+message DiceElement { uint32 id = 1; }
+
+message RpsElement { uint32 id = 1; }
+
+message PokeElement {
+ uint32 id = 1; // 戳一戳id
+ uint32 type = 2; // 戳一戳类型
+ uint32 strength = 3; // 戳一戳强度
+}
+
+message CustomMusicData {
+ string url = 1;
+ string audio = 2;
+ string title = 3;
+ string author = 4;
+ string pic = 5;
+}
+
+message MusicElement {
+ enum MusicPlatform {
+ QQ = 0;
+ NetEase = 1;
+ Custom = 10;
+ }
+
+ MusicPlatform platform = 1;
+ oneof data {
+ string id = 2;
+ CustomMusicData custom = 3;
+ }
+}
+
+message WeatherElement {
+ string city = 1;
+ string code = 2;
+}
+
+message LocationElement {
+ float lat = 1;
+ float lon = 2;
+ string title = 3;
+ string address = 4;
+}
+
+message ShareElement {
+ string url = 1;
+ string title = 2;
+ string content = 3;
+ string image = 4;
+}
+
+message GiftElement {
+ uint64 qq = 1;
+ uint32 id = 2;
+} // 不支持发送
+
+message MarketFaceElement { string id = 1; }
+
+message ForwardElement {
+ string res_id = 1;
+ string uniseq = 2;
+ string summary = 3;
+ string description = 4;
+}
+
+message ContactElement {
+ Scene scene = 1;
+ string peer = 2;
+}
+
+message JsonElement { string json = 1; }
+
+message XmlElement { string xml = 1; }
+
+message FileElement {
+ optional string name = 1;
+ optional uint64 size = 2;
+ optional uint64 expire_time = 3;
+ optional string id = 4;
+ optional string url = 5;
+ optional int32 biz = 6;
+ optional string sub_id = 7;
+} // 不支持通过这里发送
+
+message MarkdownElement { string markdown = 1; }
+
+message ButtonActionPermission {
+ int32 type = 1;
+ repeated string role_ids = 2;
+ repeated string user_ids = 3;
+}
+
+message ButtonAction {
+ int32 type = 1;
+ ButtonActionPermission permission = 2;
+ string unsupported_tips = 3;
+ string data = 4;
+ bool reply = 5;
+ bool enter = 6;
+}
+
+message ButtonRender {
+ string label = 1;
+ string visited_label = 2;
+ int32 style = 3;
+}
+
+message Button {
+ string id = 1;
+ ButtonRender render_data = 2;
+ ButtonAction action = 3;
+}
+
+message KeyboardRow { repeated Button buttons = 1; }
+
+message KeyboardElement {
+ repeated KeyboardRow rows = 1;
+ uint64 bot_appid = 2;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/common/request.proto b/Lagrange.Kritor/Protos/common/request.proto
new file mode 100644
index 000000000..88c5b197c
--- /dev/null
+++ b/Lagrange.Kritor/Protos/common/request.proto
@@ -0,0 +1,31 @@
+syntax = "proto3";
+
+package kritor.common;
+
+option csharp_namespace = "Kritor.Common";
+option java_multiple_files = true;
+option java_package = "io.kritor.common";
+option go_package = "grpc/kritor/common";
+
+message Request {
+ string cmd = 1; // command, such as "android.get_external_storage_path"
+ uint32 seq = 2;
+ bytes buf = 3;
+ bool no_response = 4; // no response
+}
+
+message Response {
+ enum ResponseCode {
+ SUCCESS = 0;
+ INVALID_ARGUMENT = 1;
+ INTERNAL = 2;
+ UNAUTHENTICATED = 3;
+ PERMISSION_DENIED = 4;
+ }
+
+ string cmd = 1;
+ uint32 seq = 2;
+ ResponseCode code = 3;
+ optional string msg = 4;
+ bytes buf = 5;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/core/core.proto b/Lagrange.Kritor/Protos/core/core.proto
new file mode 100644
index 000000000..a9a6cc9c3
--- /dev/null
+++ b/Lagrange.Kritor/Protos/core/core.proto
@@ -0,0 +1,58 @@
+syntax = "proto3";
+
+package kritor.core;
+
+option csharp_namespace = "Kritor.Core";
+option java_multiple_files = true;
+option java_package = "io.kritor.core";
+option go_package = "grpc/kritor/core";
+
+service CoreService {
+ rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); // 获取Kritor版本
+ rpc DownloadFile(DownloadFileRequest) returns (DownloadFileResponse); // 让Kritor下载文件到Kritor本地
+
+ rpc GetCurrentAccount(GetCurrentAccountRequest) returns (GetCurrentAccountResponse); // 获取当前账户信息
+ rpc SwitchAccount(SwitchAccountRequest) returns (SwitchAccountResponse); // 切换账户
+}
+
+message GetVersionRequest {
+}
+
+message GetVersionResponse {
+ string version = 1; // Kritor版本
+ string app_name = 2;
+}
+
+message DownloadFileRequest {
+ optional string url = 1; // 下载文件的URL 二选一
+ optional string base64 = 2; // 下载文件的base64 二选一
+ optional string root_path = 3; // 下载文件的根目录 需要保证Kritor有该目录访问权限 可选
+ optional string file_name = 4; // 保存的文件名称 默认为文件MD5 可选
+ optional uint32 thread_cnt = 5; // 下载文件的线程数 默认为3 可选
+ optional string headers = 6; // 下载文件的请求头 可选
+}
+
+message DownloadFileResponse {
+ string file_absolute_path = 1; // 下载文件的绝对路径
+ string file_md5 = 2; // 下载文件的MD5
+}
+
+message GetCurrentAccountRequest {
+}
+
+message GetCurrentAccountResponse {
+ string account_uid = 1; // 当前账户
+ uint64 account_uin = 2;
+ string account_name = 3; // 当前账户名称
+}
+
+message SwitchAccountRequest {
+ oneof account {
+ string account_uid = 1; // 切换账户uid
+ uint64 account_uin = 2; // 切换账户uin
+ }
+ string super_ticket = 3; // 凭证
+}
+
+message SwitchAccountResponse {
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/customization/customization.proto b/Lagrange.Kritor/Protos/customization/customization.proto
new file mode 100644
index 000000000..98ac13e32
--- /dev/null
+++ b/Lagrange.Kritor/Protos/customization/customization.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package kritor.customization;
+
+option csharp_namespace = "Kritor.Customization";
+option java_multiple_files = true;
+option java_package = "io.kritor.customization";
+option go_package = "grpc/kritor/customization";
+
+import "Protos/common/request.proto";
+
+/* 自定义功能接口 */
+
+service CustomizationService {
+ rpc CallFunction(kritor.common.Request) returns (kritor.common.Response);
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/event/event.proto b/Lagrange.Kritor/Protos/event/event.proto
new file mode 100644
index 000000000..a69847529
--- /dev/null
+++ b/Lagrange.Kritor/Protos/event/event.proto
@@ -0,0 +1,37 @@
+syntax = "proto3";
+
+package kritor.event;
+
+option csharp_namespace = "Kritor.Event";
+option java_multiple_files = true;
+option java_package = "io.kritor.event";
+option go_package = "grpc/kritor/event";
+
+import "Protos/common/message_data.proto";
+import "Protos/event/event_notice.proto";
+import "Protos/event/event_request.proto";
+
+service EventService {
+ rpc RegisterActiveListener(RequestPushEvent) returns (stream EventStructure); // 主动RPC推送器
+ rpc RegisterPassiveListener(stream EventStructure) returns (RequestPushEvent); // 被动RPC监听器
+}
+
+enum EventType {
+ EVENT_TYPE_CORE_EVENT = 0;
+ EVENT_TYPE_MESSAGE = 1;
+ EVENT_TYPE_NOTICE = 2;
+ EVENT_TYPE_REQUEST = 3;
+}
+
+message RequestPushEvent {
+ EventType type = 1;
+}
+
+message EventStructure {
+ EventType type = 1;
+ oneof event {
+ kritor.common.PushMessageBody message = 2;
+ RequestsEvent request = 3;
+ NoticeEvent notice = 4;
+ }
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/event/event_notice.proto b/Lagrange.Kritor/Protos/event/event_notice.proto
new file mode 100644
index 000000000..502c5c04a
--- /dev/null
+++ b/Lagrange.Kritor/Protos/event/event_notice.proto
@@ -0,0 +1,54 @@
+syntax = "proto3";
+
+package kritor.event;
+
+option csharp_namespace = "Kritor.Event";
+option java_multiple_files = true;
+option java_package = "io.kritor.event";
+option go_package = "grpc/kritor/event";
+
+import "Protos/event/notice_data.proto";
+
+message NoticeEvent {
+ enum NoticeType {
+ UNKNOWN = 0;
+ FRIEND_POKE = 10; // 好友头像戳一戳
+ FRIEND_RECALL = 11; // 好友消息撤回
+ FRIEND_FILE_COME = 12; // 私聊文件上传
+
+ GROUP_POKE = 20; // 群头像戳一戳
+ GROUP_CARD_CHANGED = 21; // 群名片改变
+ GROUP_MEMBER_UNIQUE_TITLE_CHANGED = 22; // 群成员专属头衔改变
+ GROUP_ESSENCE_CHANGED = 23; // 群精华消息改变
+ GROUP_RECALL = 24; // 群消息撤回
+ GROUP_MEMBER_INCREASE = 25; // 群成员增加
+ GROUP_MEMBER_DECREASE = 26; // 群成员减少
+ GROUP_ADMIN_CHANGED = 27; // 群管理员变动
+ GROUP_MEMBER_BANNED = 28; // 群成员被禁言
+ GROUP_SIGN = 29; // 群签到
+ GROUP_WHOLE_BAN = 30; // 群全员禁言
+ GROUP_FILE_COME = 31; // 群文件上传
+ }
+
+ NoticeType type = 1;
+ uint32 time = 2;
+
+ oneof notice {
+ FriendPokeNotice friend_poke = 10;
+ FriendRecallNotice friend_recall = 11;
+ FriendFileUploadedNotice friend_file_uploaded = 12;
+
+ GroupPokeNotice group_poke = 20;
+ GroupCardChangedNotice group_card_changed = 21;
+ GroupUniqueTitleChangedNotice group_member_unique_title_changed = 22;
+ GroupEssenceMessageNotice group_essence_changed = 23;
+ GroupRecallNotice group_recall = 24;
+ GroupMemberIncreasedNotice group_member_increase = 25;
+ GroupMemberDecreasedNotice group_member_decrease = 26;
+ GroupAdminChangedNotice group_admin_change = 27;
+ GroupMemberBanNotice group_member_ban = 28;
+ GroupSignInNotice group_sign_in = 29;
+ GroupWholeBanNotice group_whole_ban = 30;
+ GroupFileUploadedNotice group_file_uploaded = 31;
+ }
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/event/event_request.proto b/Lagrange.Kritor/Protos/event/event_request.proto
new file mode 100644
index 000000000..4f351273e
--- /dev/null
+++ b/Lagrange.Kritor/Protos/event/event_request.proto
@@ -0,0 +1,27 @@
+syntax = "proto3";
+
+package kritor.event;
+
+option csharp_namespace = "Kritor.Event";
+option java_multiple_files = true;
+option java_package = "io.kritor.event";
+option go_package = "grpc/kritor/event";
+
+import "Protos/event/request_data.proto";
+
+message RequestsEvent {
+ enum RequestType {
+ FRIEND_APPLY = 0;
+ GROUP_APPLY = 1;
+ INVITED_GROUP = 2;
+ }
+
+ RequestType type = 1;
+ uint32 time = 2;
+
+ oneof request {
+ FriendApplyRequest friend_apply = 3;
+ GroupApplyRequest group_apply = 4;
+ InvitedJoinGroupRequest invited_group = 5;
+ }
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/event/notice_data.proto b/Lagrange.Kritor/Protos/event/notice_data.proto
new file mode 100644
index 000000000..6de48eebe
--- /dev/null
+++ b/Lagrange.Kritor/Protos/event/notice_data.proto
@@ -0,0 +1,161 @@
+syntax = "proto3";
+
+package kritor.event;
+
+option csharp_namespace = "Kritor.Event";
+option java_multiple_files = true;
+option java_package = "io.kritor.event";
+option go_package = "grpc/kritor/event";
+
+message FriendPokeNotice {
+ string operator_uid = 1;
+ uint64 operator_uin = 2;
+ string action = 3;
+ string suffix = 4;
+ string action_image = 5;
+}
+
+message FriendRecallNotice {
+ string operator_uid = 1;
+ uint64 operator_uin = 2;
+ string message_id = 3;
+ string tip_text = 4;
+}
+
+message GroupUniqueTitleChangedNotice {
+ uint64 target = 1;
+ string title = 2;
+ uint64 group_id = 3;
+}
+
+message GroupEssenceMessageNotice {
+ uint64 group_id = 1;
+ string operator_uid = 2;
+ uint64 operator_uin = 3;
+ string target_uid = 4;
+ uint64 target_uin = 5;
+ string message_id = 6;
+ uint32 sub_type = 7;
+}
+
+message GroupPokeNotice {
+ uint64 group_id = 1;
+ string operator_uid = 2;
+ uint64 operator_uin = 3;
+ string target_uid = 4;
+ uint64 target_uin = 5;
+ string action = 6;
+ string suffix = 7;
+ string action_image = 8;
+}
+
+message GroupCardChangedNotice {
+ uint64 group_id = 1;
+ string operator_uid = 2;
+ uint64 operator_uin = 3;
+ string target_uid = 4;
+ uint64 target_uin = 5;
+ string new_card = 6;
+}
+
+message GroupMemberIncreasedNotice {
+ enum GroupMemberIncreasedType {
+ APPROVE = 0;
+ INVITE = 1;
+ }
+
+ uint64 group_id = 1;
+ string operator_uid = 2;
+ uint64 operator_uin = 3;
+ string target_uid = 4;
+ uint64 target_uin = 5;
+ GroupMemberIncreasedType type = 6;
+}
+
+message GroupMemberDecreasedNotice {
+ enum GroupMemberDecreasedType {
+ LEAVE = 0;
+ KICK = 1;
+ KICK_ME = 2;
+ }
+
+ uint64 group_id = 1;
+ optional string operator_uid = 2; // 当 type 不为 LEAVE 时提供
+ optional uint64 operator_uin = 3;
+ optional string target_uid = 4; // 当 type 不为 KICK_ME 时提供
+ optional uint64 target_uin = 5;
+ GroupMemberDecreasedType type = 6;
+}
+
+message GroupAdminChangedNotice {
+ uint64 group_id = 1;
+ string target_uid = 4;
+ uint64 target_uin = 5;
+ bool is_admin = 6;
+}
+
+message GroupMemberBanNotice {
+ enum GroupMemberBanType {
+ LIFT_BAN = 0;
+ BAN = 1;
+ }
+
+ uint64 group_id = 1;
+ string operator_uid = 2;
+ uint64 operator_uin = 3;
+ string target_uid = 4;
+ uint64 target_uin = 5;
+ int32 duration = 6;
+ GroupMemberBanType type = 7;
+}
+
+message GroupRecallNotice {
+ uint64 group_id = 1;
+ string message_id = 2;
+ string tip_text = 3;
+ string operator_uid = 4;
+ uint64 operator_uin = 5;
+ string target_uid = 6;
+ uint64 target_uin = 7;
+ uint64 message_seq = 8;
+}
+
+message GroupSignInNotice {
+ uint64 group_id = 1;
+ string target_uid = 2;
+ uint64 target_uin = 3;
+ string action = 4;
+ string suffix = 5;
+ string rank_image = 6;
+}
+
+message GroupWholeBanNotice {
+ uint64 group_id = 1;
+ string operator_uid = 2;
+ uint64 operator_uin = 3;
+ bool is_ban = 4;
+}
+
+message FriendFileUploadedNotice {
+ string operator_uid = 1;
+ uint64 operator_uin = 2;
+ string file_id = 3;
+ string file_sub_id = 4;
+ string file_name = 5;
+ uint64 file_size = 6;
+ uint32 expire_time = 7;
+ string url = 8;
+}
+
+message GroupFileUploadedNotice {
+ uint64 group_id = 1;
+ string operator_uid = 2;
+ uint64 operator_uin = 3;
+ string file_id = 4;
+ string file_sub_id = 5;
+ string file_name = 6;
+ uint64 file_size = 7;
+ uint32 expire_time = 8;
+ int32 biz = 9;
+ string url = 10;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/event/request_data.proto b/Lagrange.Kritor/Protos/event/request_data.proto
new file mode 100644
index 000000000..329056667
--- /dev/null
+++ b/Lagrange.Kritor/Protos/event/request_data.proto
@@ -0,0 +1,32 @@
+syntax = "proto3";
+
+package kritor.event;
+
+option csharp_namespace = "Kritor.Event";
+option java_multiple_files = true;
+option java_package = "io.kritor.event";
+option go_package = "grpc/kritor/event";
+
+message FriendApplyRequest {
+ string applier_uid = 1;
+ uint64 applier_uin = 2;
+ string flag = 3;
+ string message = 4;
+}
+
+message GroupApplyRequest {
+ uint64 group_id = 1;
+ string applier_uid = 2;
+ uint64 applier_uin = 3;
+ string inviter_uid = 4;
+ uint64 inviter_uin = 5;
+ string reason = 6;
+ string flag = 7;
+}
+
+message InvitedJoinGroupRequest {
+ uint64 group_id = 1;
+ string inviter_uid = 2;
+ uint64 inviter_uin = 3;
+ string flag = 4;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/file/file_data.proto b/Lagrange.Kritor/Protos/file/file_data.proto
new file mode 100644
index 000000000..6632a2f1d
--- /dev/null
+++ b/Lagrange.Kritor/Protos/file/file_data.proto
@@ -0,0 +1,33 @@
+syntax = "proto3";
+
+package kritor.file;
+
+option csharp_namespace = "Kritor.File";
+option java_multiple_files = true;
+option java_package = "io.kritor.file";
+option go_package = "grpc/kritor/file";
+
+message File {
+ string file_id = 1;
+ string file_name = 2;
+ uint64 file_size = 3;
+ int32 bus_id = 4;
+ uint32 upload_time = 5;
+ uint32 dead_time = 6;
+ uint32 modify_time = 7;
+ uint32 download_times = 8;
+ uint64 uploader = 9;
+ string uploader_name = 10;
+ string sha = 11;
+ string sha3 = 12;
+ string md5 = 13;
+}
+
+message Folder {
+ string folder_id = 1;
+ string folder_name = 2;
+ uint32 total_file_count = 3;
+ uint32 create_time = 4;
+ uint64 creator = 5;
+ string creator_name = 6;
+}
diff --git a/Lagrange.Kritor/Protos/file/group_file.proto b/Lagrange.Kritor/Protos/file/group_file.proto
new file mode 100644
index 000000000..cdbebf07a
--- /dev/null
+++ b/Lagrange.Kritor/Protos/file/group_file.proto
@@ -0,0 +1,93 @@
+syntax = "proto3";
+
+package kritor.file;
+
+option csharp_namespace = "Kritor.File";
+option java_multiple_files = true;
+option java_package = "io.kritor.file";
+option go_package = "grpc/kritor/file";
+
+import "Protos/file/file_data.proto";
+
+service GroupFileService {
+ rpc CreateFolder(CreateFolderRequest) returns (CreateFolderResponse); // 创建文件夹
+ rpc RenameFolder(RenameFolderRequest) returns (RenameFolderResponse); // 重命名文件夹
+ rpc DeleteFolder(DeleteFolderRequest) returns (DeleteFolderResponse); // 删除文件夹
+
+ rpc UploadFile(UploadFileRequest) returns (UploadFileResponse); // 删除文件
+ rpc DeleteFile(DeleteFileRequest) returns (DeleteFileResponse); // 删除文件
+
+ rpc GetFileSystemInfo(GetFileSystemInfoRequest) returns (GetFileSystemInfoResponse); // 获取文件系统信息
+ rpc GetFileList(GetFileListRequest) returns (GetFileListResponse); // 获取文件夹下文件
+}
+
+message CreateFolderRequest {
+ uint64 group_id = 1; // 群号
+ string name = 2; // 文件夹名
+}
+
+message CreateFolderResponse {
+ string id = 1; // 文件夹id
+ uint64 used_space = 2; // 已使用空间
+}
+
+message RenameFolderRequest {
+ uint64 group_id = 1; // 群号
+ string folder_id = 2; // 文件夹id
+ string name = 3; // 文件夹名
+}
+
+message RenameFolderResponse {
+}
+
+message DeleteFolderRequest {
+ uint64 group_id = 1; // 群号
+ string folder_id = 2; // 文件夹id
+}
+
+message DeleteFolderResponse {
+}
+
+message UploadFileRequest {
+ uint64 group_id = 1; // 群号
+ oneof data {
+ bytes file = 2; // 文件内容
+ string file_name = 3; // 文件文件名
+ string file_path = 4; // 文件绝对路径
+ string file_url = 5; // 文件下载地址
+ }
+}
+
+message UploadFileResponse {
+
+}
+
+message DeleteFileRequest {
+ uint64 group_id = 1; // 群号
+ string file_id = 2; // 文件id
+ int32 bus_id = 3; // 文件类型ID
+}
+
+message DeleteFileResponse {
+}
+
+message GetFileSystemInfoRequest {
+ uint64 group_id = 1; // 群号
+}
+
+message GetFileSystemInfoResponse {
+ uint32 file_count = 1; // 文件数量
+ uint32 total_count = 2; // 文件数量上限
+ uint32 used_space = 3; // 已使用空间
+ uint32 total_space = 4; // 空间上限
+}
+
+message GetFileListRequest {
+ uint64 group_id = 1; // 群号
+ optional string folder_id = 2; // 文件夹id 空则为根目录
+}
+
+message GetFileListResponse {
+ repeated File files = 1;
+ repeated Folder folders = 2;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/friend/firend_data.proto b/Lagrange.Kritor/Protos/friend/firend_data.proto
new file mode 100644
index 000000000..9363be6d6
--- /dev/null
+++ b/Lagrange.Kritor/Protos/friend/firend_data.proto
@@ -0,0 +1,54 @@
+syntax = "proto3";
+
+package kritor.friend;
+
+option csharp_namespace = "Kritor.Friend";
+option java_multiple_files = true;
+option java_package = "io.kritor.friend";
+option go_package = "grpc/kritor/friend";
+
+message FriendInfo {
+ string uid = 1; // uid 'u_*********'
+ uint64 uin = 2; // qq 如果没有可不提供
+ string qid = 3; // qid 用户自定义的qid 如若没有则为空
+
+ string nick = 4; // 名称
+ string remark = 5; // 备注
+ uint32 level = 6; // 等级
+ uint32 age = 7; // 年龄
+ uint32 vote_cnt = 8; // 赞数量
+ int32 gender = 9; // 性别 可不提供
+ int32 group_id = 10; // 好友分组id
+
+
+ optional ExtInfo ext = 99; // 扩展信息,根据协议平台提供的扩展信息
+}
+
+message ProfileCard {
+ string uid = 1;
+ uint64 uin = 2;
+ string qid = 3;
+
+ string nick = 4;
+ optional string remark = 5;
+ uint32 level = 6;
+ optional uint64 birthday = 7;
+ uint32 login_day = 8; // 登录天数
+ uint32 vote_cnt = 9; // 点赞数
+
+ /* 以下字段可以不实现 */
+ optional bool is_school_verified = 51;
+ optional ExtInfo ext = 99; // 扩展信息,根据协议平台提供的扩展信息
+}
+
+// 通用好友信息扩展字段
+// 所有第三方协议分发扩展字段,
+// 必须基于本字段修改,
+// 并保存定制的副本到本仓库特定路径!!
+message ExtInfo {
+ optional bool big_vip = 1; // 大会员
+ optional bool hollywood_vip = 2; // 好莱坞/腾讯视频会员
+ optional bool qq_vip = 3; // QQ会员
+ optional bool super_vip = 4; // QQ超级会员
+ optional bool voted = 5; // 是否已经赞过
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/friend/friend.proto b/Lagrange.Kritor/Protos/friend/friend.proto
new file mode 100644
index 000000000..d8070496b
--- /dev/null
+++ b/Lagrange.Kritor/Protos/friend/friend.proto
@@ -0,0 +1,101 @@
+syntax = "proto3";
+
+package kritor.friend;
+
+option csharp_namespace = "Kritor.Friend";
+option java_multiple_files = true;
+option java_package = "io.kritor.friend";
+option go_package = "grpc/kritor/friend";
+
+import "Protos/friend/firend_data.proto";
+
+service FriendService {
+ rpc GetFriendList (GetFriendListRequest) returns (GetFriendListResponse); // 获取好友列表
+
+ rpc GetFriendProfileCard(GetFriendProfileCardRequest) returns (GetFriendProfileCardResponse); // 获取名片(限好友)
+ rpc GetStrangerProfileCard(GetStrangerProfileCardRequest) returns (GetStrangerProfileCardResponse); // 获取陌生人信息
+ rpc SetProfileCard(SetProfileCardRequest) returns (SetProfileCardResponse); // 设置自己的名片
+
+ rpc IsBlackListUser(IsBlackListUserRequest) returns (IsBlackListUserResponse); // 是否是黑名单用户
+ rpc VoteUser(VoteUserRequest) returns (VoteUserResponse); // 点赞好友
+
+ rpc GetUidByUin(GetUidRequest) returns (GetUidResponse); // 获取uid
+ rpc GetUinByUid(GetUinByUidRequest) returns (GetUinByUidResponse); // 获取uin
+}
+
+message GetFriendListRequest {
+ optional bool refresh = 1; // 是否刷新好友列表
+}
+
+message GetFriendListResponse {
+ repeated FriendInfo friends_info = 1;
+}
+
+message GetFriendProfileCardRequest {
+ repeated string target_uids = 1;
+ repeated uint64 target_uins = 2;
+}
+
+message GetFriendProfileCardResponse {
+ repeated ProfileCard friends_profile_card = 1;
+}
+
+message GetStrangerProfileCardRequest {
+ repeated string target_uids = 1;
+ repeated uint64 target_uins = 2;
+}
+
+message GetStrangerProfileCardResponse {
+ repeated ProfileCard strangers_profile_card = 1;
+}
+
+message SetProfileCardRequest {
+ optional string nick_name = 1;
+ optional string company = 2;
+ optional string email = 3;
+ optional string college = 4;
+ optional string personal_note = 5;
+ optional uint32 birthday = 6;
+ optional uint32 age = 7;
+}
+
+message SetProfileCardResponse {
+}
+
+message GetUidRequest {
+ repeated uint64 target_uins = 1;
+}
+
+message GetUidResponse {
+ map uid_map = 1;
+}
+
+message GetUinByUidRequest {
+ repeated string target_uids = 1;
+}
+
+message GetUinByUidResponse {
+ map uin_map = 1;
+}
+
+message IsBlackListUserRequest {
+ oneof target {
+ string target_uid = 1;
+ uint64 target_uin = 2;
+ }
+}
+
+message IsBlackListUserResponse {
+ bool is_black_list_user = 1;
+}
+
+message VoteUserRequest {
+ oneof target {
+ string target_uid = 1;
+ uint64 target_uin = 2;
+ }
+ uint32 vote_count = 3;
+}
+
+message VoteUserResponse {
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/group/group.proto b/Lagrange.Kritor/Protos/group/group.proto
new file mode 100644
index 000000000..60dc828f8
--- /dev/null
+++ b/Lagrange.Kritor/Protos/group/group.proto
@@ -0,0 +1,210 @@
+syntax = "proto3";
+
+package kritor.group;
+
+option csharp_namespace = "Kritor.Group";
+option java_multiple_files = true;
+option java_package = "io.kritor.group";
+option go_package = "grpc/kritor/group";
+
+import "Protos/group/group_data.proto";
+
+service GroupService {
+ rpc BanMember(BanMemberRequest) returns (BanMemberResponse); // 禁言用户
+ rpc PokeMember(PokeMemberRequest) returns (PokeMemberResponse); // 戳一戳用户
+ rpc KickMember(KickMemberRequest) returns (KickMemberResponse); // 踢出用户
+ rpc LeaveGroup(LeaveGroupRequest) returns (LeaveGroupResponse); // 退出群组
+ rpc ModifyMemberCard(ModifyMemberCardRequest) returns (ModifyMemberCardResponse); // 修改群名片
+ rpc ModifyGroupName(ModifyGroupNameRequest) returns (ModifyGroupNameResponse); // 修改群名称
+ rpc ModifyGroupRemark(ModifyGroupRemarkRequest) returns (ModifyGroupRemarkResponse); // 修改群备注
+ rpc SetGroupAdmin(SetGroupAdminRequest) returns (SetGroupAdminResponse); // 设置群管理员
+ rpc SetGroupUniqueTitle(SetGroupUniqueTitleRequest) returns (SetGroupUniqueTitleResponse); // 设置群头衔
+ rpc SetGroupWholeBan(SetGroupWholeBanRequest) returns (SetGroupWholeBanResponse); // 设置全员禁言
+
+ rpc GetGroupInfo(GetGroupInfoRequest) returns (GetGroupInfoResponse); // 获取群信息
+ rpc GetGroupList(GetGroupListRequest) returns (GetGroupListResponse); // 获取群列表
+ rpc GetGroupMemberInfo(GetGroupMemberInfoRequest) returns (GetGroupMemberInfoResponse); // 获取群成员信息
+ rpc GetGroupMemberList(GetGroupMemberListRequest) returns (GetGroupMemberListResponse); // 获取群成员列表
+
+ rpc GetProhibitedUserList(GetProhibitedUserListRequest) returns (GetProhibitedUserListResponse); // 获取禁言用户列表
+ rpc GetRemainCountAtAll(GetRemainCountAtAllRequest) returns (GetRemainCountAtAllResponse); // 获取艾特全体成员剩余次数
+ rpc GetNotJoinedGroupInfo(GetNotJoinedGroupInfoRequest) returns (GetNotJoinedGroupInfoResponse); // 获取未加入群组信息
+ rpc GetGroupHonor(GetGroupHonorRequest) returns (GetGroupHonorResponse); // 获取群荣誉信息
+}
+
+message BanMemberRequest {
+ uint64 group_id = 1; // 群组ID
+ oneof target{
+ string target_uid = 2; // 被禁言目标uid
+ uint64 target_uin = 3; // 被禁言目标uin
+ }
+ uint32 duration = 4; // 单位:秒
+}
+
+message BanMemberResponse {
+ uint64 group_id = 1; // 群组ID
+}
+
+message PokeMemberRequest {
+ uint64 group_id = 1; // 群组ID
+ oneof target{
+ string target_uid = 2; // 被戳一戳目标uid
+ uint64 target_uin = 3; // 被戳一戳目标uin
+ }
+}
+
+message PokeMemberResponse {
+}
+
+message KickMemberRequest {
+ uint64 group_id = 1; // 群组ID
+ oneof target{
+ string target_uid = 2; // 被踢出目标uid
+ uint64 target_uin = 3; // 被踢出目标uin
+ }
+ optional bool reject_add_request = 6; // 是否拒绝再次申请 默认false
+ optional string kick_reason = 5; // 踢出原因,可选
+}
+
+message KickMemberResponse {
+}
+
+message LeaveGroupRequest {
+ uint64 group_id = 1; // 群组ID
+}
+
+message LeaveGroupResponse {
+}
+
+message ModifyMemberCardRequest {
+ uint64 group_id = 1; // 群组ID
+ oneof target{
+ string target_uid = 2; // 目标uid
+ uint64 target_uin = 3; // 目标uin
+ }
+ string card = 4; // 新的群名片
+}
+
+message ModifyMemberCardResponse {
+}
+
+message ModifyGroupNameRequest {
+ uint64 group_id = 1; // 群组ID
+ string group_name = 2; // 新的群名称
+}
+
+message ModifyGroupNameResponse {
+}
+
+message ModifyGroupRemarkRequest {
+ uint64 group_id = 1; // 群组ID
+ string remark = 2; // 新的群备注
+}
+
+message ModifyGroupRemarkResponse {
+}
+
+message SetGroupAdminRequest {
+ uint64 group_id = 1; // 群组ID
+ oneof target{
+ string target_uid = 2; // 目标uid
+ uint64 target_uin = 3; // 目标uin
+ }
+ bool is_admin = 4; // 是否设置为管理员
+}
+
+message SetGroupAdminResponse {
+}
+
+message SetGroupUniqueTitleRequest {
+ uint64 group_id = 1; // 群组ID
+ oneof target{
+ string target_uid = 2; // 目标uid
+ uint64 target_uin = 3; // 目标uin
+ }
+ string unique_title = 4; // 新的群头衔
+}
+
+message SetGroupUniqueTitleResponse {
+}
+
+message SetGroupWholeBanRequest {
+ uint64 group_id = 1; // 群组ID
+ bool is_ban = 2; // 是否全员禁言
+}
+
+message SetGroupWholeBanResponse {
+}
+
+message GetGroupInfoRequest {
+ uint64 group_id = 1; // 群组ID
+}
+
+message GetGroupInfoResponse {
+ GroupInfo group_info = 1; // 群组信息
+}
+
+message GetGroupListRequest {
+ optional bool refresh = 1; // 是否刷新缓存
+}
+
+message GetGroupListResponse {
+ repeated GroupInfo groups_info = 1; // 群组信息
+}
+
+message GetGroupMemberInfoRequest {
+ uint64 group_id = 1; // 群组ID
+ oneof target{
+ string target_uid = 2; // 获取目标uid
+ uint64 target_uin = 3; // 获取目标uin
+ }
+ optional bool refresh = 4; // 是否刷新缓存
+}
+
+message GetGroupMemberInfoResponse {
+ GroupMemberInfo group_member_info = 1; // 群成员信息
+}
+
+message GetGroupMemberListRequest {
+ uint64 group_id = 1; // 群组ID
+ optional bool refresh = 2; // 是否刷新缓存
+}
+
+message GetGroupMemberListResponse {
+ repeated GroupMemberInfo group_members_info = 1; // 群成员信息
+}
+
+message GetProhibitedUserListRequest {
+ uint64 group_id = 1; // 群组ID
+}
+
+message GetProhibitedUserListResponse {
+ repeated ProhibitedUserInfo prohibited_users_info = 1; // 禁言用户信息
+}
+
+message GetRemainCountAtAllRequest {
+ uint64 group_id = 1; // 群组ID
+}
+
+message GetRemainCountAtAllResponse {
+ bool access_at_all = 1;
+ uint32 remain_count_for_group = 2; // 剩余次数对于全群
+ uint32 remain_count_for_self = 3; // 剩余次数对于自己
+}
+
+message GetNotJoinedGroupInfoRequest {
+ uint64 group_id = 1; // 群号
+}
+
+message GetNotJoinedGroupInfoResponse {
+ NotJoinedGroupInfo group_info = 1; // 未加入群组信息
+}
+
+message GetGroupHonorRequest {
+ uint64 group_id = 1; // 群号
+ optional bool refresh = 2; // 是否刷新缓存
+}
+
+message GetGroupHonorResponse {
+ repeated GroupHonorInfo group_honors_info = 1; // 群荣誉信息
+}
diff --git a/Lagrange.Kritor/Protos/group/group_data.proto b/Lagrange.Kritor/Protos/group/group_data.proto
new file mode 100644
index 000000000..40fc24d31
--- /dev/null
+++ b/Lagrange.Kritor/Protos/group/group_data.proto
@@ -0,0 +1,75 @@
+syntax = "proto3";
+
+package kritor.group;
+
+option csharp_namespace = "Kritor.Group";
+option java_multiple_files = true;
+option java_package = "io.kritor.group";
+option go_package = "grpc/kritor/group";
+
+message GroupInfo {
+ uint64 group_id = 1;
+ string group_name = 2;
+ string group_remark = 3;
+ uint64 owner = 4;
+ repeated uint64 admins = 5;
+ uint32 max_member_count = 6;
+ uint32 member_count = 7;
+ uint64 group_uin = 10;
+}
+
+message NotJoinedGroupInfo {
+ uint64 group_id = 1;
+ uint32 max_member_count = 2;
+ uint32 member_count = 3;
+ string group_name = 4;
+ string group_desc = 5;
+ uint64 owner = 6;
+ uint32 create_time = 7;
+
+ uint32 group_flag = 8; // 群聊类型什么的都在这里,如果获取不到可以不实现
+ uint32 group_flag_ext = 9; // 扩展群聊类型
+}
+
+message ProhibitedUserInfo {
+ string uid = 1;
+ uint64 uin = 2;
+ uint32 prohibited_time = 3;
+}
+
+message GroupHonorInfo {
+ string uid = 1; // 荣誉成员uid
+ uint64 uin = 2; // 荣誉成员uin
+ string nick = 3; // 荣誉成员昵称
+ string honor_name = 4; // 荣誉名称
+ string avatar = 5; // 荣誉图标url
+ uint32 id = 6; // 荣誉id
+ string description = 7; // 荣誉描述
+}
+
+enum MemberRole {
+ ADMIN = 0;
+ MEMBER = 1;
+ OWNER = 2;
+ STRANGER = 3;
+}
+
+message GroupMemberInfo {
+ string uid = 1;
+ uint64 uin = 2;
+ string nick = 3;
+ uint32 age = 4;
+ string unique_title = 5;
+ uint32 unique_title_expire_time = 6;
+ string card = 7;
+ uint64 join_time = 8;
+ uint64 last_active_time = 9;
+ uint32 level = 10;
+ uint64 shut_up_timestamp = 11;
+
+ optional uint32 distance = 100;
+ repeated uint32 honors = 101;
+ optional bool unfriendly = 102;
+ optional bool card_changeable = 103;
+}
+
diff --git a/Lagrange.Kritor/Protos/message/message.proto b/Lagrange.Kritor/Protos/message/message.proto
new file mode 100644
index 000000000..2e0eafa05
--- /dev/null
+++ b/Lagrange.Kritor/Protos/message/message.proto
@@ -0,0 +1,161 @@
+syntax = "proto3";
+
+package kritor.message;
+
+option csharp_namespace = "Kritor.Message";
+option java_multiple_files = true;
+option java_package = "io.kritor.message";
+option go_package = "grpc/kritor/message";
+
+import "Protos/common/contact.proto";
+import "Protos/common/message_data.proto";
+import "Protos/common/message_element.proto";
+
+service MessageService {
+ rpc SendMessage(SendMessageRequest) returns (SendMessageResponse); // 发送消息
+ rpc SendMessageByResId(SendMessageByResIdRequest) returns (SendMessageByResIdResponse); // 通过资源ID发送消息(转发消息
+ rpc SetMessageReaded(SetMessageReadRequest) returns (SetMessageReadResponse); // 清空本地聊天记录
+ rpc RecallMessage(RecallMessageRequest) returns (RecallMessageResponse); // 撤回消息
+ rpc ReactMessageWithEmoji(ReactMessageWithEmojiRequest) returns (ReactMessageWithEmojiResponse); // 设置消息评论表情
+
+ rpc GetMessage(GetMessageRequest) returns (GetMessageResponse); // 获取消息
+ rpc GetMessageBySeq(GetMessageBySeqRequest) returns (GetMessageBySeqResponse); // 获取消息
+ rpc GetHistoryMessage(GetHistoryMessageRequest) returns (GetHistoryMessageResponse); // 获取历史消息
+ rpc GetHistoryMessageBySeq(GetHistoryMessageBySeqRequest) returns (GetHistoryMessageBySeqResponse); // 获取历史消息
+
+ rpc UploadForwardMessage(UploadForwardMessageRequest) returns (UploadForwardMessageResponse); // 上传合并转发消息
+ rpc DownloadForwardMessage(DownloadForwardMessageRequest) returns (DownloadForwardMessageResponse); // 下载合并转发消息
+
+ rpc GetEssenceMessageList(GetEssenceMessageListRequest) returns (GetEssenceMessageListResponse); // 获取精华消息
+ rpc SetEssenceMessage(SetEssenceMessageRequest) returns (SetEssenceMessageResponse); // 设置精华消息
+ rpc DeleteEssenceMessage(DeleteEssenceMessageRequest) returns (DeleteEssenceMessageResponse); // 删除精华消息
+}
+
+message SendMessageRequest {
+ kritor.common.Contact contact = 1; // 发送目标
+ repeated kritor.common.Element elements = 2; // 发的什么东西
+ optional uint32 retry_count = 3; // 重试次数
+}
+
+message SendMessageResponse {
+ string message_id = 1; // 发送成功后的消息ID
+ uint32 message_time = 2; // 发送时间
+}
+
+message SendMessageByResIdRequest {
+ kritor.common.Contact contact = 1; // 发送目标
+ string res_id = 2; // 资源ID
+ optional uint32 retry_count = 3; // 重试次数
+}
+
+message SendMessageByResIdResponse {
+ string message_id = 1; // 发送成功后的消息ID
+ uint32 message_time = 2; // 发送时间
+}
+
+message SetMessageReadRequest {
+ kritor.common.Contact contact = 1; // 要清空的目标
+}
+
+message SetMessageReadResponse {
+}
+
+message RecallMessageRequest {
+ kritor.common.Contact contact = 1; // 要撤回的目标,私聊则为对方,而不是写自己
+ string message_id = 2; // 要撤回的消息ID,消息id固有格式:前32bit为时间戳,后32bit为扩展字段,可携带聊天类型等各种信息
+}
+
+message RecallMessageResponse {
+}
+
+message ReactMessageWithEmojiRequest {
+ kritor.common.Contact contact = 1;
+ string message_id = 2; // 要设置的消息ID
+ uint32 face_id = 3; // 表情ID
+ bool is_set = 4; // 是否是评论,如果是false,则为撤销
+}
+
+message ReactMessageWithEmojiResponse {
+}
+
+message GetMessageRequest {
+ kritor.common.Contact contact = 1; // 要获取的目标
+ string message_id = 2; // 要获取的消息ID
+}
+
+message GetMessageResponse {
+ kritor.common.PushMessageBody message = 1; // 获取到的消息
+}
+
+message GetMessageBySeqRequest {
+ kritor.common.Contact contact = 1; // 要获取的目标
+ uint64 message_seq = 2; // 要获取的消息序号
+}
+
+message GetMessageBySeqResponse {
+ kritor.common.PushMessageBody message = 1; // 获取到的消息
+}
+
+message GetHistoryMessageRequest {
+ kritor.common.Contact contact = 1; // 要获取的目标
+ optional string start_message_id = 2; // 起始消息ID 默认最新一条开始
+ optional uint32 count = 3; // 获取数量 默认10
+}
+
+message GetHistoryMessageResponse {
+ repeated kritor.common.PushMessageBody messages = 1; // 获取到的消息
+}
+
+message GetHistoryMessageBySeqRequest {
+ kritor.common.Contact contact = 1; // 要获取的目标
+ optional uint64 start_message_seq = 2; // 起始消息ID 默认最新一条开始
+ optional uint32 count = 3; // 获取数量 默认10
+}
+
+message GetHistoryMessageBySeqResponse {
+ repeated kritor.common.PushMessageBody messages = 1; // 获取到的消息
+}
+
+message UploadForwardMessageRequest {
+ kritor.common.Contact contact = 1;
+ repeated kritor.common.ForwardMessageBody messages = 2;
+ optional uint32 retry_count = 3;
+}
+
+message UploadForwardMessageResponse {
+ string res_id = 1;
+}
+
+message DownloadForwardMessageRequest {
+ string res_id = 1; // 资源ID
+}
+
+message DownloadForwardMessageResponse {
+ repeated kritor.common.PushMessageBody messages = 1; // 获取到的消息
+}
+
+message GetEssenceMessageListRequest {
+ uint64 group_id = 1;
+ uint32 page = 2;
+ uint32 page_size = 3;
+}
+
+message GetEssenceMessageListResponse {
+ repeated kritor.common.EssenceMessageBody messages = 1;
+}
+
+message SetEssenceMessageRequest {
+ uint64 group_id = 1;
+ string message_id = 2; // 要设置为精华消息的消息ID
+}
+
+message SetEssenceMessageResponse {
+}
+
+message DeleteEssenceMessageRequest {
+ uint64 group_id = 1;
+ string message_id = 2; // 要删除的消息ID
+}
+
+message DeleteEssenceMessageResponse {
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/reverse/reverse.proto b/Lagrange.Kritor/Protos/reverse/reverse.proto
new file mode 100644
index 000000000..6b8cfe03d
--- /dev/null
+++ b/Lagrange.Kritor/Protos/reverse/reverse.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package kritor.reverse;
+
+option csharp_namespace = "Kritor.Reverse";
+option java_multiple_files = true;
+option java_package = "io.kritor.reverse";
+option go_package = "grpc/kritor/reverse";
+
+import "Protos/common/request.proto";
+
+service ReverseService {
+ rpc ReverseStream(stream kritor.common.Response) returns (stream kritor.common.Request);
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Protos/web/web.proto b/Lagrange.Kritor/Protos/web/web.proto
new file mode 100644
index 000000000..bd376a185
--- /dev/null
+++ b/Lagrange.Kritor/Protos/web/web.proto
@@ -0,0 +1,50 @@
+syntax = "proto3";
+
+package kritor.web;
+
+option csharp_namespace = "Kritor.Web";
+option java_multiple_files = true;
+option java_package = "io.kritor.web";
+option go_package = "grpc/kritor/web";
+
+service WebService {
+ rpc GetCookies(GetCookiesRequest) returns (GetCookiesResponse); // 获取通用cookie
+ rpc GetCredentials(GetCredentialsRequest) returns (GetCredentialsResponse); // 获取bkn参数与cookie
+ rpc GetCSRFToken(GetCSRFTokenRequest) returns (GetCSRFTokenResponse); // 获取bkn
+ rpc GetHttpCookies(GetHttpCookiesRequest) returns (GetHttpCookiesResponse); // 获取http请求的cookie
+}
+
+message GetCookiesRequest {
+ optional string domain = 1; // The domain to get cookies from
+}
+
+message GetCookiesResponse {
+ string cookie = 1;
+}
+
+message GetCredentialsRequest {
+ optional string domain = 1; // The domain to get credentials from
+}
+
+message GetCredentialsResponse {
+ string bkn = 1;
+ string cookie = 2;
+}
+
+message GetCSRFTokenRequest {
+ optional string domain = 1; // The domain to get the CSRF token from
+}
+
+message GetCSRFTokenResponse {
+ string bkn = 1;
+}
+
+message GetHttpCookiesRequest {
+ string appid = 1;
+ string daid = 2;
+ string jump_url = 3;
+}
+
+message GetHttpCookiesResponse {
+ string cookie = 1;
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/AuthService.cs b/Lagrange.Kritor/Services/AuthService.cs
new file mode 100644
index 000000000..a4c662fc4
--- /dev/null
+++ b/Lagrange.Kritor/Services/AuthService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class AuthService : global::Kritor.Authentication.AuthenticationService.AuthenticationServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/CoreService.cs b/Lagrange.Kritor/Services/CoreService.cs
new file mode 100644
index 000000000..faddb67fb
--- /dev/null
+++ b/Lagrange.Kritor/Services/CoreService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class CoreService : global::Kritor.Core.CoreService.CoreServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/CustomizationService.cs b/Lagrange.Kritor/Services/CustomizationService.cs
new file mode 100644
index 000000000..f768fd593
--- /dev/null
+++ b/Lagrange.Kritor/Services/CustomizationService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class CustomizationService : global::Kritor.Customization.CustomizationService.CustomizationServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/EventService.cs b/Lagrange.Kritor/Services/EventService.cs
new file mode 100644
index 000000000..201111983
--- /dev/null
+++ b/Lagrange.Kritor/Services/EventService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class EventService : global::Kritor.Event.EventService.EventServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/FriendService.cs b/Lagrange.Kritor/Services/FriendService.cs
new file mode 100644
index 000000000..ce418bca5
--- /dev/null
+++ b/Lagrange.Kritor/Services/FriendService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class FriendService : global::Kritor.Friend.FriendService.FriendServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/GroupFileService.cs b/Lagrange.Kritor/Services/GroupFileService.cs
new file mode 100644
index 000000000..d919990db
--- /dev/null
+++ b/Lagrange.Kritor/Services/GroupFileService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class GroupFileService : global::Kritor.File.GroupFileService.GroupFileServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/GroupService.cs b/Lagrange.Kritor/Services/GroupService.cs
new file mode 100644
index 000000000..bbf1f7da1
--- /dev/null
+++ b/Lagrange.Kritor/Services/GroupService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class GroupService : global::Kritor.Group.GroupService.GroupServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/MessageService.cs b/Lagrange.Kritor/Services/MessageService.cs
new file mode 100644
index 000000000..558b50f74
--- /dev/null
+++ b/Lagrange.Kritor/Services/MessageService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class MessageService : global::Kritor.Message.MessageService.MessageServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/Services/WebService.cs b/Lagrange.Kritor/Services/WebService.cs
new file mode 100644
index 000000000..798cc6947
--- /dev/null
+++ b/Lagrange.Kritor/Services/WebService.cs
@@ -0,0 +1,6 @@
+namespace Lagrange.Kritor.Services;
+
+public class WebService : global::Kritor.Web.WebService.WebServiceBase
+{
+
+}
\ No newline at end of file
diff --git a/Lagrange.Kritor/appsettings.Development.json b/Lagrange.Kritor/appsettings.Development.json
new file mode 100644
index 000000000..0c208ae91
--- /dev/null
+++ b/Lagrange.Kritor/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/Lagrange.Kritor/appsettings.json b/Lagrange.Kritor/appsettings.json
new file mode 100644
index 000000000..1aef5074f
--- /dev/null
+++ b/Lagrange.Kritor/appsettings.json
@@ -0,0 +1,14 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "Kestrel": {
+ "EndpointDefaults": {
+ "Protocols": "Http2"
+ }
+ }
+}