diff --git a/AGENTS.md b/AGENTS.md index b4267b88..2084e4e8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,6 +31,15 @@ - Redis 只保存当前路由/lease 等热状态,不能作为唯一恢复来源。 - Redis lease 更新必须保持原子性,不能改回非原子的 GET + SET 接管逻辑。 +## Time Rules + +- 全局业务时间统一使用 UTC,不使用服务器所在地、容器本地时区、客户端时区或 IP 推断时区作为结算、统计、刷新和幂等周期的切日来源。 +- 跨服务契约、HTTP 响应、数据库业务事实和 outbox payload 中的时间统一使用 Unix epoch milliseconds,字段名保持 `*_ms`。 +- 统计、账务和列表时间范围统一使用 `[start_ms, end_ms)`:包含开始毫秒,不包含结束毫秒,避免相邻区间重复计算边界记录。 +- 每日任务、自然日刷新和 `task_day` 统一按 UTC 日期计算;不要重新引入 `task_timezone`、`time.Local` 或 `loc=Local`。 +- MySQL DSN 必须使用 `loc=UTC`;Docker/Compose 服务必须保持 `TZ=UTC`,MySQL 必须保持 `--default-time-zone=+00:00`。 +- 如果产品需要用户本地时间展示,只能在展示层或资料/风控元数据中处理;要把它用于业务切日,必须先形成明确产品规则、契约字段和边界测试。 + ## Protocol Rules - 外部 HTTP JSON 入口在 `gateway-service`。 @@ -105,4 +114,5 @@ docker compose down - 房间状态变更必须经过 Room Cell 命令链路。 - 需要恢复的关键动作必须写 command log 或 snapshot,不能只改内存。 - 房间外副作用优先走 outbox,除非是明确的同步主链路依赖。 +- 新增统计、账务、任务刷新或时间范围逻辑时,必须补 UTC 边界测试,至少覆盖开始边界、结束前一毫秒和结束边界。 - 文档只写当前事实和明确约束,不记录“做了什么”的流水账。 diff --git a/README.md b/README.md index eb4f584d..cd301c46 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ HY Voice Room 是语音房后端 monorepo。当前架构不再自研 IM 长连 - `room-service` 是房间业务状态 owner,负责 Room Cell、麦位、房间 presence、本地礼物榜、送礼落房间、snapshot、command log、outbox、Redis lease,以及腾讯云 IM 群组/系统消息桥接。 - `wallet-service` 当前提供 `DebitGift` 送礼扣费语义,余额、流水和幂等记录落 MySQL;`room-service` 的 `SendGift` 同步调用它。 - `user-service` 当前承接登录、三方注册、密码、refresh session、用户主数据、默认短号和临时靓号基础能力。 -- `activity-service` 当前提供活动 gRPC 查询骨架和房间事件 consumer 边界,尚未接入 `room_outbox` 消费主循环。 +- `activity-service` 当前承接每日任务、活动/系统消息基础能力和房间事件 consumer 边界;`room_outbox` 到 activity/audit 的实际消费链路按独立消费位点接入。 +- `cron-service` 当前负责后台调度、任务运行记录,以及通过内部 gRPC 触发 owner service 批处理;它不直接拥有房间、账务、用户或活动业务状态。 - 腾讯云 IM 承担客户端长连接、群消息、公屏、单聊、离线/漫游和全球接入能力;本仓库不再部署 `im-service`。 - 多 App 共用同一套后端服务,入口由 `gateway-service` 通过包名或 `app_code` 解析租户;所有业务库表按 `app_code` 隔离,设计细节见 `docs/multi-app-tenant-architecture.md`。 @@ -23,6 +24,16 @@ HY Voice Room 是语音房后端 monorepo。当前架构不再自研 IM 长连 - 服务内部调用:gRPC + protobuf,契约在独立 Go module `api`,业务代码通过 `hyapp.local/api/proto/...` 引用生成包。 - 房间外事件:protobuf outbox,当前先落 MySQL。 +## Time Model + +项目全局时间模型固定为 UTC + epoch milliseconds: + +- 跨服务、数据库和 HTTP/gRPC 响应里的业务时间统一使用 Unix epoch milliseconds,字段名保持 `*_ms`,例如 `created_at_ms`、`expire_at_ms`、`start_at_ms`、`end_at_ms`、`next_refresh_at_ms`。 +- 后端业务自然日统一按 UTC 切日。每日任务的 `task_day` 是 UTC `YYYY-MM-DD`,`next_refresh_at_ms` 是下一次 UTC 00:00:00 的毫秒时间戳。 +- 统计和账务时间范围统一使用 `[start_ms, end_ms)`,也就是包含开始、不包含结束。查询“昨天充值多少”时,调用方必须先把“昨天”转换成明确的 UTC 毫秒范围,再交给后端查询。 +- MySQL DSN 必须使用 `loc=UTC`。Docker 环境设置 `TZ=UTC`,MySQL 使用 `--default-time-zone=+00:00`,避免依赖服务器所在地或容器本地时区。 +- 用户所在时区、设备时区或 IP 推断时区只能用于展示、风控或资料字段;不能作为结算、统计、任务刷新和幂等周期的业务切日来源。 + ## Ports 本地和 Docker 编排统一使用 `13xxx` 端口: @@ -34,6 +45,7 @@ HY Voice Room 是语音房后端 monorepo。当前架构不再自研 IM 长连 | `wallet-service` | `13004` | gRPC | | `user-service` | `13005` | gRPC | | `activity-service` | `13006` | gRPC | +| `cron-service` | `13007` | gRPC | | MySQL | `23306 -> 3306` | local Docker only | | Redis | `13379 -> 6379` | local Docker only | @@ -45,7 +57,7 @@ Use Docker for local and test environments: make up ``` -Service aliases: `gs/gateway`, `rs/room`, `ws/wallet`, `us/user`, `as/activity`, `mysql`, `redis`. +Service aliases: `gs/gateway`, `rs/room`, `ws/wallet`, `us/user`, `as/activity`, `cs/cron`, `mysql`, `redis`, plus full service names. Common commands: @@ -62,7 +74,7 @@ make down `make admin-up` 会先启动后台本地依赖 MySQL、Redis 和 `user-service`,再以前台进程启动 `server/admin`。依赖已经存在时,可以直接运行 `make admin`。 -For direct host execution, each service reads its own `services//configs/config.yaml`; `room-service`、`user-service`、`wallet-service` 和 `activity-service` 都要求 MySQL 可用。 +For direct host execution, each service reads its own `services//configs/config.yaml`; `room-service`、`user-service`、`wallet-service`、`activity-service` 和 `cron-service` 都要求 MySQL 可用。 ## Tencent IM @@ -117,7 +129,8 @@ MySQL 是本地和线上运行的持久化底座: - `room-service`: `hyapp_room`,保存 room meta、snapshot、command log 和 outbox,业务行按 `app_code` 隔离。 - `user-service`: `hyapp_user`,保存 `apps` 注册表、用户主数据、注册资料快照、登录身份、session、默认短号、靓号租约和 host 关系事实,业务行按 `app_code` 隔离。 - `wallet-service`: `hyapp_wallet`,保存余额、账务流水、礼物价格和扣费幂等记录,业务行按 `app_code` 隔离。 -- `activity-service`: `hyapp_activity`,保存活动状态、事件消费幂等和 activity outbox,业务行按 `app_code` 隔离。 +- `activity-service`: `hyapp_activity`,保存任务定义、任务进度、奖励领取、活动状态、事件消费幂等和 activity outbox,业务行按 `app_code` 隔离。 +- `cron-service`: `hyapp_cron`,保存后台任务定义、运行记录和调度锁;实际业务批处理仍由各 owner service 执行。 - `hyapp_admin`: 后台管理后端独立库,只保存后台账号、权限和审计;不要把后台审计耦合进 App 业务库。 `room-service` uses MySQL as the room recovery durable source: @@ -161,6 +174,7 @@ services/room-service/ Room Cell and durable room state services/wallet-service/ wallet DebitGift and ledger foundation services/user-service/ user service services/activity-service/ activity foundation and room event consumer boundary +services/cron-service/ background scheduling and owner-service batch trigger ``` ## Current Limits @@ -168,6 +182,6 @@ services/activity-service/ activity foundation and room event consumer boundary - 腾讯云 IM 回调入口已经落在 gateway;线上仍必须在腾讯云 IM 控制台启用 `Group.CallbackBeforeApplyJoinGroup` 和 `Group.CallbackBeforeSendMsg`,并配置公网 callback URL 与鉴权 token。 - 房间命令未传 `command_id` 时,gateway 会自动生成新值;客户端 HTTP 重试同一业务动作时必须复用原 `command_id` 才能命中 room-service command log 幂等。 - `wallet-service` App 运行路径使用 MySQL 扣费事务;本地需要先通过 compose initdb 建好 `hyapp_wallet`。 -- `activity-service` 当前只有同步查询和 consumer 边界;`room_outbox` 到 activity/audit 的实际消费链路未完整实现。 +- `activity-service` 已承接每日任务和消息/活动基础能力;`room_outbox` 到 activity/audit 的实际消费链路仍需按独立消费位点补齐。 - `room-service` App 已启动 `room_outbox` 补偿 worker;该状态只表示腾讯云 IM 系统消息补偿结果,activity/audit 后续必须使用独立消费位点。 - JWT、腾讯云 IM secret 等本地配置只能用开发值,线上必须走安全配置源。 diff --git a/api/proto/activity/v1/activity.pb.go b/api/proto/activity/v1/activity.pb.go index 9d88173f..1c2bc99f 100644 --- a/api/proto/activity/v1/activity.pb.go +++ b/api/proto/activity/v1/activity.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 -// protoc v4.25.3 +// protoc-gen-go v1.34.2 +// protoc v5.29.2 // source: proto/activity/v1/activity.proto package activityv1 @@ -9,6 +9,7 @@ package activityv1 import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + v1 "hyapp.local/api/proto/events/room/v1" reflect "reflect" sync "sync" ) @@ -35,9 +36,11 @@ type RequestMeta struct { func (x *RequestMeta) Reset() { *x = RequestMeta{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RequestMeta) String() string { @@ -48,7 +51,7 @@ func (*RequestMeta) ProtoMessage() {} func (x *RequestMeta) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -109,9 +112,11 @@ type PingActivityRequest struct { func (x *PingActivityRequest) Reset() { *x = PingActivityRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *PingActivityRequest) String() string { @@ -122,7 +127,7 @@ func (*PingActivityRequest) ProtoMessage() {} func (x *PingActivityRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -156,9 +161,11 @@ type PingActivityResponse struct { func (x *PingActivityResponse) Reset() { *x = PingActivityResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *PingActivityResponse) String() string { @@ -169,7 +176,7 @@ func (*PingActivityResponse) ProtoMessage() {} func (x *PingActivityResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -210,9 +217,11 @@ type GetActivityStatusRequest struct { func (x *GetActivityStatusRequest) Reset() { *x = GetActivityStatusRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetActivityStatusRequest) String() string { @@ -223,7 +232,7 @@ func (*GetActivityStatusRequest) ProtoMessage() {} func (x *GetActivityStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -264,9 +273,11 @@ type GetActivityStatusResponse struct { func (x *GetActivityStatusResponse) Reset() { *x = GetActivityStatusResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetActivityStatusResponse) String() string { @@ -277,7 +288,7 @@ func (*GetActivityStatusResponse) ProtoMessage() {} func (x *GetActivityStatusResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -320,9 +331,11 @@ type MessageTabSection struct { func (x *MessageTabSection) Reset() { *x = MessageTabSection{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MessageTabSection) String() string { @@ -333,7 +346,7 @@ func (*MessageTabSection) ProtoMessage() {} func (x *MessageTabSection) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -388,9 +401,11 @@ type ListMessageTabsRequest struct { func (x *ListMessageTabsRequest) Reset() { *x = ListMessageTabsRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListMessageTabsRequest) String() string { @@ -401,7 +416,7 @@ func (*ListMessageTabsRequest) ProtoMessage() {} func (x *ListMessageTabsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -441,9 +456,11 @@ type ListMessageTabsResponse struct { func (x *ListMessageTabsResponse) Reset() { *x = ListMessageTabsResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListMessageTabsResponse) String() string { @@ -454,7 +471,7 @@ func (*ListMessageTabsResponse) ProtoMessage() {} func (x *ListMessageTabsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -497,9 +514,11 @@ type InboxMessage struct { func (x *InboxMessage) Reset() { *x = InboxMessage{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *InboxMessage) String() string { @@ -510,7 +529,7 @@ func (*InboxMessage) ProtoMessage() {} func (x *InboxMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -617,9 +636,11 @@ type ListInboxMessagesRequest struct { func (x *ListInboxMessagesRequest) Reset() { *x = ListInboxMessagesRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListInboxMessagesRequest) String() string { @@ -630,7 +651,7 @@ func (*ListInboxMessagesRequest) ProtoMessage() {} func (x *ListInboxMessagesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -693,9 +714,11 @@ type ListInboxMessagesResponse struct { func (x *ListInboxMessagesResponse) Reset() { *x = ListInboxMessagesResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListInboxMessagesResponse) String() string { @@ -706,7 +729,7 @@ func (*ListInboxMessagesResponse) ProtoMessage() {} func (x *ListInboxMessagesResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[10] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -755,9 +778,11 @@ type MarkInboxMessageReadRequest struct { func (x *MarkInboxMessageReadRequest) Reset() { *x = MarkInboxMessageReadRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MarkInboxMessageReadRequest) String() string { @@ -768,7 +793,7 @@ func (*MarkInboxMessageReadRequest) ProtoMessage() {} func (x *MarkInboxMessageReadRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[11] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -817,9 +842,11 @@ type MarkInboxMessageReadResponse struct { func (x *MarkInboxMessageReadResponse) Reset() { *x = MarkInboxMessageReadResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MarkInboxMessageReadResponse) String() string { @@ -830,7 +857,7 @@ func (*MarkInboxMessageReadResponse) ProtoMessage() {} func (x *MarkInboxMessageReadResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[12] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -879,9 +906,11 @@ type MarkInboxSectionReadRequest struct { func (x *MarkInboxSectionReadRequest) Reset() { *x = MarkInboxSectionReadRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MarkInboxSectionReadRequest) String() string { @@ -892,7 +921,7 @@ func (*MarkInboxSectionReadRequest) ProtoMessage() {} func (x *MarkInboxSectionReadRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[13] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -940,9 +969,11 @@ type MarkInboxSectionReadResponse struct { func (x *MarkInboxSectionReadResponse) Reset() { *x = MarkInboxSectionReadResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MarkInboxSectionReadResponse) String() string { @@ -953,7 +984,7 @@ func (*MarkInboxSectionReadResponse) ProtoMessage() {} func (x *MarkInboxSectionReadResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[14] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -995,9 +1026,11 @@ type DeleteInboxMessageRequest struct { func (x *DeleteInboxMessageRequest) Reset() { *x = DeleteInboxMessageRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *DeleteInboxMessageRequest) String() string { @@ -1008,7 +1041,7 @@ func (*DeleteInboxMessageRequest) ProtoMessage() {} func (x *DeleteInboxMessageRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[15] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1056,9 +1089,11 @@ type DeleteInboxMessageResponse struct { func (x *DeleteInboxMessageResponse) Reset() { *x = DeleteInboxMessageResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *DeleteInboxMessageResponse) String() string { @@ -1069,7 +1104,7 @@ func (*DeleteInboxMessageResponse) ProtoMessage() {} func (x *DeleteInboxMessageResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[16] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1129,9 +1164,11 @@ type CreateInboxMessageRequest struct { func (x *CreateInboxMessageRequest) Reset() { *x = CreateInboxMessageRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateInboxMessageRequest) String() string { @@ -1142,7 +1179,7 @@ func (*CreateInboxMessageRequest) ProtoMessage() {} func (x *CreateInboxMessageRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[17] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1316,9 +1353,11 @@ type CreateInboxMessageResponse struct { func (x *CreateInboxMessageResponse) Reset() { *x = CreateInboxMessageResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateInboxMessageResponse) String() string { @@ -1329,7 +1368,7 @@ func (*CreateInboxMessageResponse) ProtoMessage() {} func (x *CreateInboxMessageResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[18] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1376,9 +1415,11 @@ type CreateFanoutJobRequest struct { func (x *CreateFanoutJobRequest) Reset() { *x = CreateFanoutJobRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateFanoutJobRequest) String() string { @@ -1389,7 +1430,7 @@ func (*CreateFanoutJobRequest) ProtoMessage() {} func (x *CreateFanoutJobRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[19] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1473,9 +1514,11 @@ type CreateFanoutJobResponse struct { func (x *CreateFanoutJobResponse) Reset() { *x = CreateFanoutJobResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateFanoutJobResponse) String() string { @@ -1486,7 +1529,7 @@ func (*CreateFanoutJobResponse) ProtoMessage() {} func (x *CreateFanoutJobResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[20] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1537,9 +1580,11 @@ type CronBatchRequest struct { func (x *CronBatchRequest) Reset() { *x = CronBatchRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CronBatchRequest) String() string { @@ -1550,7 +1595,7 @@ func (*CronBatchRequest) ProtoMessage() {} func (x *CronBatchRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[21] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1615,9 +1660,11 @@ type CronBatchResponse struct { func (x *CronBatchResponse) Reset() { *x = CronBatchResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CronBatchResponse) String() string { @@ -1628,7 +1675,7 @@ func (*CronBatchResponse) ProtoMessage() {} func (x *CronBatchResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[22] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1705,9 +1752,11 @@ type TaskItem struct { func (x *TaskItem) Reset() { *x = TaskItem{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *TaskItem) String() string { @@ -1718,7 +1767,7 @@ func (*TaskItem) ProtoMessage() {} func (x *TaskItem) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[23] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1866,9 +1915,11 @@ type TaskSection struct { func (x *TaskSection) Reset() { *x = TaskSection{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *TaskSection) String() string { @@ -1879,7 +1930,7 @@ func (*TaskSection) ProtoMessage() {} func (x *TaskSection) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[24] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1934,9 +1985,11 @@ type ListUserTasksRequest struct { func (x *ListUserTasksRequest) Reset() { *x = ListUserTasksRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListUserTasksRequest) String() string { @@ -1947,7 +2000,7 @@ func (*ListUserTasksRequest) ProtoMessage() {} func (x *ListUserTasksRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[25] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1989,9 +2042,11 @@ type ListUserTasksResponse struct { func (x *ListUserTasksResponse) Reset() { *x = ListUserTasksResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListUserTasksResponse) String() string { @@ -2002,7 +2057,7 @@ func (*ListUserTasksResponse) ProtoMessage() {} func (x *ListUserTasksResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[26] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2054,9 +2109,11 @@ type ClaimTaskRewardRequest struct { func (x *ClaimTaskRewardRequest) Reset() { *x = ClaimTaskRewardRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ClaimTaskRewardRequest) String() string { @@ -2067,7 +2124,7 @@ func (*ClaimTaskRewardRequest) ProtoMessage() {} func (x *ClaimTaskRewardRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[27] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2143,9 +2200,11 @@ type ClaimTaskRewardResponse struct { func (x *ClaimTaskRewardResponse) Reset() { *x = ClaimTaskRewardResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ClaimTaskRewardResponse) String() string { @@ -2156,7 +2215,7 @@ func (*ClaimTaskRewardResponse) ProtoMessage() {} func (x *ClaimTaskRewardResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[28] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2252,9 +2311,11 @@ type ConsumeTaskEventRequest struct { func (x *ConsumeTaskEventRequest) Reset() { *x = ConsumeTaskEventRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ConsumeTaskEventRequest) String() string { @@ -2265,7 +2326,7 @@ func (*ConsumeTaskEventRequest) ProtoMessage() {} func (x *ConsumeTaskEventRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[29] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2349,9 +2410,11 @@ type ConsumeTaskEventResponse struct { func (x *ConsumeTaskEventResponse) Reset() { *x = ConsumeTaskEventResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ConsumeTaskEventResponse) String() string { @@ -2362,7 +2425,7 @@ func (*ConsumeTaskEventResponse) ProtoMessage() {} func (x *ConsumeTaskEventResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_activity_v1_activity_proto_msgTypes[30] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2398,6 +2461,709 @@ func (x *ConsumeTaskEventResponse) GetMatchedTaskCount() int32 { return 0 } +// BroadcastJoinGroup 是 gateway 下发给客户端的 IM 播报群信息在服务端的同源结构。 +type BroadcastJoinGroup struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + RegionId int64 `protobuf:"varint,3,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"` +} + +func (x *BroadcastJoinGroup) Reset() { + *x = BroadcastJoinGroup{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BroadcastJoinGroup) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BroadcastJoinGroup) ProtoMessage() {} + +func (x *BroadcastJoinGroup) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BroadcastJoinGroup.ProtoReflect.Descriptor instead. +func (*BroadcastJoinGroup) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{31} +} + +func (x *BroadcastJoinGroup) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *BroadcastJoinGroup) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *BroadcastJoinGroup) GetRegionId() int64 { + if x != nil { + return x.RegionId + } + return 0 +} + +type EnsureBroadcastGroupsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *EnsureBroadcastGroupsRequest) Reset() { + *x = EnsureBroadcastGroupsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnsureBroadcastGroupsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnsureBroadcastGroupsRequest) ProtoMessage() {} + +func (x *EnsureBroadcastGroupsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnsureBroadcastGroupsRequest.ProtoReflect.Descriptor instead. +func (*EnsureBroadcastGroupsRequest) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{32} +} + +func (x *EnsureBroadcastGroupsRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type EnsureBroadcastGroupsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EnsuredCount int32 `protobuf:"varint,1,opt,name=ensured_count,json=ensuredCount,proto3" json:"ensured_count,omitempty"` +} + +func (x *EnsureBroadcastGroupsResponse) Reset() { + *x = EnsureBroadcastGroupsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnsureBroadcastGroupsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnsureBroadcastGroupsResponse) ProtoMessage() {} + +func (x *EnsureBroadcastGroupsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnsureBroadcastGroupsResponse.ProtoReflect.Descriptor instead. +func (*EnsureBroadcastGroupsResponse) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{33} +} + +func (x *EnsureBroadcastGroupsResponse) GetEnsuredCount() int32 { + if x != nil { + return x.EnsuredCount + } + return 0 +} + +type PublishRegionBroadcastRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + EventId string `protobuf:"bytes,2,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` + RegionId int64 `protobuf:"varint,3,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"` + BroadcastType string `protobuf:"bytes,4,opt,name=broadcast_type,json=broadcastType,proto3" json:"broadcast_type,omitempty"` + PayloadJson string `protobuf:"bytes,5,opt,name=payload_json,json=payloadJson,proto3" json:"payload_json,omitempty"` +} + +func (x *PublishRegionBroadcastRequest) Reset() { + *x = PublishRegionBroadcastRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishRegionBroadcastRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishRegionBroadcastRequest) ProtoMessage() {} + +func (x *PublishRegionBroadcastRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublishRegionBroadcastRequest.ProtoReflect.Descriptor instead. +func (*PublishRegionBroadcastRequest) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{34} +} + +func (x *PublishRegionBroadcastRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *PublishRegionBroadcastRequest) GetEventId() string { + if x != nil { + return x.EventId + } + return "" +} + +func (x *PublishRegionBroadcastRequest) GetRegionId() int64 { + if x != nil { + return x.RegionId + } + return 0 +} + +func (x *PublishRegionBroadcastRequest) GetBroadcastType() string { + if x != nil { + return x.BroadcastType + } + return "" +} + +func (x *PublishRegionBroadcastRequest) GetPayloadJson() string { + if x != nil { + return x.PayloadJson + } + return "" +} + +type PublishGlobalBroadcastRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + EventId string `protobuf:"bytes,2,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` + BroadcastType string `protobuf:"bytes,3,opt,name=broadcast_type,json=broadcastType,proto3" json:"broadcast_type,omitempty"` + PayloadJson string `protobuf:"bytes,4,opt,name=payload_json,json=payloadJson,proto3" json:"payload_json,omitempty"` +} + +func (x *PublishGlobalBroadcastRequest) Reset() { + *x = PublishGlobalBroadcastRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishGlobalBroadcastRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishGlobalBroadcastRequest) ProtoMessage() {} + +func (x *PublishGlobalBroadcastRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublishGlobalBroadcastRequest.ProtoReflect.Descriptor instead. +func (*PublishGlobalBroadcastRequest) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{35} +} + +func (x *PublishGlobalBroadcastRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *PublishGlobalBroadcastRequest) GetEventId() string { + if x != nil { + return x.EventId + } + return "" +} + +func (x *PublishGlobalBroadcastRequest) GetBroadcastType() string { + if x != nil { + return x.BroadcastType + } + return "" +} + +func (x *PublishGlobalBroadcastRequest) GetPayloadJson() string { + if x != nil { + return x.PayloadJson + } + return "" +} + +type PublishBroadcastResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EventId string `protobuf:"bytes,1,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` + GroupId string `protobuf:"bytes,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` + Created bool `protobuf:"varint,4,opt,name=created,proto3" json:"created,omitempty"` +} + +func (x *PublishBroadcastResponse) Reset() { + *x = PublishBroadcastResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishBroadcastResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishBroadcastResponse) ProtoMessage() {} + +func (x *PublishBroadcastResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublishBroadcastResponse.ProtoReflect.Descriptor instead. +func (*PublishBroadcastResponse) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{36} +} + +func (x *PublishBroadcastResponse) GetEventId() string { + if x != nil { + return x.EventId + } + return "" +} + +func (x *PublishBroadcastResponse) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *PublishBroadcastResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *PublishBroadcastResponse) GetCreated() bool { + if x != nil { + return x.Created + } + return false +} + +// RemoveRegionBroadcastMemberRequest 只移除某个用户的旧区域群成员关系,不删除或解散区域群。 +type RemoveRegionBroadcastMemberRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + RegionId int64 `protobuf:"varint,3,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"` + Reason string `protobuf:"bytes,4,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *RemoveRegionBroadcastMemberRequest) Reset() { + *x = RemoveRegionBroadcastMemberRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRegionBroadcastMemberRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRegionBroadcastMemberRequest) ProtoMessage() {} + +func (x *RemoveRegionBroadcastMemberRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveRegionBroadcastMemberRequest.ProtoReflect.Descriptor instead. +func (*RemoveRegionBroadcastMemberRequest) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{37} +} + +func (x *RemoveRegionBroadcastMemberRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *RemoveRegionBroadcastMemberRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *RemoveRegionBroadcastMemberRequest) GetRegionId() int64 { + if x != nil { + return x.RegionId + } + return 0 +} + +func (x *RemoveRegionBroadcastMemberRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +type RemoveRegionBroadcastMemberResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + Removed bool `protobuf:"varint,2,opt,name=removed,proto3" json:"removed,omitempty"` +} + +func (x *RemoveRegionBroadcastMemberResponse) Reset() { + *x = RemoveRegionBroadcastMemberResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRegionBroadcastMemberResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRegionBroadcastMemberResponse) ProtoMessage() {} + +func (x *RemoveRegionBroadcastMemberResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveRegionBroadcastMemberResponse.ProtoReflect.Descriptor instead. +func (*RemoveRegionBroadcastMemberResponse) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{38} +} + +func (x *RemoveRegionBroadcastMemberResponse) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *RemoveRegionBroadcastMemberResponse) GetRemoved() bool { + if x != nil { + return x.Removed + } + return false +} + +type ProcessBroadcastOutboxBatchResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClaimedCount int32 `protobuf:"varint,1,opt,name=claimed_count,json=claimedCount,proto3" json:"claimed_count,omitempty"` + SuccessCount int32 `protobuf:"varint,2,opt,name=success_count,json=successCount,proto3" json:"success_count,omitempty"` + FailureCount int32 `protobuf:"varint,3,opt,name=failure_count,json=failureCount,proto3" json:"failure_count,omitempty"` + HasMore bool `protobuf:"varint,4,opt,name=has_more,json=hasMore,proto3" json:"has_more,omitempty"` +} + +func (x *ProcessBroadcastOutboxBatchResponse) Reset() { + *x = ProcessBroadcastOutboxBatchResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProcessBroadcastOutboxBatchResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessBroadcastOutboxBatchResponse) ProtoMessage() {} + +func (x *ProcessBroadcastOutboxBatchResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessBroadcastOutboxBatchResponse.ProtoReflect.Descriptor instead. +func (*ProcessBroadcastOutboxBatchResponse) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{39} +} + +func (x *ProcessBroadcastOutboxBatchResponse) GetClaimedCount() int32 { + if x != nil { + return x.ClaimedCount + } + return 0 +} + +func (x *ProcessBroadcastOutboxBatchResponse) GetSuccessCount() int32 { + if x != nil { + return x.SuccessCount + } + return 0 +} + +func (x *ProcessBroadcastOutboxBatchResponse) GetFailureCount() int32 { + if x != nil { + return x.FailureCount + } + return 0 +} + +func (x *ProcessBroadcastOutboxBatchResponse) GetHasMore() bool { + if x != nil { + return x.HasMore + } + return false +} + +type ConsumeRoomEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + Envelope *v1.EventEnvelope `protobuf:"bytes,2,opt,name=envelope,proto3" json:"envelope,omitempty"` +} + +func (x *ConsumeRoomEventRequest) Reset() { + *x = ConsumeRoomEventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConsumeRoomEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConsumeRoomEventRequest) ProtoMessage() {} + +func (x *ConsumeRoomEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConsumeRoomEventRequest.ProtoReflect.Descriptor instead. +func (*ConsumeRoomEventRequest) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{40} +} + +func (x *ConsumeRoomEventRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *ConsumeRoomEventRequest) GetEnvelope() *v1.EventEnvelope { + if x != nil { + return x.Envelope + } + return nil +} + +type ConsumeRoomEventResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EventId string `protobuf:"bytes,1,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + BroadcastEventId string `protobuf:"bytes,3,opt,name=broadcast_event_id,json=broadcastEventId,proto3" json:"broadcast_event_id,omitempty"` + BroadcastCreated bool `protobuf:"varint,4,opt,name=broadcast_created,json=broadcastCreated,proto3" json:"broadcast_created,omitempty"` +} + +func (x *ConsumeRoomEventResponse) Reset() { + *x = ConsumeRoomEventResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConsumeRoomEventResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConsumeRoomEventResponse) ProtoMessage() {} + +func (x *ConsumeRoomEventResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConsumeRoomEventResponse.ProtoReflect.Descriptor instead. +func (*ConsumeRoomEventResponse) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{41} +} + +func (x *ConsumeRoomEventResponse) GetEventId() string { + if x != nil { + return x.EventId + } + return "" +} + +func (x *ConsumeRoomEventResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ConsumeRoomEventResponse) GetBroadcastEventId() string { + if x != nil { + return x.BroadcastEventId + } + return "" +} + +func (x *ConsumeRoomEventResponse) GetBroadcastCreated() bool { + if x != nil { + return x.BroadcastCreated + } + return false +} + // TaskDefinition 是后台管理任务配置的当前版本读模型。 type TaskDefinition struct { state protoimpl.MessageState @@ -2426,9 +3192,11 @@ type TaskDefinition struct { func (x *TaskDefinition) Reset() { *x = TaskDefinition{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *TaskDefinition) String() string { @@ -2438,8 +3206,8 @@ func (x *TaskDefinition) String() string { func (*TaskDefinition) ProtoMessage() {} func (x *TaskDefinition) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[31] - if x != nil { + mi := &file_proto_activity_v1_activity_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2451,7 +3219,7 @@ func (x *TaskDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use TaskDefinition.ProtoReflect.Descriptor instead. func (*TaskDefinition) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{31} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{42} } func (x *TaskDefinition) GetTaskId() string { @@ -2597,9 +3365,11 @@ type ListTaskDefinitionsRequest struct { func (x *ListTaskDefinitionsRequest) Reset() { *x = ListTaskDefinitionsRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListTaskDefinitionsRequest) String() string { @@ -2609,8 +3379,8 @@ func (x *ListTaskDefinitionsRequest) String() string { func (*ListTaskDefinitionsRequest) ProtoMessage() {} func (x *ListTaskDefinitionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[32] - if x != nil { + mi := &file_proto_activity_v1_activity_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2622,7 +3392,7 @@ func (x *ListTaskDefinitionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTaskDefinitionsRequest.ProtoReflect.Descriptor instead. func (*ListTaskDefinitionsRequest) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{32} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{43} } func (x *ListTaskDefinitionsRequest) GetMeta() *RequestMeta { @@ -2685,9 +3455,11 @@ type ListTaskDefinitionsResponse struct { func (x *ListTaskDefinitionsResponse) Reset() { *x = ListTaskDefinitionsResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListTaskDefinitionsResponse) String() string { @@ -2697,8 +3469,8 @@ func (x *ListTaskDefinitionsResponse) String() string { func (*ListTaskDefinitionsResponse) ProtoMessage() {} func (x *ListTaskDefinitionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[33] - if x != nil { + mi := &file_proto_activity_v1_activity_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2710,7 +3482,7 @@ func (x *ListTaskDefinitionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTaskDefinitionsResponse.ProtoReflect.Descriptor instead. func (*ListTaskDefinitionsResponse) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{33} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{44} } func (x *ListTaskDefinitionsResponse) GetTasks() []*TaskDefinition { @@ -2752,9 +3524,11 @@ type UpsertTaskDefinitionRequest struct { func (x *UpsertTaskDefinitionRequest) Reset() { *x = UpsertTaskDefinitionRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpsertTaskDefinitionRequest) String() string { @@ -2764,8 +3538,8 @@ func (x *UpsertTaskDefinitionRequest) String() string { func (*UpsertTaskDefinitionRequest) ProtoMessage() {} func (x *UpsertTaskDefinitionRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[34] - if x != nil { + mi := &file_proto_activity_v1_activity_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2777,7 +3551,7 @@ func (x *UpsertTaskDefinitionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpsertTaskDefinitionRequest.ProtoReflect.Descriptor instead. func (*UpsertTaskDefinitionRequest) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{34} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{45} } func (x *UpsertTaskDefinitionRequest) GetMeta() *RequestMeta { @@ -2896,9 +3670,11 @@ type UpsertTaskDefinitionResponse struct { func (x *UpsertTaskDefinitionResponse) Reset() { *x = UpsertTaskDefinitionResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpsertTaskDefinitionResponse) String() string { @@ -2908,8 +3684,8 @@ func (x *UpsertTaskDefinitionResponse) String() string { func (*UpsertTaskDefinitionResponse) ProtoMessage() {} func (x *UpsertTaskDefinitionResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[35] - if x != nil { + mi := &file_proto_activity_v1_activity_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2921,7 +3697,7 @@ func (x *UpsertTaskDefinitionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpsertTaskDefinitionResponse.ProtoReflect.Descriptor instead. func (*UpsertTaskDefinitionResponse) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{35} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{46} } func (x *UpsertTaskDefinitionResponse) GetTask() *TaskDefinition { @@ -2952,9 +3728,11 @@ type SetTaskDefinitionStatusRequest struct { func (x *SetTaskDefinitionStatusRequest) Reset() { *x = SetTaskDefinitionStatusRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetTaskDefinitionStatusRequest) String() string { @@ -2964,8 +3742,8 @@ func (x *SetTaskDefinitionStatusRequest) String() string { func (*SetTaskDefinitionStatusRequest) ProtoMessage() {} func (x *SetTaskDefinitionStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[36] - if x != nil { + mi := &file_proto_activity_v1_activity_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2977,7 +3755,7 @@ func (x *SetTaskDefinitionStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetTaskDefinitionStatusRequest.ProtoReflect.Descriptor instead. func (*SetTaskDefinitionStatusRequest) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{36} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{47} } func (x *SetTaskDefinitionStatusRequest) GetMeta() *RequestMeta { @@ -3018,9 +3796,11 @@ type SetTaskDefinitionStatusResponse struct { func (x *SetTaskDefinitionStatusResponse) Reset() { *x = SetTaskDefinitionStatusResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_activity_v1_activity_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetTaskDefinitionStatusResponse) String() string { @@ -3030,8 +3810,8 @@ func (x *SetTaskDefinitionStatusResponse) String() string { func (*SetTaskDefinitionStatusResponse) ProtoMessage() {} func (x *SetTaskDefinitionStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[37] - if x != nil { + mi := &file_proto_activity_v1_activity_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3043,7 +3823,7 @@ func (x *SetTaskDefinitionStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetTaskDefinitionStatusResponse.ProtoReflect.Descriptor instead. func (*SetTaskDefinitionStatusResponse) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{37} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{48} } func (x *SetTaskDefinitionStatusResponse) GetTask() *TaskDefinition { @@ -3059,612 +3839,760 @@ var file_proto_activity_v1_activity_proto_rawDesc = []byte{ 0x0a, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, - 0x74, 0x79, 0x2e, 0x76, 0x31, 0x22, 0xa5, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4e, 0x6f, - 0x64, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x5f, - 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, - 0x4d, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x49, 0x0a, - 0x13, 0x50, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, - 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x3f, 0x0a, 0x14, 0x50, 0x69, 0x6e, 0x67, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, - 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x18, 0x47, 0x65, 0x74, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, 0x64, 0x22, 0x54, 0x0a, 0x19, 0x47, 0x65, - 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x7e, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x53, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x5f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x6e, 0x72, - 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x65, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, - 0x61, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, - 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, - 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x5b, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x54, 0x61, 0x62, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb9, 0x02, 0x0a, 0x0c, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, - 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x12, - 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, - 0x64, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x63, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, - 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x12, - 0x0a, 0x04, 0x72, 0x65, 0x61, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x72, 0x65, - 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x4d, 0x73, - 0x22, 0xbd, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, + 0x74, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x2f, 0x72, 0x6f, 0x6f, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, + 0x26, 0x0a, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x5f, + 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x6e, + 0x74, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x43, 0x6f, 0x64, 0x65, + 0x22, 0x49, 0x0a, 0x13, 0x50, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x3f, 0x0a, 0x14, 0x50, + 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x18, + 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, 0x64, 0x22, 0x54, 0x0a, + 0x19, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x22, 0x7e, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, + 0x62, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x72, 0x65, + 0x61, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, + 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x22, 0x65, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0x94, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x62, 0x6f, - 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, - 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, - 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x89, 0x01, 0x0a, 0x1b, 0x4d, 0x61, 0x72, 0x6b, - 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, + 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x5b, 0x0a, 0x17, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb9, 0x02, 0x0a, 0x0c, 0x49, 0x6e, 0x62, 0x6f, + 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x63, 0x6f, 0x6e, 0x55, 0x72, 0x6c, + 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, + 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x61, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x04, 0x72, 0x65, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, + 0x5f, 0x6d, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x74, 0x41, + 0x74, 0x4d, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, + 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x94, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, + 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x05, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x49, + 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, + 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x89, 0x01, 0x0a, 0x1b, 0x4d, + 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, + 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x1c, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, + 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x61, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x04, 0x72, 0x65, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x0a, 0x72, 0x65, 0x61, + 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, + 0x65, 0x61, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x1b, 0x4d, 0x61, 0x72, 0x6b, + 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x1c, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x04, 0x72, 0x65, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x61, - 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, - 0x41, 0x74, 0x4d, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x1b, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, - 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, - 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x57, 0x0a, 0x1c, 0x4d, - 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x65, 0x61, 0x64, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x87, 0x01, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, - 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x55, - 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0xe7, 0x05, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, - 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, - 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x6f, - 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, - 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x67, 0x67, 0x72, - 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, - 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, - 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x12, - 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, - 0x64, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x63, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, - 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x0a, 0x73, 0x65, - 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, - 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x20, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x73, 0x6f, 0x6e, 0x22, - 0x55, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xd3, 0x02, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, - 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x6a, 0x73, - 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x1d, - 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0x62, 0x0a, 0x17, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x22, 0xb9, 0x01, 0x0a, 0x10, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x57, + 0x0a, 0x1c, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x61, 0x64, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x65, + 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x87, 0x01, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x75, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x64, - 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0b, - 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x74, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x74, 0x6c, 0x4d, 0x73, 0x22, 0xc6, 0x01, 0x0a, - 0x11, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x63, 0x6c, 0x61, 0x69, 0x6d, - 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, - 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x66, 0x61, - 0x69, 0x6c, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x68, 0x61, - 0x73, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x61, - 0x73, 0x4d, 0x6f, 0x72, 0x65, 0x22, 0xab, 0x04, 0x0a, 0x08, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x74, - 0x65, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, - 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, - 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x6e, 0x69, - 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x67, 0x72, - 0x65, 0x73, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x77, 0x61, - 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x69, 0x6e, - 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, - 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x74, 0x61, 0x73, 0x6b, 0x44, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x2b, 0x0a, - 0x12, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x74, - 0x5f, 0x6d, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x52, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6f, - 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, - 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x0a, - 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, + 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, + 0x64, 0x22, 0x55, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0xe7, 0x05, 0x0a, 0x19, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x11, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, + 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x63, 0x6f, 0x6e, 0x55, 0x72, 0x6c, + 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, + 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, + 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x20, 0x0a, 0x0c, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x15, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x73, + 0x6f, 0x6e, 0x22, 0x55, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, + 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xd3, 0x02, 0x0a, 0x16, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x2c, 0x0a, + 0x12, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x6a, + 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x16, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4a, 0x73, 0x6f, + 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, + 0x62, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, + 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, + 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x22, 0xb9, 0x01, 0x0a, 0x10, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x15, 0x0a, 0x06, + 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x75, + 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x1e, 0x0a, 0x0b, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x74, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x74, 0x6c, 0x4d, 0x73, 0x22, + 0xc6, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x63, 0x6c, + 0x61, 0x69, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x68, 0x61, 0x73, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x68, 0x61, 0x73, 0x4d, 0x6f, 0x72, 0x65, 0x22, 0xab, 0x04, 0x0a, 0x08, 0x54, 0x61, 0x73, + 0x6b, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x6e, + 0x69, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x55, 0x6e, 0x69, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x72, + 0x65, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x43, + 0x6f, 0x69, 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x44, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, + 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x65, + 0x78, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x1d, 0x0a, + 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x73, 0x6b, 0x53, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x31, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, + 0x73, 0x68, 0x41, 0x74, 0x4d, 0x73, 0x22, 0x63, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, + 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, - 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, - 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, - 0x74, 0x4d, 0x73, 0x22, 0x63, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x54, - 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xa6, 0x01, 0x0a, 0x15, + 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, + 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x78, 0x74, 0x5f, + 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x41, 0x74, 0x4d, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x16, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x61, + 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, + 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, + 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x44, 0x61, 0x79, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x22, 0xbd, 0x02, 0x0a, + 0x17, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, + 0x6b, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, + 0x6b, 0x44, 0x61, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x63, + 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x10, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, 0x61, 0x6c, 0x6c, 0x65, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x22, + 0x0a, 0x0d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x4d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x22, 0xa4, 0x02, 0x0a, + 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x17, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x24, 0x0a, + 0x0e, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x41, + 0x74, 0x4d, 0x73, 0x22, 0x7b, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, + 0x73, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x74, 0x61, + 0x73, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0x60, 0x0a, 0x12, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4a, 0x6f, 0x69, + 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x22, 0x52, 0x0a, 0x1c, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x42, 0x72, 0x6f, 0x61, + 0x64, 0x63, 0x61, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x44, 0x0a, 0x1d, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, + 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x73, 0x75, 0x72, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, + 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd5, 0x01, 0x0a, + 0x1d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, + 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, + 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x72, + 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6a, 0x73, 0x6f, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0xb8, 0x01, 0x0a, 0x1d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, + 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, + 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4a, 0x73, 0x6f, 0x6e, 0x22, + 0x82, 0x01, 0x0a, 0x18, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x42, 0x72, 0x6f, 0x61, 0x64, + 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x22, 0xa6, 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, + 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xa6, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, - 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, - 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x74, 0x4d, - 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x16, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x52, - 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, - 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, - 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, - 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, - 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x44, 0x61, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x22, 0xbd, 0x02, 0x0a, 0x17, 0x43, 0x6c, - 0x61, 0x69, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x49, 0x64, - 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, - 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, - 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x64, - 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x44, 0x61, - 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x69, 0x6e, - 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, - 0x65, 0x77, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x67, - 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x22, 0xa4, 0x02, 0x0a, 0x17, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x63, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, - 0x22, 0x7b, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x2c, 0x0a, 0x12, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x64, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xf8, 0x04, - 0x0a, 0x0e, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, - 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, - 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, - 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, - 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x6e, 0x69, 0x74, 0x12, - 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x77, - 0x61, 0x72, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, - 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, - 0x0a, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x6d, - 0x5f, 0x6d, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x4d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0d, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x6f, - 0x4d, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, - 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x2d, 0x0a, 0x13, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x49, 0x64, - 0x12, 0x22, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, - 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x4d, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, - 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x67, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x5a, 0x0a, + 0x23, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x6f, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0xaf, 0x01, 0x0a, 0x23, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4f, 0x75, + 0x74, 0x62, 0x6f, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, + 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x68, 0x61, 0x73, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x68, 0x61, 0x73, 0x4d, 0x6f, 0x72, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x17, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x74, - 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, - 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, - 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x6c, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xa5, 0x04, 0x0a, 0x1b, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, - 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, - 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, - 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, - 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x77, 0x61, - 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x69, 0x6e, - 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, - 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x2a, 0x0a, - 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, - 0x6d, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x4d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0d, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x6f, 0x4d, - 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x22, 0x6f, 0x0a, - 0x1c, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, - 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, - 0x74, 0x61, 0x73, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xb1, - 0x01, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x08, 0x65, + 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x72, 0x6f, 0x6f, + 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, + 0x70, 0x65, 0x52, 0x08, 0x65, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x22, 0xa8, 0x01, 0x0a, + 0x18, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x12, + 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, + 0x61, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x62, 0x72, + 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xf8, 0x04, 0x0a, 0x0e, 0x54, 0x61, 0x73, 0x6b, + 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, + 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, + 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x77, + 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x69, + 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6d, 0x73, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, + 0x6f, 0x6d, 0x4d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x6f, 0x4d, 0x73, 0x12, 0x2d, 0x0a, 0x13, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x13, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x22, + 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x4d, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, - 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x6d, 0x69, 0x6e, - 0x49, 0x64, 0x22, 0x58, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x32, 0xe2, 0x01, 0x0a, - 0x0f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x5f, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, - 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, - 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x6e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0xb1, 0x06, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x62, - 0x6f, 0x78, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x0f, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, 0x12, 0x29, 0x2e, 0x68, - 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, + 0x70, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, + 0x65, 0x22, 0x6c, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x37, 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, + 0xa5, 0x04, 0x0a, 0x1b, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, + 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, + 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, + 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x6e, + 0x69, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x69, + 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, + 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, + 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, + 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6d, 0x73, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x6f, + 0x6d, 0x4d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x74, 0x6f, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x54, 0x6f, 0x4d, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x1c, 0x55, 0x70, 0x73, 0x65, 0x72, + 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xb1, 0x01, 0x0a, 0x1e, 0x53, 0x65, 0x74, + 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, + 0x17, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x22, 0x58, 0x0a, 0x1f, + 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x35, 0x0a, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x32, 0xe2, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0c, 0x50, 0x69, + 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb1, 0x06, 0x0a, 0x13, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x61, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x61, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, + 0x11, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, + 0x14, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x61, 0x64, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, + 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, + 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x14, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, + 0x62, 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x12, 0x2e, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, + 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x71, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, + 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x71, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, + 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, + 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x61, + 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, + 0x7d, 0x0a, 0x13, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x43, 0x72, 0x6f, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x66, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, + 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc8, + 0x02, 0x0a, 0x0b, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, + 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, + 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, - 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x14, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x12, 0x2e, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x14, - 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x61, 0x64, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, - 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x62, - 0x6f, 0x78, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, - 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x68, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0f, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x52, + 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x54, + 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, + 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x10, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0f, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x12, 0x29, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, - 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6e, 0x6f, 0x75, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x7d, 0x0a, 0x13, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x43, 0x72, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x66, 0x0a, 0x19, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x61, - 0x6e, 0x6f, 0x75, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, - 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc8, 0x02, 0x0a, 0x0b, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, - 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, - 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0f, 0x43, 0x6c, 0x61, 0x69, - 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x29, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, - 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, - 0x73, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, - 0x84, 0x03, 0x0a, 0x10, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, - 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x2e, 0x68, 0x79, - 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, - 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x14, 0x55, 0x70, - 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x73, - 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x73, - 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, - 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2e, 0x5a, 0x2c, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8b, 0x05, 0x0a, 0x10, 0x42, 0x72, + 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7a, + 0x0a, 0x15, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, + 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x73, 0x75, + 0x72, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x73, + 0x75, 0x72, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, + 0x63, 0x61, 0x73, 0x74, 0x12, 0x30, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x30, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x42, + 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x42, 0x72, 0x6f, 0x61, 0x64, + 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, + 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x6f, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x35, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x6f, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x1b, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4f, + 0x75, 0x74, 0x62, 0x6f, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61, + 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x72, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x72, 0x6f, 0x61, 0x64, + 0x63, 0x61, 0x73, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x87, 0x01, 0x0a, 0x18, 0x52, 0x6f, 0x6f, 0x6d, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x6b, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x52, + 0x6f, 0x6f, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, + 0x52, 0x6f, 0x6f, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x32, 0x84, 0x03, 0x0a, 0x10, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, + 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x2e, + 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, + 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x14, + 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, + 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, + 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, + 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x31, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x61, 0x73, 0x6b, + 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2e, 0x5a, 0x2c, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3679,46 +4607,58 @@ func file_proto_activity_v1_activity_proto_rawDescGZIP() []byte { return file_proto_activity_v1_activity_proto_rawDescData } -var file_proto_activity_v1_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 38) +var file_proto_activity_v1_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 49) var file_proto_activity_v1_activity_proto_goTypes = []any{ - (*RequestMeta)(nil), // 0: hyapp.activity.v1.RequestMeta - (*PingActivityRequest)(nil), // 1: hyapp.activity.v1.PingActivityRequest - (*PingActivityResponse)(nil), // 2: hyapp.activity.v1.PingActivityResponse - (*GetActivityStatusRequest)(nil), // 3: hyapp.activity.v1.GetActivityStatusRequest - (*GetActivityStatusResponse)(nil), // 4: hyapp.activity.v1.GetActivityStatusResponse - (*MessageTabSection)(nil), // 5: hyapp.activity.v1.MessageTabSection - (*ListMessageTabsRequest)(nil), // 6: hyapp.activity.v1.ListMessageTabsRequest - (*ListMessageTabsResponse)(nil), // 7: hyapp.activity.v1.ListMessageTabsResponse - (*InboxMessage)(nil), // 8: hyapp.activity.v1.InboxMessage - (*ListInboxMessagesRequest)(nil), // 9: hyapp.activity.v1.ListInboxMessagesRequest - (*ListInboxMessagesResponse)(nil), // 10: hyapp.activity.v1.ListInboxMessagesResponse - (*MarkInboxMessageReadRequest)(nil), // 11: hyapp.activity.v1.MarkInboxMessageReadRequest - (*MarkInboxMessageReadResponse)(nil), // 12: hyapp.activity.v1.MarkInboxMessageReadResponse - (*MarkInboxSectionReadRequest)(nil), // 13: hyapp.activity.v1.MarkInboxSectionReadRequest - (*MarkInboxSectionReadResponse)(nil), // 14: hyapp.activity.v1.MarkInboxSectionReadResponse - (*DeleteInboxMessageRequest)(nil), // 15: hyapp.activity.v1.DeleteInboxMessageRequest - (*DeleteInboxMessageResponse)(nil), // 16: hyapp.activity.v1.DeleteInboxMessageResponse - (*CreateInboxMessageRequest)(nil), // 17: hyapp.activity.v1.CreateInboxMessageRequest - (*CreateInboxMessageResponse)(nil), // 18: hyapp.activity.v1.CreateInboxMessageResponse - (*CreateFanoutJobRequest)(nil), // 19: hyapp.activity.v1.CreateFanoutJobRequest - (*CreateFanoutJobResponse)(nil), // 20: hyapp.activity.v1.CreateFanoutJobResponse - (*CronBatchRequest)(nil), // 21: hyapp.activity.v1.CronBatchRequest - (*CronBatchResponse)(nil), // 22: hyapp.activity.v1.CronBatchResponse - (*TaskItem)(nil), // 23: hyapp.activity.v1.TaskItem - (*TaskSection)(nil), // 24: hyapp.activity.v1.TaskSection - (*ListUserTasksRequest)(nil), // 25: hyapp.activity.v1.ListUserTasksRequest - (*ListUserTasksResponse)(nil), // 26: hyapp.activity.v1.ListUserTasksResponse - (*ClaimTaskRewardRequest)(nil), // 27: hyapp.activity.v1.ClaimTaskRewardRequest - (*ClaimTaskRewardResponse)(nil), // 28: hyapp.activity.v1.ClaimTaskRewardResponse - (*ConsumeTaskEventRequest)(nil), // 29: hyapp.activity.v1.ConsumeTaskEventRequest - (*ConsumeTaskEventResponse)(nil), // 30: hyapp.activity.v1.ConsumeTaskEventResponse - (*TaskDefinition)(nil), // 31: hyapp.activity.v1.TaskDefinition - (*ListTaskDefinitionsRequest)(nil), // 32: hyapp.activity.v1.ListTaskDefinitionsRequest - (*ListTaskDefinitionsResponse)(nil), // 33: hyapp.activity.v1.ListTaskDefinitionsResponse - (*UpsertTaskDefinitionRequest)(nil), // 34: hyapp.activity.v1.UpsertTaskDefinitionRequest - (*UpsertTaskDefinitionResponse)(nil), // 35: hyapp.activity.v1.UpsertTaskDefinitionResponse - (*SetTaskDefinitionStatusRequest)(nil), // 36: hyapp.activity.v1.SetTaskDefinitionStatusRequest - (*SetTaskDefinitionStatusResponse)(nil), // 37: hyapp.activity.v1.SetTaskDefinitionStatusResponse + (*RequestMeta)(nil), // 0: hyapp.activity.v1.RequestMeta + (*PingActivityRequest)(nil), // 1: hyapp.activity.v1.PingActivityRequest + (*PingActivityResponse)(nil), // 2: hyapp.activity.v1.PingActivityResponse + (*GetActivityStatusRequest)(nil), // 3: hyapp.activity.v1.GetActivityStatusRequest + (*GetActivityStatusResponse)(nil), // 4: hyapp.activity.v1.GetActivityStatusResponse + (*MessageTabSection)(nil), // 5: hyapp.activity.v1.MessageTabSection + (*ListMessageTabsRequest)(nil), // 6: hyapp.activity.v1.ListMessageTabsRequest + (*ListMessageTabsResponse)(nil), // 7: hyapp.activity.v1.ListMessageTabsResponse + (*InboxMessage)(nil), // 8: hyapp.activity.v1.InboxMessage + (*ListInboxMessagesRequest)(nil), // 9: hyapp.activity.v1.ListInboxMessagesRequest + (*ListInboxMessagesResponse)(nil), // 10: hyapp.activity.v1.ListInboxMessagesResponse + (*MarkInboxMessageReadRequest)(nil), // 11: hyapp.activity.v1.MarkInboxMessageReadRequest + (*MarkInboxMessageReadResponse)(nil), // 12: hyapp.activity.v1.MarkInboxMessageReadResponse + (*MarkInboxSectionReadRequest)(nil), // 13: hyapp.activity.v1.MarkInboxSectionReadRequest + (*MarkInboxSectionReadResponse)(nil), // 14: hyapp.activity.v1.MarkInboxSectionReadResponse + (*DeleteInboxMessageRequest)(nil), // 15: hyapp.activity.v1.DeleteInboxMessageRequest + (*DeleteInboxMessageResponse)(nil), // 16: hyapp.activity.v1.DeleteInboxMessageResponse + (*CreateInboxMessageRequest)(nil), // 17: hyapp.activity.v1.CreateInboxMessageRequest + (*CreateInboxMessageResponse)(nil), // 18: hyapp.activity.v1.CreateInboxMessageResponse + (*CreateFanoutJobRequest)(nil), // 19: hyapp.activity.v1.CreateFanoutJobRequest + (*CreateFanoutJobResponse)(nil), // 20: hyapp.activity.v1.CreateFanoutJobResponse + (*CronBatchRequest)(nil), // 21: hyapp.activity.v1.CronBatchRequest + (*CronBatchResponse)(nil), // 22: hyapp.activity.v1.CronBatchResponse + (*TaskItem)(nil), // 23: hyapp.activity.v1.TaskItem + (*TaskSection)(nil), // 24: hyapp.activity.v1.TaskSection + (*ListUserTasksRequest)(nil), // 25: hyapp.activity.v1.ListUserTasksRequest + (*ListUserTasksResponse)(nil), // 26: hyapp.activity.v1.ListUserTasksResponse + (*ClaimTaskRewardRequest)(nil), // 27: hyapp.activity.v1.ClaimTaskRewardRequest + (*ClaimTaskRewardResponse)(nil), // 28: hyapp.activity.v1.ClaimTaskRewardResponse + (*ConsumeTaskEventRequest)(nil), // 29: hyapp.activity.v1.ConsumeTaskEventRequest + (*ConsumeTaskEventResponse)(nil), // 30: hyapp.activity.v1.ConsumeTaskEventResponse + (*BroadcastJoinGroup)(nil), // 31: hyapp.activity.v1.BroadcastJoinGroup + (*EnsureBroadcastGroupsRequest)(nil), // 32: hyapp.activity.v1.EnsureBroadcastGroupsRequest + (*EnsureBroadcastGroupsResponse)(nil), // 33: hyapp.activity.v1.EnsureBroadcastGroupsResponse + (*PublishRegionBroadcastRequest)(nil), // 34: hyapp.activity.v1.PublishRegionBroadcastRequest + (*PublishGlobalBroadcastRequest)(nil), // 35: hyapp.activity.v1.PublishGlobalBroadcastRequest + (*PublishBroadcastResponse)(nil), // 36: hyapp.activity.v1.PublishBroadcastResponse + (*RemoveRegionBroadcastMemberRequest)(nil), // 37: hyapp.activity.v1.RemoveRegionBroadcastMemberRequest + (*RemoveRegionBroadcastMemberResponse)(nil), // 38: hyapp.activity.v1.RemoveRegionBroadcastMemberResponse + (*ProcessBroadcastOutboxBatchResponse)(nil), // 39: hyapp.activity.v1.ProcessBroadcastOutboxBatchResponse + (*ConsumeRoomEventRequest)(nil), // 40: hyapp.activity.v1.ConsumeRoomEventRequest + (*ConsumeRoomEventResponse)(nil), // 41: hyapp.activity.v1.ConsumeRoomEventResponse + (*TaskDefinition)(nil), // 42: hyapp.activity.v1.TaskDefinition + (*ListTaskDefinitionsRequest)(nil), // 43: hyapp.activity.v1.ListTaskDefinitionsRequest + (*ListTaskDefinitionsResponse)(nil), // 44: hyapp.activity.v1.ListTaskDefinitionsResponse + (*UpsertTaskDefinitionRequest)(nil), // 45: hyapp.activity.v1.UpsertTaskDefinitionRequest + (*UpsertTaskDefinitionResponse)(nil), // 46: hyapp.activity.v1.UpsertTaskDefinitionResponse + (*SetTaskDefinitionStatusRequest)(nil), // 47: hyapp.activity.v1.SetTaskDefinitionStatusRequest + (*SetTaskDefinitionStatusResponse)(nil), // 48: hyapp.activity.v1.SetTaskDefinitionStatusResponse + (*v1.EventEnvelope)(nil), // 49: hyapp.events.room.v1.EventEnvelope } var file_proto_activity_v1_activity_proto_depIdxs = []int32{ 0, // 0: hyapp.activity.v1.PingActivityRequest.meta:type_name -> hyapp.activity.v1.RequestMeta @@ -3738,49 +4678,67 @@ var file_proto_activity_v1_activity_proto_depIdxs = []int32{ 24, // 14: hyapp.activity.v1.ListUserTasksResponse.sections:type_name -> hyapp.activity.v1.TaskSection 0, // 15: hyapp.activity.v1.ClaimTaskRewardRequest.meta:type_name -> hyapp.activity.v1.RequestMeta 0, // 16: hyapp.activity.v1.ConsumeTaskEventRequest.meta:type_name -> hyapp.activity.v1.RequestMeta - 0, // 17: hyapp.activity.v1.ListTaskDefinitionsRequest.meta:type_name -> hyapp.activity.v1.RequestMeta - 31, // 18: hyapp.activity.v1.ListTaskDefinitionsResponse.tasks:type_name -> hyapp.activity.v1.TaskDefinition - 0, // 19: hyapp.activity.v1.UpsertTaskDefinitionRequest.meta:type_name -> hyapp.activity.v1.RequestMeta - 31, // 20: hyapp.activity.v1.UpsertTaskDefinitionResponse.task:type_name -> hyapp.activity.v1.TaskDefinition - 0, // 21: hyapp.activity.v1.SetTaskDefinitionStatusRequest.meta:type_name -> hyapp.activity.v1.RequestMeta - 31, // 22: hyapp.activity.v1.SetTaskDefinitionStatusResponse.task:type_name -> hyapp.activity.v1.TaskDefinition - 1, // 23: hyapp.activity.v1.ActivityService.PingActivity:input_type -> hyapp.activity.v1.PingActivityRequest - 3, // 24: hyapp.activity.v1.ActivityService.GetActivityStatus:input_type -> hyapp.activity.v1.GetActivityStatusRequest - 6, // 25: hyapp.activity.v1.MessageInboxService.ListMessageTabs:input_type -> hyapp.activity.v1.ListMessageTabsRequest - 9, // 26: hyapp.activity.v1.MessageInboxService.ListInboxMessages:input_type -> hyapp.activity.v1.ListInboxMessagesRequest - 11, // 27: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:input_type -> hyapp.activity.v1.MarkInboxMessageReadRequest - 13, // 28: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:input_type -> hyapp.activity.v1.MarkInboxSectionReadRequest - 15, // 29: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:input_type -> hyapp.activity.v1.DeleteInboxMessageRequest - 17, // 30: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:input_type -> hyapp.activity.v1.CreateInboxMessageRequest - 19, // 31: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:input_type -> hyapp.activity.v1.CreateFanoutJobRequest - 21, // 32: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:input_type -> hyapp.activity.v1.CronBatchRequest - 25, // 33: hyapp.activity.v1.TaskService.ListUserTasks:input_type -> hyapp.activity.v1.ListUserTasksRequest - 27, // 34: hyapp.activity.v1.TaskService.ClaimTaskReward:input_type -> hyapp.activity.v1.ClaimTaskRewardRequest - 29, // 35: hyapp.activity.v1.TaskService.ConsumeTaskEvent:input_type -> hyapp.activity.v1.ConsumeTaskEventRequest - 32, // 36: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:input_type -> hyapp.activity.v1.ListTaskDefinitionsRequest - 34, // 37: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:input_type -> hyapp.activity.v1.UpsertTaskDefinitionRequest - 36, // 38: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:input_type -> hyapp.activity.v1.SetTaskDefinitionStatusRequest - 2, // 39: hyapp.activity.v1.ActivityService.PingActivity:output_type -> hyapp.activity.v1.PingActivityResponse - 4, // 40: hyapp.activity.v1.ActivityService.GetActivityStatus:output_type -> hyapp.activity.v1.GetActivityStatusResponse - 7, // 41: hyapp.activity.v1.MessageInboxService.ListMessageTabs:output_type -> hyapp.activity.v1.ListMessageTabsResponse - 10, // 42: hyapp.activity.v1.MessageInboxService.ListInboxMessages:output_type -> hyapp.activity.v1.ListInboxMessagesResponse - 12, // 43: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:output_type -> hyapp.activity.v1.MarkInboxMessageReadResponse - 14, // 44: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:output_type -> hyapp.activity.v1.MarkInboxSectionReadResponse - 16, // 45: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:output_type -> hyapp.activity.v1.DeleteInboxMessageResponse - 18, // 46: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:output_type -> hyapp.activity.v1.CreateInboxMessageResponse - 20, // 47: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:output_type -> hyapp.activity.v1.CreateFanoutJobResponse - 22, // 48: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:output_type -> hyapp.activity.v1.CronBatchResponse - 26, // 49: hyapp.activity.v1.TaskService.ListUserTasks:output_type -> hyapp.activity.v1.ListUserTasksResponse - 28, // 50: hyapp.activity.v1.TaskService.ClaimTaskReward:output_type -> hyapp.activity.v1.ClaimTaskRewardResponse - 30, // 51: hyapp.activity.v1.TaskService.ConsumeTaskEvent:output_type -> hyapp.activity.v1.ConsumeTaskEventResponse - 33, // 52: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:output_type -> hyapp.activity.v1.ListTaskDefinitionsResponse - 35, // 53: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:output_type -> hyapp.activity.v1.UpsertTaskDefinitionResponse - 37, // 54: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:output_type -> hyapp.activity.v1.SetTaskDefinitionStatusResponse - 39, // [39:55] is the sub-list for method output_type - 23, // [23:39] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name + 0, // 17: hyapp.activity.v1.EnsureBroadcastGroupsRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 0, // 18: hyapp.activity.v1.PublishRegionBroadcastRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 0, // 19: hyapp.activity.v1.PublishGlobalBroadcastRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 0, // 20: hyapp.activity.v1.RemoveRegionBroadcastMemberRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 0, // 21: hyapp.activity.v1.ConsumeRoomEventRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 49, // 22: hyapp.activity.v1.ConsumeRoomEventRequest.envelope:type_name -> hyapp.events.room.v1.EventEnvelope + 0, // 23: hyapp.activity.v1.ListTaskDefinitionsRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 42, // 24: hyapp.activity.v1.ListTaskDefinitionsResponse.tasks:type_name -> hyapp.activity.v1.TaskDefinition + 0, // 25: hyapp.activity.v1.UpsertTaskDefinitionRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 42, // 26: hyapp.activity.v1.UpsertTaskDefinitionResponse.task:type_name -> hyapp.activity.v1.TaskDefinition + 0, // 27: hyapp.activity.v1.SetTaskDefinitionStatusRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 42, // 28: hyapp.activity.v1.SetTaskDefinitionStatusResponse.task:type_name -> hyapp.activity.v1.TaskDefinition + 1, // 29: hyapp.activity.v1.ActivityService.PingActivity:input_type -> hyapp.activity.v1.PingActivityRequest + 3, // 30: hyapp.activity.v1.ActivityService.GetActivityStatus:input_type -> hyapp.activity.v1.GetActivityStatusRequest + 6, // 31: hyapp.activity.v1.MessageInboxService.ListMessageTabs:input_type -> hyapp.activity.v1.ListMessageTabsRequest + 9, // 32: hyapp.activity.v1.MessageInboxService.ListInboxMessages:input_type -> hyapp.activity.v1.ListInboxMessagesRequest + 11, // 33: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:input_type -> hyapp.activity.v1.MarkInboxMessageReadRequest + 13, // 34: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:input_type -> hyapp.activity.v1.MarkInboxSectionReadRequest + 15, // 35: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:input_type -> hyapp.activity.v1.DeleteInboxMessageRequest + 17, // 36: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:input_type -> hyapp.activity.v1.CreateInboxMessageRequest + 19, // 37: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:input_type -> hyapp.activity.v1.CreateFanoutJobRequest + 21, // 38: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:input_type -> hyapp.activity.v1.CronBatchRequest + 25, // 39: hyapp.activity.v1.TaskService.ListUserTasks:input_type -> hyapp.activity.v1.ListUserTasksRequest + 27, // 40: hyapp.activity.v1.TaskService.ClaimTaskReward:input_type -> hyapp.activity.v1.ClaimTaskRewardRequest + 29, // 41: hyapp.activity.v1.TaskService.ConsumeTaskEvent:input_type -> hyapp.activity.v1.ConsumeTaskEventRequest + 32, // 42: hyapp.activity.v1.BroadcastService.EnsureBroadcastGroups:input_type -> hyapp.activity.v1.EnsureBroadcastGroupsRequest + 34, // 43: hyapp.activity.v1.BroadcastService.PublishRegionBroadcast:input_type -> hyapp.activity.v1.PublishRegionBroadcastRequest + 35, // 44: hyapp.activity.v1.BroadcastService.PublishGlobalBroadcast:input_type -> hyapp.activity.v1.PublishGlobalBroadcastRequest + 37, // 45: hyapp.activity.v1.BroadcastService.RemoveRegionBroadcastMember:input_type -> hyapp.activity.v1.RemoveRegionBroadcastMemberRequest + 21, // 46: hyapp.activity.v1.BroadcastService.ProcessBroadcastOutboxBatch:input_type -> hyapp.activity.v1.CronBatchRequest + 40, // 47: hyapp.activity.v1.RoomEventConsumerService.ConsumeRoomEvent:input_type -> hyapp.activity.v1.ConsumeRoomEventRequest + 43, // 48: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:input_type -> hyapp.activity.v1.ListTaskDefinitionsRequest + 45, // 49: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:input_type -> hyapp.activity.v1.UpsertTaskDefinitionRequest + 47, // 50: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:input_type -> hyapp.activity.v1.SetTaskDefinitionStatusRequest + 2, // 51: hyapp.activity.v1.ActivityService.PingActivity:output_type -> hyapp.activity.v1.PingActivityResponse + 4, // 52: hyapp.activity.v1.ActivityService.GetActivityStatus:output_type -> hyapp.activity.v1.GetActivityStatusResponse + 7, // 53: hyapp.activity.v1.MessageInboxService.ListMessageTabs:output_type -> hyapp.activity.v1.ListMessageTabsResponse + 10, // 54: hyapp.activity.v1.MessageInboxService.ListInboxMessages:output_type -> hyapp.activity.v1.ListInboxMessagesResponse + 12, // 55: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:output_type -> hyapp.activity.v1.MarkInboxMessageReadResponse + 14, // 56: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:output_type -> hyapp.activity.v1.MarkInboxSectionReadResponse + 16, // 57: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:output_type -> hyapp.activity.v1.DeleteInboxMessageResponse + 18, // 58: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:output_type -> hyapp.activity.v1.CreateInboxMessageResponse + 20, // 59: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:output_type -> hyapp.activity.v1.CreateFanoutJobResponse + 22, // 60: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:output_type -> hyapp.activity.v1.CronBatchResponse + 26, // 61: hyapp.activity.v1.TaskService.ListUserTasks:output_type -> hyapp.activity.v1.ListUserTasksResponse + 28, // 62: hyapp.activity.v1.TaskService.ClaimTaskReward:output_type -> hyapp.activity.v1.ClaimTaskRewardResponse + 30, // 63: hyapp.activity.v1.TaskService.ConsumeTaskEvent:output_type -> hyapp.activity.v1.ConsumeTaskEventResponse + 33, // 64: hyapp.activity.v1.BroadcastService.EnsureBroadcastGroups:output_type -> hyapp.activity.v1.EnsureBroadcastGroupsResponse + 36, // 65: hyapp.activity.v1.BroadcastService.PublishRegionBroadcast:output_type -> hyapp.activity.v1.PublishBroadcastResponse + 36, // 66: hyapp.activity.v1.BroadcastService.PublishGlobalBroadcast:output_type -> hyapp.activity.v1.PublishBroadcastResponse + 38, // 67: hyapp.activity.v1.BroadcastService.RemoveRegionBroadcastMember:output_type -> hyapp.activity.v1.RemoveRegionBroadcastMemberResponse + 39, // 68: hyapp.activity.v1.BroadcastService.ProcessBroadcastOutboxBatch:output_type -> hyapp.activity.v1.ProcessBroadcastOutboxBatchResponse + 41, // 69: hyapp.activity.v1.RoomEventConsumerService.ConsumeRoomEvent:output_type -> hyapp.activity.v1.ConsumeRoomEventResponse + 44, // 70: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:output_type -> hyapp.activity.v1.ListTaskDefinitionsResponse + 46, // 71: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:output_type -> hyapp.activity.v1.UpsertTaskDefinitionResponse + 48, // 72: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:output_type -> hyapp.activity.v1.SetTaskDefinitionStatusResponse + 51, // [51:73] is the sub-list for method output_type + 29, // [29:51] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_proto_activity_v1_activity_proto_init() } @@ -3788,15 +4746,605 @@ func file_proto_activity_v1_activity_proto_init() { if File_proto_activity_v1_activity_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_proto_activity_v1_activity_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*RequestMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*PingActivityRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*PingActivityResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetActivityStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetActivityStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*MessageTabSection); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*ListMessageTabsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*ListMessageTabsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*InboxMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*ListInboxMessagesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*ListInboxMessagesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*MarkInboxMessageReadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*MarkInboxMessageReadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*MarkInboxSectionReadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*MarkInboxSectionReadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*DeleteInboxMessageRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*DeleteInboxMessageResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*CreateInboxMessageRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*CreateInboxMessageResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*CreateFanoutJobRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[20].Exporter = func(v any, i int) any { + switch v := v.(*CreateFanoutJobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[21].Exporter = func(v any, i int) any { + switch v := v.(*CronBatchRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[22].Exporter = func(v any, i int) any { + switch v := v.(*CronBatchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[23].Exporter = func(v any, i int) any { + switch v := v.(*TaskItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[24].Exporter = func(v any, i int) any { + switch v := v.(*TaskSection); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[25].Exporter = func(v any, i int) any { + switch v := v.(*ListUserTasksRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[26].Exporter = func(v any, i int) any { + switch v := v.(*ListUserTasksResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[27].Exporter = func(v any, i int) any { + switch v := v.(*ClaimTaskRewardRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[28].Exporter = func(v any, i int) any { + switch v := v.(*ClaimTaskRewardResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[29].Exporter = func(v any, i int) any { + switch v := v.(*ConsumeTaskEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[30].Exporter = func(v any, i int) any { + switch v := v.(*ConsumeTaskEventResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[31].Exporter = func(v any, i int) any { + switch v := v.(*BroadcastJoinGroup); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[32].Exporter = func(v any, i int) any { + switch v := v.(*EnsureBroadcastGroupsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[33].Exporter = func(v any, i int) any { + switch v := v.(*EnsureBroadcastGroupsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[34].Exporter = func(v any, i int) any { + switch v := v.(*PublishRegionBroadcastRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[35].Exporter = func(v any, i int) any { + switch v := v.(*PublishGlobalBroadcastRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[36].Exporter = func(v any, i int) any { + switch v := v.(*PublishBroadcastResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[37].Exporter = func(v any, i int) any { + switch v := v.(*RemoveRegionBroadcastMemberRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[38].Exporter = func(v any, i int) any { + switch v := v.(*RemoveRegionBroadcastMemberResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[39].Exporter = func(v any, i int) any { + switch v := v.(*ProcessBroadcastOutboxBatchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[40].Exporter = func(v any, i int) any { + switch v := v.(*ConsumeRoomEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[41].Exporter = func(v any, i int) any { + switch v := v.(*ConsumeRoomEventResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[42].Exporter = func(v any, i int) any { + switch v := v.(*TaskDefinition); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[43].Exporter = func(v any, i int) any { + switch v := v.(*ListTaskDefinitionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[44].Exporter = func(v any, i int) any { + switch v := v.(*ListTaskDefinitionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[45].Exporter = func(v any, i int) any { + switch v := v.(*UpsertTaskDefinitionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[46].Exporter = func(v any, i int) any { + switch v := v.(*UpsertTaskDefinitionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*SetTaskDefinitionStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_activity_v1_activity_proto_msgTypes[48].Exporter = func(v any, i int) any { + switch v := v.(*SetTaskDefinitionStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_activity_v1_activity_proto_rawDesc, NumEnums: 0, - NumMessages: 38, + NumMessages: 49, NumExtensions: 0, - NumServices: 5, + NumServices: 7, }, GoTypes: file_proto_activity_v1_activity_proto_goTypes, DependencyIndexes: file_proto_activity_v1_activity_proto_depIdxs, diff --git a/api/proto/activity/v1/activity.proto b/api/proto/activity/v1/activity.proto index dfcd4706..150668fc 100644 --- a/api/proto/activity/v1/activity.proto +++ b/api/proto/activity/v1/activity.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package hyapp.activity.v1; +import "proto/events/room/v1/events.proto"; + option go_package = "hyapp.local/api/proto/activity/v1;activityv1"; // RequestMeta 是 activity-service 内部 RPC 的最小追踪元信息。 @@ -278,6 +280,75 @@ message ConsumeTaskEventResponse { int32 matched_task_count = 3; } +// BroadcastJoinGroup 是 gateway 下发给客户端的 IM 播报群信息在服务端的同源结构。 +message BroadcastJoinGroup { + string group_id = 1; + string type = 2; + int64 region_id = 3; +} + +message EnsureBroadcastGroupsRequest { + RequestMeta meta = 1; +} + +message EnsureBroadcastGroupsResponse { + int32 ensured_count = 1; +} + +message PublishRegionBroadcastRequest { + RequestMeta meta = 1; + string event_id = 2; + int64 region_id = 3; + string broadcast_type = 4; + string payload_json = 5; +} + +message PublishGlobalBroadcastRequest { + RequestMeta meta = 1; + string event_id = 2; + string broadcast_type = 3; + string payload_json = 4; +} + +message PublishBroadcastResponse { + string event_id = 1; + string group_id = 2; + string status = 3; + bool created = 4; +} + +// RemoveRegionBroadcastMemberRequest 只移除某个用户的旧区域群成员关系,不删除或解散区域群。 +message RemoveRegionBroadcastMemberRequest { + RequestMeta meta = 1; + int64 user_id = 2; + int64 region_id = 3; + string reason = 4; +} + +message RemoveRegionBroadcastMemberResponse { + string group_id = 1; + bool removed = 2; +} + +message ProcessBroadcastOutboxBatchResponse { + int32 claimed_count = 1; + int32 success_count = 2; + int32 failure_count = 3; + bool has_more = 4; +} + +message ConsumeRoomEventRequest { + RequestMeta meta = 1; + hyapp.events.room.v1.EventEnvelope envelope = 2; +} + +message ConsumeRoomEventResponse { + string event_id = 1; + string status = 2; + string broadcast_event_id = 3; + bool broadcast_created = 4; +} + // TaskDefinition 是后台管理任务配置的当前版本读模型。 message TaskDefinition { string task_id = 1; @@ -381,6 +452,20 @@ service TaskService { rpc ConsumeTaskEvent(ConsumeTaskEventRequest) returns (ConsumeTaskEventResponse); } +// BroadcastService owns server-side Tencent IM global/region broadcast delivery. +service BroadcastService { + rpc EnsureBroadcastGroups(EnsureBroadcastGroupsRequest) returns (EnsureBroadcastGroupsResponse); + rpc PublishRegionBroadcast(PublishRegionBroadcastRequest) returns (PublishBroadcastResponse); + rpc PublishGlobalBroadcast(PublishGlobalBroadcastRequest) returns (PublishBroadcastResponse); + rpc RemoveRegionBroadcastMember(RemoveRegionBroadcastMemberRequest) returns (RemoveRegionBroadcastMemberResponse); + rpc ProcessBroadcastOutboxBatch(CronBatchRequest) returns (ProcessBroadcastOutboxBatchResponse); +} + +// RoomEventConsumerService consumes room-service outbox facts without owning Room Cell state. +service RoomEventConsumerService { + rpc ConsumeRoomEvent(ConsumeRoomEventRequest) returns (ConsumeRoomEventResponse); +} + // AdminTaskService 是后台活动管理访问 activity-service 的唯一任务配置入口。 service AdminTaskService { rpc ListTaskDefinitions(ListTaskDefinitionsRequest) returns (ListTaskDefinitionsResponse); diff --git a/api/proto/activity/v1/activity_grpc.pb.go b/api/proto/activity/v1/activity_grpc.pb.go index dfe4b8fc..de0125e4 100644 --- a/api/proto/activity/v1/activity_grpc.pb.go +++ b/api/proto/activity/v1/activity_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v4.25.3 +// - protoc v5.29.2 // source: proto/activity/v1/activity.proto package activityv1 @@ -784,6 +784,371 @@ var TaskService_ServiceDesc = grpc.ServiceDesc{ Metadata: "proto/activity/v1/activity.proto", } +const ( + BroadcastService_EnsureBroadcastGroups_FullMethodName = "/hyapp.activity.v1.BroadcastService/EnsureBroadcastGroups" + BroadcastService_PublishRegionBroadcast_FullMethodName = "/hyapp.activity.v1.BroadcastService/PublishRegionBroadcast" + BroadcastService_PublishGlobalBroadcast_FullMethodName = "/hyapp.activity.v1.BroadcastService/PublishGlobalBroadcast" + BroadcastService_RemoveRegionBroadcastMember_FullMethodName = "/hyapp.activity.v1.BroadcastService/RemoveRegionBroadcastMember" + BroadcastService_ProcessBroadcastOutboxBatch_FullMethodName = "/hyapp.activity.v1.BroadcastService/ProcessBroadcastOutboxBatch" +) + +// BroadcastServiceClient is the client API for BroadcastService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// BroadcastService owns server-side Tencent IM global/region broadcast delivery. +type BroadcastServiceClient interface { + EnsureBroadcastGroups(ctx context.Context, in *EnsureBroadcastGroupsRequest, opts ...grpc.CallOption) (*EnsureBroadcastGroupsResponse, error) + PublishRegionBroadcast(ctx context.Context, in *PublishRegionBroadcastRequest, opts ...grpc.CallOption) (*PublishBroadcastResponse, error) + PublishGlobalBroadcast(ctx context.Context, in *PublishGlobalBroadcastRequest, opts ...grpc.CallOption) (*PublishBroadcastResponse, error) + RemoveRegionBroadcastMember(ctx context.Context, in *RemoveRegionBroadcastMemberRequest, opts ...grpc.CallOption) (*RemoveRegionBroadcastMemberResponse, error) + ProcessBroadcastOutboxBatch(ctx context.Context, in *CronBatchRequest, opts ...grpc.CallOption) (*ProcessBroadcastOutboxBatchResponse, error) +} + +type broadcastServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewBroadcastServiceClient(cc grpc.ClientConnInterface) BroadcastServiceClient { + return &broadcastServiceClient{cc} +} + +func (c *broadcastServiceClient) EnsureBroadcastGroups(ctx context.Context, in *EnsureBroadcastGroupsRequest, opts ...grpc.CallOption) (*EnsureBroadcastGroupsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(EnsureBroadcastGroupsResponse) + err := c.cc.Invoke(ctx, BroadcastService_EnsureBroadcastGroups_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *broadcastServiceClient) PublishRegionBroadcast(ctx context.Context, in *PublishRegionBroadcastRequest, opts ...grpc.CallOption) (*PublishBroadcastResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PublishBroadcastResponse) + err := c.cc.Invoke(ctx, BroadcastService_PublishRegionBroadcast_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *broadcastServiceClient) PublishGlobalBroadcast(ctx context.Context, in *PublishGlobalBroadcastRequest, opts ...grpc.CallOption) (*PublishBroadcastResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PublishBroadcastResponse) + err := c.cc.Invoke(ctx, BroadcastService_PublishGlobalBroadcast_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *broadcastServiceClient) RemoveRegionBroadcastMember(ctx context.Context, in *RemoveRegionBroadcastMemberRequest, opts ...grpc.CallOption) (*RemoveRegionBroadcastMemberResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RemoveRegionBroadcastMemberResponse) + err := c.cc.Invoke(ctx, BroadcastService_RemoveRegionBroadcastMember_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *broadcastServiceClient) ProcessBroadcastOutboxBatch(ctx context.Context, in *CronBatchRequest, opts ...grpc.CallOption) (*ProcessBroadcastOutboxBatchResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ProcessBroadcastOutboxBatchResponse) + err := c.cc.Invoke(ctx, BroadcastService_ProcessBroadcastOutboxBatch_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// BroadcastServiceServer is the server API for BroadcastService service. +// All implementations must embed UnimplementedBroadcastServiceServer +// for forward compatibility. +// +// BroadcastService owns server-side Tencent IM global/region broadcast delivery. +type BroadcastServiceServer interface { + EnsureBroadcastGroups(context.Context, *EnsureBroadcastGroupsRequest) (*EnsureBroadcastGroupsResponse, error) + PublishRegionBroadcast(context.Context, *PublishRegionBroadcastRequest) (*PublishBroadcastResponse, error) + PublishGlobalBroadcast(context.Context, *PublishGlobalBroadcastRequest) (*PublishBroadcastResponse, error) + RemoveRegionBroadcastMember(context.Context, *RemoveRegionBroadcastMemberRequest) (*RemoveRegionBroadcastMemberResponse, error) + ProcessBroadcastOutboxBatch(context.Context, *CronBatchRequest) (*ProcessBroadcastOutboxBatchResponse, error) + mustEmbedUnimplementedBroadcastServiceServer() +} + +// UnimplementedBroadcastServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedBroadcastServiceServer struct{} + +func (UnimplementedBroadcastServiceServer) EnsureBroadcastGroups(context.Context, *EnsureBroadcastGroupsRequest) (*EnsureBroadcastGroupsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EnsureBroadcastGroups not implemented") +} +func (UnimplementedBroadcastServiceServer) PublishRegionBroadcast(context.Context, *PublishRegionBroadcastRequest) (*PublishBroadcastResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PublishRegionBroadcast not implemented") +} +func (UnimplementedBroadcastServiceServer) PublishGlobalBroadcast(context.Context, *PublishGlobalBroadcastRequest) (*PublishBroadcastResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PublishGlobalBroadcast not implemented") +} +func (UnimplementedBroadcastServiceServer) RemoveRegionBroadcastMember(context.Context, *RemoveRegionBroadcastMemberRequest) (*RemoveRegionBroadcastMemberResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveRegionBroadcastMember not implemented") +} +func (UnimplementedBroadcastServiceServer) ProcessBroadcastOutboxBatch(context.Context, *CronBatchRequest) (*ProcessBroadcastOutboxBatchResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ProcessBroadcastOutboxBatch not implemented") +} +func (UnimplementedBroadcastServiceServer) mustEmbedUnimplementedBroadcastServiceServer() {} +func (UnimplementedBroadcastServiceServer) testEmbeddedByValue() {} + +// UnsafeBroadcastServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to BroadcastServiceServer will +// result in compilation errors. +type UnsafeBroadcastServiceServer interface { + mustEmbedUnimplementedBroadcastServiceServer() +} + +func RegisterBroadcastServiceServer(s grpc.ServiceRegistrar, srv BroadcastServiceServer) { + // If the following call pancis, it indicates UnimplementedBroadcastServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&BroadcastService_ServiceDesc, srv) +} + +func _BroadcastService_EnsureBroadcastGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EnsureBroadcastGroupsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BroadcastServiceServer).EnsureBroadcastGroups(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: BroadcastService_EnsureBroadcastGroups_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BroadcastServiceServer).EnsureBroadcastGroups(ctx, req.(*EnsureBroadcastGroupsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BroadcastService_PublishRegionBroadcast_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PublishRegionBroadcastRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BroadcastServiceServer).PublishRegionBroadcast(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: BroadcastService_PublishRegionBroadcast_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BroadcastServiceServer).PublishRegionBroadcast(ctx, req.(*PublishRegionBroadcastRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BroadcastService_PublishGlobalBroadcast_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PublishGlobalBroadcastRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BroadcastServiceServer).PublishGlobalBroadcast(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: BroadcastService_PublishGlobalBroadcast_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BroadcastServiceServer).PublishGlobalBroadcast(ctx, req.(*PublishGlobalBroadcastRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BroadcastService_RemoveRegionBroadcastMember_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveRegionBroadcastMemberRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BroadcastServiceServer).RemoveRegionBroadcastMember(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: BroadcastService_RemoveRegionBroadcastMember_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BroadcastServiceServer).RemoveRegionBroadcastMember(ctx, req.(*RemoveRegionBroadcastMemberRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BroadcastService_ProcessBroadcastOutboxBatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CronBatchRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BroadcastServiceServer).ProcessBroadcastOutboxBatch(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: BroadcastService_ProcessBroadcastOutboxBatch_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BroadcastServiceServer).ProcessBroadcastOutboxBatch(ctx, req.(*CronBatchRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// BroadcastService_ServiceDesc is the grpc.ServiceDesc for BroadcastService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var BroadcastService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "hyapp.activity.v1.BroadcastService", + HandlerType: (*BroadcastServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "EnsureBroadcastGroups", + Handler: _BroadcastService_EnsureBroadcastGroups_Handler, + }, + { + MethodName: "PublishRegionBroadcast", + Handler: _BroadcastService_PublishRegionBroadcast_Handler, + }, + { + MethodName: "PublishGlobalBroadcast", + Handler: _BroadcastService_PublishGlobalBroadcast_Handler, + }, + { + MethodName: "RemoveRegionBroadcastMember", + Handler: _BroadcastService_RemoveRegionBroadcastMember_Handler, + }, + { + MethodName: "ProcessBroadcastOutboxBatch", + Handler: _BroadcastService_ProcessBroadcastOutboxBatch_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/activity/v1/activity.proto", +} + +const ( + RoomEventConsumerService_ConsumeRoomEvent_FullMethodName = "/hyapp.activity.v1.RoomEventConsumerService/ConsumeRoomEvent" +) + +// RoomEventConsumerServiceClient is the client API for RoomEventConsumerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// RoomEventConsumerService consumes room-service outbox facts without owning Room Cell state. +type RoomEventConsumerServiceClient interface { + ConsumeRoomEvent(ctx context.Context, in *ConsumeRoomEventRequest, opts ...grpc.CallOption) (*ConsumeRoomEventResponse, error) +} + +type roomEventConsumerServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewRoomEventConsumerServiceClient(cc grpc.ClientConnInterface) RoomEventConsumerServiceClient { + return &roomEventConsumerServiceClient{cc} +} + +func (c *roomEventConsumerServiceClient) ConsumeRoomEvent(ctx context.Context, in *ConsumeRoomEventRequest, opts ...grpc.CallOption) (*ConsumeRoomEventResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ConsumeRoomEventResponse) + err := c.cc.Invoke(ctx, RoomEventConsumerService_ConsumeRoomEvent_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RoomEventConsumerServiceServer is the server API for RoomEventConsumerService service. +// All implementations must embed UnimplementedRoomEventConsumerServiceServer +// for forward compatibility. +// +// RoomEventConsumerService consumes room-service outbox facts without owning Room Cell state. +type RoomEventConsumerServiceServer interface { + ConsumeRoomEvent(context.Context, *ConsumeRoomEventRequest) (*ConsumeRoomEventResponse, error) + mustEmbedUnimplementedRoomEventConsumerServiceServer() +} + +// UnimplementedRoomEventConsumerServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedRoomEventConsumerServiceServer struct{} + +func (UnimplementedRoomEventConsumerServiceServer) ConsumeRoomEvent(context.Context, *ConsumeRoomEventRequest) (*ConsumeRoomEventResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConsumeRoomEvent not implemented") +} +func (UnimplementedRoomEventConsumerServiceServer) mustEmbedUnimplementedRoomEventConsumerServiceServer() { +} +func (UnimplementedRoomEventConsumerServiceServer) testEmbeddedByValue() {} + +// UnsafeRoomEventConsumerServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to RoomEventConsumerServiceServer will +// result in compilation errors. +type UnsafeRoomEventConsumerServiceServer interface { + mustEmbedUnimplementedRoomEventConsumerServiceServer() +} + +func RegisterRoomEventConsumerServiceServer(s grpc.ServiceRegistrar, srv RoomEventConsumerServiceServer) { + // If the following call pancis, it indicates UnimplementedRoomEventConsumerServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&RoomEventConsumerService_ServiceDesc, srv) +} + +func _RoomEventConsumerService_ConsumeRoomEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConsumeRoomEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoomEventConsumerServiceServer).ConsumeRoomEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RoomEventConsumerService_ConsumeRoomEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoomEventConsumerServiceServer).ConsumeRoomEvent(ctx, req.(*ConsumeRoomEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// RoomEventConsumerService_ServiceDesc is the grpc.ServiceDesc for RoomEventConsumerService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var RoomEventConsumerService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "hyapp.activity.v1.RoomEventConsumerService", + HandlerType: (*RoomEventConsumerServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ConsumeRoomEvent", + Handler: _RoomEventConsumerService_ConsumeRoomEvent_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/activity/v1/activity.proto", +} + const ( AdminTaskService_ListTaskDefinitions_FullMethodName = "/hyapp.activity.v1.AdminTaskService/ListTaskDefinitions" AdminTaskService_UpsertTaskDefinition_FullMethodName = "/hyapp.activity.v1.AdminTaskService/UpsertTaskDefinition" diff --git a/api/proto/events/room/v1/events.pb.go b/api/proto/events/room/v1/events.pb.go index 19355143..3396c61d 100644 --- a/api/proto/events/room/v1/events.pb.go +++ b/api/proto/events/room/v1/events.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 -// protoc v4.25.3 +// protoc-gen-go v1.34.2 +// protoc v5.29.2 // source: proto/events/room/v1/events.proto package roomeventsv1 @@ -38,9 +38,11 @@ type EventEnvelope struct { func (x *EventEnvelope) Reset() { *x = EventEnvelope{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *EventEnvelope) String() string { @@ -51,7 +53,7 @@ func (*EventEnvelope) ProtoMessage() {} func (x *EventEnvelope) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -133,9 +135,11 @@ type RoomCreated struct { func (x *RoomCreated) Reset() { *x = RoomCreated{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomCreated) String() string { @@ -146,7 +150,7 @@ func (*RoomCreated) ProtoMessage() {} func (x *RoomCreated) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -222,9 +226,11 @@ type RoomUserJoined struct { func (x *RoomUserJoined) Reset() { *x = RoomUserJoined{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomUserJoined) String() string { @@ -235,7 +241,7 @@ func (*RoomUserJoined) ProtoMessage() {} func (x *RoomUserJoined) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -275,9 +281,11 @@ type RoomUserLeft struct { func (x *RoomUserLeft) Reset() { *x = RoomUserLeft{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomUserLeft) String() string { @@ -288,7 +296,7 @@ func (*RoomUserLeft) ProtoMessage() {} func (x *RoomUserLeft) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -322,9 +330,11 @@ type RoomClosed struct { func (x *RoomClosed) Reset() { *x = RoomClosed{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomClosed) String() string { @@ -335,7 +345,7 @@ func (*RoomClosed) ProtoMessage() {} func (x *RoomClosed) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -387,9 +397,11 @@ type RoomMicChanged struct { func (x *RoomMicChanged) Reset() { *x = RoomMicChanged{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomMicChanged) String() string { @@ -400,7 +412,7 @@ func (*RoomMicChanged) ProtoMessage() {} func (x *RoomMicChanged) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -498,9 +510,11 @@ type RoomMicSeatLocked struct { func (x *RoomMicSeatLocked) Reset() { *x = RoomMicSeatLocked{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomMicSeatLocked) String() string { @@ -511,7 +525,7 @@ func (*RoomMicSeatLocked) ProtoMessage() {} func (x *RoomMicSeatLocked) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -559,9 +573,11 @@ type RoomChatEnabledChanged struct { func (x *RoomChatEnabledChanged) Reset() { *x = RoomChatEnabledChanged{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomChatEnabledChanged) String() string { @@ -572,7 +588,7 @@ func (*RoomChatEnabledChanged) ProtoMessage() {} func (x *RoomChatEnabledChanged) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -614,9 +630,11 @@ type RoomAdminChanged struct { func (x *RoomAdminChanged) Reset() { *x = RoomAdminChanged{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomAdminChanged) String() string { @@ -627,7 +645,7 @@ func (*RoomAdminChanged) ProtoMessage() {} func (x *RoomAdminChanged) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -676,9 +694,11 @@ type RoomHostTransferred struct { func (x *RoomHostTransferred) Reset() { *x = RoomHostTransferred{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomHostTransferred) String() string { @@ -689,7 +709,7 @@ func (*RoomHostTransferred) ProtoMessage() {} func (x *RoomHostTransferred) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -738,9 +758,11 @@ type RoomUserMuted struct { func (x *RoomUserMuted) Reset() { *x = RoomUserMuted{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomUserMuted) String() string { @@ -751,7 +773,7 @@ func (*RoomUserMuted) ProtoMessage() {} func (x *RoomUserMuted) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[10] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -799,9 +821,11 @@ type RoomUserKicked struct { func (x *RoomUserKicked) Reset() { *x = RoomUserKicked{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomUserKicked) String() string { @@ -812,7 +836,7 @@ func (*RoomUserKicked) ProtoMessage() {} func (x *RoomUserKicked) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[11] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -853,9 +877,11 @@ type RoomUserUnbanned struct { func (x *RoomUserUnbanned) Reset() { *x = RoomUserUnbanned{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomUserUnbanned) String() string { @@ -866,7 +892,7 @@ func (*RoomUserUnbanned) ProtoMessage() {} func (x *RoomUserUnbanned) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[12] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -907,13 +933,17 @@ type RoomGiftSent struct { GiftCount int32 `protobuf:"varint,4,opt,name=gift_count,json=giftCount,proto3" json:"gift_count,omitempty"` GiftValue int64 `protobuf:"varint,5,opt,name=gift_value,json=giftValue,proto3" json:"gift_value,omitempty"` BillingReceiptId string `protobuf:"bytes,6,opt,name=billing_receipt_id,json=billingReceiptId,proto3" json:"billing_receipt_id,omitempty"` + VisibleRegionId int64 `protobuf:"varint,7,opt,name=visible_region_id,json=visibleRegionId,proto3" json:"visible_region_id,omitempty"` + CommandId string `protobuf:"bytes,8,opt,name=command_id,json=commandId,proto3" json:"command_id,omitempty"` } func (x *RoomGiftSent) Reset() { *x = RoomGiftSent{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomGiftSent) String() string { @@ -924,7 +954,7 @@ func (*RoomGiftSent) ProtoMessage() {} func (x *RoomGiftSent) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[13] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -981,6 +1011,20 @@ func (x *RoomGiftSent) GetBillingReceiptId() string { return "" } +func (x *RoomGiftSent) GetVisibleRegionId() int64 { + if x != nil { + return x.VisibleRegionId + } + return 0 +} + +func (x *RoomGiftSent) GetCommandId() string { + if x != nil { + return x.CommandId + } + return "" +} + // RoomHeatChanged 表达热度变化结果。 type RoomHeatChanged struct { state protoimpl.MessageState @@ -993,9 +1037,11 @@ type RoomHeatChanged struct { func (x *RoomHeatChanged) Reset() { *x = RoomHeatChanged{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomHeatChanged) String() string { @@ -1006,7 +1052,7 @@ func (*RoomHeatChanged) ProtoMessage() {} func (x *RoomHeatChanged) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[14] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1048,9 +1094,11 @@ type RoomRankChanged struct { func (x *RoomRankChanged) Reset() { *x = RoomRankChanged{} - mi := &file_proto_events_room_v1_events_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_events_room_v1_events_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomRankChanged) String() string { @@ -1061,7 +1109,7 @@ func (*RoomRankChanged) ProtoMessage() {} func (x *RoomRankChanged) ProtoReflect() protoreflect.Message { mi := &file_proto_events_room_v1_events_proto_msgTypes[15] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1213,8 +1261,8 @@ var file_proto_events_room_v1_events_proto_rawDesc = []byte{ 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xdf, - 0x01, 0x0a, 0x0c, 0x52, 0x6f, 0x6f, 0x6d, 0x47, 0x69, 0x66, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x12, + 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xaa, + 0x02, 0x0a, 0x0c, 0x52, 0x6f, 0x6f, 0x6d, 0x47, 0x69, 0x66, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, @@ -1228,21 +1276,26 @@ var file_proto_events_room_v1_events_proto_rawDesc = []byte{ 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x49, 0x64, - 0x22, 0x4a, 0x0a, 0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x48, 0x65, 0x61, 0x74, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x74, 0x22, 0x5f, 0x0a, 0x0f, - 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x61, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, - 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x67, 0x69, 0x66, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x67, 0x69, 0x66, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x33, 0x5a, - 0x31, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x72, 0x6f, - 0x6f, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x6f, 0x6f, 0x6d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x2a, 0x0a, 0x11, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x22, 0x4a, 0x0a, 0x0f, 0x52, + 0x6f, 0x6f, 0x6d, 0x48, 0x65, 0x61, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, + 0x65, 0x6c, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, + 0x68, 0x65, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x74, 0x22, 0x5f, 0x0a, 0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x52, + 0x61, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x66, + 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x67, + 0x69, 0x66, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x68, 0x79, 0x61, 0x70, + 0x70, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x72, 0x6f, 0x6f, 0x6d, 0x2f, 0x76, 0x31, + 0x3b, 0x72, 0x6f, 0x6f, 0x6d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1289,6 +1342,200 @@ func file_proto_events_room_v1_events_proto_init() { if File_proto_events_room_v1_events_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_proto_events_room_v1_events_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*EventEnvelope); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*RoomCreated); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*RoomUserJoined); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*RoomUserLeft); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*RoomClosed); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*RoomMicChanged); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*RoomMicSeatLocked); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*RoomChatEnabledChanged); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*RoomAdminChanged); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*RoomHostTransferred); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*RoomUserMuted); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*RoomUserKicked); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*RoomUserUnbanned); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*RoomGiftSent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*RoomHeatChanged); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_events_room_v1_events_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*RoomRankChanged); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/proto/events/room/v1/events.proto b/api/proto/events/room/v1/events.proto index d89949e3..9c36b32c 100644 --- a/api/proto/events/room/v1/events.proto +++ b/api/proto/events/room/v1/events.proto @@ -116,6 +116,8 @@ message RoomGiftSent { int32 gift_count = 4; int64 gift_value = 5; string billing_receipt_id = 6; + int64 visible_region_id = 7; + string command_id = 8; } // RoomHeatChanged 表达热度变化结果。 diff --git a/api/proto/room/v1/room.pb.go b/api/proto/room/v1/room.pb.go index adc82f41..78e35b7a 100644 --- a/api/proto/room/v1/room.pb.go +++ b/api/proto/room/v1/room.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 -// protoc v4.25.3 +// protoc-gen-go v1.34.2 +// protoc v5.29.2 // source: proto/room/v1/room.proto package roomv1 @@ -41,9 +41,11 @@ type RequestMeta struct { func (x *RequestMeta) Reset() { *x = RequestMeta{} - mi := &file_proto_room_v1_room_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RequestMeta) String() string { @@ -54,7 +56,7 @@ func (*RequestMeta) ProtoMessage() {} func (x *RequestMeta) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -138,9 +140,11 @@ type CommandResult struct { func (x *CommandResult) Reset() { *x = CommandResult{} - mi := &file_proto_room_v1_room_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CommandResult) String() string { @@ -151,7 +155,7 @@ func (*CommandResult) ProtoMessage() {} func (x *CommandResult) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -201,9 +205,11 @@ type RoomUser struct { func (x *RoomUser) Reset() { *x = RoomUser{} - mi := &file_proto_room_v1_room_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomUser) String() string { @@ -214,7 +220,7 @@ func (*RoomUser) ProtoMessage() {} func (x *RoomUser) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -280,9 +286,11 @@ type SeatState struct { func (x *SeatState) Reset() { *x = SeatState{} - mi := &file_proto_room_v1_room_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SeatState) String() string { @@ -293,7 +301,7 @@ func (*SeatState) ProtoMessage() {} func (x *SeatState) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -378,9 +386,11 @@ type RankItem struct { func (x *RankItem) Reset() { *x = RankItem{} - mi := &file_proto_room_v1_room_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RankItem) String() string { @@ -391,7 +401,7 @@ func (*RankItem) ProtoMessage() {} func (x *RankItem) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -461,9 +471,11 @@ type RoomSnapshot struct { func (x *RoomSnapshot) Reset() { *x = RoomSnapshot{} - mi := &file_proto_room_v1_room_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomSnapshot) String() string { @@ -474,7 +486,7 @@ func (*RoomSnapshot) ProtoMessage() {} func (x *RoomSnapshot) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -635,9 +647,11 @@ type CreateRoomRequest struct { func (x *CreateRoomRequest) Reset() { *x = CreateRoomRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateRoomRequest) String() string { @@ -648,7 +662,7 @@ func (*CreateRoomRequest) ProtoMessage() {} func (x *CreateRoomRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -731,9 +745,11 @@ type CreateRoomResponse struct { func (x *CreateRoomResponse) Reset() { *x = CreateRoomResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateRoomResponse) String() string { @@ -744,7 +760,7 @@ func (*CreateRoomResponse) ProtoMessage() {} func (x *CreateRoomResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -785,9 +801,11 @@ type JoinRoomRequest struct { func (x *JoinRoomRequest) Reset() { *x = JoinRoomRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *JoinRoomRequest) String() string { @@ -798,7 +816,7 @@ func (*JoinRoomRequest) ProtoMessage() {} func (x *JoinRoomRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -840,9 +858,11 @@ type JoinRoomResponse struct { func (x *JoinRoomResponse) Reset() { *x = JoinRoomResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *JoinRoomResponse) String() string { @@ -853,7 +873,7 @@ func (*JoinRoomResponse) ProtoMessage() {} func (x *JoinRoomResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -901,9 +921,11 @@ type RoomHeartbeatRequest struct { func (x *RoomHeartbeatRequest) Reset() { *x = RoomHeartbeatRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomHeartbeatRequest) String() string { @@ -914,7 +936,7 @@ func (*RoomHeartbeatRequest) ProtoMessage() {} func (x *RoomHeartbeatRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[10] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -949,9 +971,11 @@ type RoomHeartbeatResponse struct { func (x *RoomHeartbeatResponse) Reset() { *x = RoomHeartbeatResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomHeartbeatResponse) String() string { @@ -962,7 +986,7 @@ func (*RoomHeartbeatResponse) ProtoMessage() {} func (x *RoomHeartbeatResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[11] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1009,9 +1033,11 @@ type LeaveRoomRequest struct { func (x *LeaveRoomRequest) Reset() { *x = LeaveRoomRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *LeaveRoomRequest) String() string { @@ -1022,7 +1048,7 @@ func (*LeaveRoomRequest) ProtoMessage() {} func (x *LeaveRoomRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[12] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1056,9 +1082,11 @@ type LeaveRoomResponse struct { func (x *LeaveRoomResponse) Reset() { *x = LeaveRoomResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *LeaveRoomResponse) String() string { @@ -1069,7 +1097,7 @@ func (*LeaveRoomResponse) ProtoMessage() {} func (x *LeaveRoomResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[13] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1110,9 +1138,11 @@ type CloseRoomRequest struct { func (x *CloseRoomRequest) Reset() { *x = CloseRoomRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CloseRoomRequest) String() string { @@ -1123,7 +1153,7 @@ func (*CloseRoomRequest) ProtoMessage() {} func (x *CloseRoomRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[14] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1164,9 +1194,11 @@ type CloseRoomResponse struct { func (x *CloseRoomResponse) Reset() { *x = CloseRoomResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CloseRoomResponse) String() string { @@ -1177,7 +1209,7 @@ func (*CloseRoomResponse) ProtoMessage() {} func (x *CloseRoomResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[15] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1218,9 +1250,11 @@ type MicUpRequest struct { func (x *MicUpRequest) Reset() { *x = MicUpRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MicUpRequest) String() string { @@ -1231,7 +1265,7 @@ func (*MicUpRequest) ProtoMessage() {} func (x *MicUpRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[16] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1275,9 +1309,11 @@ type MicUpResponse struct { func (x *MicUpResponse) Reset() { *x = MicUpResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MicUpResponse) String() string { @@ -1288,7 +1324,7 @@ func (*MicUpResponse) ProtoMessage() {} func (x *MicUpResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[17] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1352,9 +1388,11 @@ type MicDownRequest struct { func (x *MicDownRequest) Reset() { *x = MicDownRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MicDownRequest) String() string { @@ -1365,7 +1403,7 @@ func (*MicDownRequest) ProtoMessage() {} func (x *MicDownRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[18] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1414,9 +1452,11 @@ type MicDownResponse struct { func (x *MicDownResponse) Reset() { *x = MicDownResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MicDownResponse) String() string { @@ -1427,7 +1467,7 @@ func (*MicDownResponse) ProtoMessage() {} func (x *MicDownResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[19] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1476,9 +1516,11 @@ type ChangeMicSeatRequest struct { func (x *ChangeMicSeatRequest) Reset() { *x = ChangeMicSeatRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ChangeMicSeatRequest) String() string { @@ -1489,7 +1531,7 @@ func (*ChangeMicSeatRequest) ProtoMessage() {} func (x *ChangeMicSeatRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[20] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1537,9 +1579,11 @@ type ChangeMicSeatResponse struct { func (x *ChangeMicSeatResponse) Reset() { *x = ChangeMicSeatResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ChangeMicSeatResponse) String() string { @@ -1550,7 +1594,7 @@ func (*ChangeMicSeatResponse) ProtoMessage() {} func (x *ChangeMicSeatResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[21] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1597,9 +1641,11 @@ type ConfirmMicPublishingRequest struct { func (x *ConfirmMicPublishingRequest) Reset() { *x = ConfirmMicPublishingRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ConfirmMicPublishingRequest) String() string { @@ -1610,7 +1656,7 @@ func (*ConfirmMicPublishingRequest) ProtoMessage() {} func (x *ConfirmMicPublishingRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[22] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1680,9 +1726,11 @@ type ConfirmMicPublishingResponse struct { func (x *ConfirmMicPublishingResponse) Reset() { *x = ConfirmMicPublishingResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ConfirmMicPublishingResponse) String() string { @@ -1693,7 +1741,7 @@ func (*ConfirmMicPublishingResponse) ProtoMessage() {} func (x *ConfirmMicPublishingResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[23] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1747,9 +1795,11 @@ type ApplyRTCEventRequest struct { func (x *ApplyRTCEventRequest) Reset() { *x = ApplyRTCEventRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ApplyRTCEventRequest) String() string { @@ -1760,7 +1810,7 @@ func (*ApplyRTCEventRequest) ProtoMessage() {} func (x *ApplyRTCEventRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[24] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1837,9 +1887,11 @@ type ApplyRTCEventResponse struct { func (x *ApplyRTCEventResponse) Reset() { *x = ApplyRTCEventResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ApplyRTCEventResponse) String() string { @@ -1850,7 +1902,7 @@ func (*ApplyRTCEventResponse) ProtoMessage() {} func (x *ApplyRTCEventResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[25] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1899,9 +1951,11 @@ type SetMicSeatLockRequest struct { func (x *SetMicSeatLockRequest) Reset() { *x = SetMicSeatLockRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetMicSeatLockRequest) String() string { @@ -1912,7 +1966,7 @@ func (*SetMicSeatLockRequest) ProtoMessage() {} func (x *SetMicSeatLockRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[26] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1960,9 +2014,11 @@ type SetMicSeatLockResponse struct { func (x *SetMicSeatLockResponse) Reset() { *x = SetMicSeatLockResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetMicSeatLockResponse) String() string { @@ -1973,7 +2029,7 @@ func (*SetMicSeatLockResponse) ProtoMessage() {} func (x *SetMicSeatLockResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[27] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2014,9 +2070,11 @@ type SetChatEnabledRequest struct { func (x *SetChatEnabledRequest) Reset() { *x = SetChatEnabledRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetChatEnabledRequest) String() string { @@ -2027,7 +2085,7 @@ func (*SetChatEnabledRequest) ProtoMessage() {} func (x *SetChatEnabledRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[28] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2068,9 +2126,11 @@ type SetChatEnabledResponse struct { func (x *SetChatEnabledResponse) Reset() { *x = SetChatEnabledResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetChatEnabledResponse) String() string { @@ -2081,7 +2141,7 @@ func (*SetChatEnabledResponse) ProtoMessage() {} func (x *SetChatEnabledResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[29] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2123,9 +2183,11 @@ type SetRoomAdminRequest struct { func (x *SetRoomAdminRequest) Reset() { *x = SetRoomAdminRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetRoomAdminRequest) String() string { @@ -2136,7 +2198,7 @@ func (*SetRoomAdminRequest) ProtoMessage() {} func (x *SetRoomAdminRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[30] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2184,9 +2246,11 @@ type SetRoomAdminResponse struct { func (x *SetRoomAdminResponse) Reset() { *x = SetRoomAdminResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetRoomAdminResponse) String() string { @@ -2197,7 +2261,7 @@ func (*SetRoomAdminResponse) ProtoMessage() {} func (x *SetRoomAdminResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[31] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2238,9 +2302,11 @@ type TransferRoomHostRequest struct { func (x *TransferRoomHostRequest) Reset() { *x = TransferRoomHostRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *TransferRoomHostRequest) String() string { @@ -2251,7 +2317,7 @@ func (*TransferRoomHostRequest) ProtoMessage() {} func (x *TransferRoomHostRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[32] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2292,9 +2358,11 @@ type TransferRoomHostResponse struct { func (x *TransferRoomHostResponse) Reset() { *x = TransferRoomHostResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *TransferRoomHostResponse) String() string { @@ -2305,7 +2373,7 @@ func (*TransferRoomHostResponse) ProtoMessage() {} func (x *TransferRoomHostResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[33] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2347,9 +2415,11 @@ type MuteUserRequest struct { func (x *MuteUserRequest) Reset() { *x = MuteUserRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MuteUserRequest) String() string { @@ -2360,7 +2430,7 @@ func (*MuteUserRequest) ProtoMessage() {} func (x *MuteUserRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[34] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2408,9 +2478,11 @@ type MuteUserResponse struct { func (x *MuteUserResponse) Reset() { *x = MuteUserResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *MuteUserResponse) String() string { @@ -2421,7 +2493,7 @@ func (*MuteUserResponse) ProtoMessage() {} func (x *MuteUserResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[35] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2462,9 +2534,11 @@ type KickUserRequest struct { func (x *KickUserRequest) Reset() { *x = KickUserRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *KickUserRequest) String() string { @@ -2475,7 +2549,7 @@ func (*KickUserRequest) ProtoMessage() {} func (x *KickUserRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[36] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2516,9 +2590,11 @@ type KickUserResponse struct { func (x *KickUserResponse) Reset() { *x = KickUserResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *KickUserResponse) String() string { @@ -2529,7 +2605,7 @@ func (*KickUserResponse) ProtoMessage() {} func (x *KickUserResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[37] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2570,9 +2646,11 @@ type UnbanUserRequest struct { func (x *UnbanUserRequest) Reset() { *x = UnbanUserRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UnbanUserRequest) String() string { @@ -2583,7 +2661,7 @@ func (*UnbanUserRequest) ProtoMessage() {} func (x *UnbanUserRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[38] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2624,9 +2702,11 @@ type UnbanUserResponse struct { func (x *UnbanUserResponse) Reset() { *x = UnbanUserResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UnbanUserResponse) String() string { @@ -2637,7 +2717,7 @@ func (*UnbanUserResponse) ProtoMessage() {} func (x *UnbanUserResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[39] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2680,9 +2760,11 @@ type SendGiftRequest struct { func (x *SendGiftRequest) Reset() { *x = SendGiftRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SendGiftRequest) String() string { @@ -2693,7 +2775,7 @@ func (*SendGiftRequest) ProtoMessage() {} func (x *SendGiftRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[40] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2751,9 +2833,11 @@ type SendGiftResponse struct { func (x *SendGiftResponse) Reset() { *x = SendGiftResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SendGiftResponse) String() string { @@ -2764,7 +2848,7 @@ func (*SendGiftResponse) ProtoMessage() {} func (x *SendGiftResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[41] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2827,9 +2911,11 @@ type CheckSpeakPermissionRequest struct { func (x *CheckSpeakPermissionRequest) Reset() { *x = CheckSpeakPermissionRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[42] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CheckSpeakPermissionRequest) String() string { @@ -2840,7 +2926,7 @@ func (*CheckSpeakPermissionRequest) ProtoMessage() {} func (x *CheckSpeakPermissionRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[42] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2889,9 +2975,11 @@ type CheckSpeakPermissionResponse struct { func (x *CheckSpeakPermissionResponse) Reset() { *x = CheckSpeakPermissionResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CheckSpeakPermissionResponse) String() string { @@ -2902,7 +2990,7 @@ func (*CheckSpeakPermissionResponse) ProtoMessage() {} func (x *CheckSpeakPermissionResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[43] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2953,9 +3041,11 @@ type VerifyRoomPresenceRequest struct { func (x *VerifyRoomPresenceRequest) Reset() { *x = VerifyRoomPresenceRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *VerifyRoomPresenceRequest) String() string { @@ -2966,7 +3056,7 @@ func (*VerifyRoomPresenceRequest) ProtoMessage() {} func (x *VerifyRoomPresenceRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[44] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3029,9 +3119,11 @@ type VerifyRoomPresenceResponse struct { func (x *VerifyRoomPresenceResponse) Reset() { *x = VerifyRoomPresenceResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *VerifyRoomPresenceResponse) String() string { @@ -3042,7 +3134,7 @@ func (*VerifyRoomPresenceResponse) ProtoMessage() {} func (x *VerifyRoomPresenceResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[45] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3096,9 +3188,11 @@ type ListRoomsRequest struct { func (x *ListRoomsRequest) Reset() { *x = ListRoomsRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRoomsRequest) String() string { @@ -3109,7 +3203,7 @@ func (*ListRoomsRequest) ProtoMessage() {} func (x *ListRoomsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[46] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3197,9 +3291,11 @@ type RoomListItem struct { func (x *RoomListItem) Reset() { *x = RoomListItem{} - mi := &file_proto_room_v1_room_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoomListItem) String() string { @@ -3210,7 +3306,7 @@ func (*RoomListItem) ProtoMessage() {} func (x *RoomListItem) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[47] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3335,9 +3431,11 @@ type ListRoomsResponse struct { func (x *ListRoomsResponse) Reset() { *x = ListRoomsResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[48] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRoomsResponse) String() string { @@ -3348,7 +3446,7 @@ func (*ListRoomsResponse) ProtoMessage() {} func (x *ListRoomsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[48] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3390,9 +3488,11 @@ type GetCurrentRoomRequest struct { func (x *GetCurrentRoomRequest) Reset() { *x = GetCurrentRoomRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[49] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetCurrentRoomRequest) String() string { @@ -3403,7 +3503,7 @@ func (*GetCurrentRoomRequest) ProtoMessage() {} func (x *GetCurrentRoomRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[49] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3452,9 +3552,11 @@ type GetCurrentRoomResponse struct { func (x *GetCurrentRoomResponse) Reset() { *x = GetCurrentRoomResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[50] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetCurrentRoomResponse) String() string { @@ -3465,7 +3567,7 @@ func (*GetCurrentRoomResponse) ProtoMessage() {} func (x *GetCurrentRoomResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[50] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3557,9 +3659,11 @@ type GetRoomSnapshotRequest struct { func (x *GetRoomSnapshotRequest) Reset() { *x = GetRoomSnapshotRequest{} - mi := &file_proto_room_v1_room_proto_msgTypes[51] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetRoomSnapshotRequest) String() string { @@ -3570,7 +3674,7 @@ func (*GetRoomSnapshotRequest) ProtoMessage() {} func (x *GetRoomSnapshotRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[51] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3618,9 +3722,11 @@ type GetRoomSnapshotResponse struct { func (x *GetRoomSnapshotResponse) Reset() { *x = GetRoomSnapshotResponse{} - mi := &file_proto_room_v1_room_proto_msgTypes[52] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_room_v1_room_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetRoomSnapshotResponse) String() string { @@ -3631,7 +3737,7 @@ func (*GetRoomSnapshotResponse) ProtoMessage() {} func (x *GetRoomSnapshotResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_room_v1_room_proto_msgTypes[52] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4547,6 +4653,644 @@ func file_proto_room_v1_room_proto_init() { if File_proto_room_v1_room_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_proto_room_v1_room_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*RequestMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*CommandResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*RoomUser); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*SeatState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*RankItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*RoomSnapshot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*CreateRoomRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*CreateRoomResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*JoinRoomRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*JoinRoomResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*RoomHeartbeatRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*RoomHeartbeatResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*LeaveRoomRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*LeaveRoomResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*CloseRoomRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*CloseRoomResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*MicUpRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*MicUpResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*MicDownRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*MicDownResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[20].Exporter = func(v any, i int) any { + switch v := v.(*ChangeMicSeatRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[21].Exporter = func(v any, i int) any { + switch v := v.(*ChangeMicSeatResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[22].Exporter = func(v any, i int) any { + switch v := v.(*ConfirmMicPublishingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[23].Exporter = func(v any, i int) any { + switch v := v.(*ConfirmMicPublishingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[24].Exporter = func(v any, i int) any { + switch v := v.(*ApplyRTCEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[25].Exporter = func(v any, i int) any { + switch v := v.(*ApplyRTCEventResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[26].Exporter = func(v any, i int) any { + switch v := v.(*SetMicSeatLockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[27].Exporter = func(v any, i int) any { + switch v := v.(*SetMicSeatLockResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[28].Exporter = func(v any, i int) any { + switch v := v.(*SetChatEnabledRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[29].Exporter = func(v any, i int) any { + switch v := v.(*SetChatEnabledResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[30].Exporter = func(v any, i int) any { + switch v := v.(*SetRoomAdminRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[31].Exporter = func(v any, i int) any { + switch v := v.(*SetRoomAdminResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[32].Exporter = func(v any, i int) any { + switch v := v.(*TransferRoomHostRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[33].Exporter = func(v any, i int) any { + switch v := v.(*TransferRoomHostResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[34].Exporter = func(v any, i int) any { + switch v := v.(*MuteUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[35].Exporter = func(v any, i int) any { + switch v := v.(*MuteUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[36].Exporter = func(v any, i int) any { + switch v := v.(*KickUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[37].Exporter = func(v any, i int) any { + switch v := v.(*KickUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[38].Exporter = func(v any, i int) any { + switch v := v.(*UnbanUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[39].Exporter = func(v any, i int) any { + switch v := v.(*UnbanUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[40].Exporter = func(v any, i int) any { + switch v := v.(*SendGiftRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[41].Exporter = func(v any, i int) any { + switch v := v.(*SendGiftResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[42].Exporter = func(v any, i int) any { + switch v := v.(*CheckSpeakPermissionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[43].Exporter = func(v any, i int) any { + switch v := v.(*CheckSpeakPermissionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[44].Exporter = func(v any, i int) any { + switch v := v.(*VerifyRoomPresenceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[45].Exporter = func(v any, i int) any { + switch v := v.(*VerifyRoomPresenceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[46].Exporter = func(v any, i int) any { + switch v := v.(*ListRoomsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*RoomListItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[48].Exporter = func(v any, i int) any { + switch v := v.(*ListRoomsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[49].Exporter = func(v any, i int) any { + switch v := v.(*GetCurrentRoomRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[50].Exporter = func(v any, i int) any { + switch v := v.(*GetCurrentRoomResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[51].Exporter = func(v any, i int) any { + switch v := v.(*GetRoomSnapshotRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_room_v1_room_proto_msgTypes[52].Exporter = func(v any, i int) any { + switch v := v.(*GetRoomSnapshotResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/proto/room/v1/room_grpc.pb.go b/api/proto/room/v1/room_grpc.pb.go index be8fe87b..d1ac7979 100644 --- a/api/proto/room/v1/room_grpc.pb.go +++ b/api/proto/room/v1/room_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v4.25.3 +// - protoc v5.29.2 // source: proto/room/v1/room.proto package roomv1 diff --git a/api/proto/user/v1/auth.pb.go b/api/proto/user/v1/auth.pb.go index 46a71686..dabd98a8 100644 --- a/api/proto/user/v1/auth.pb.go +++ b/api/proto/user/v1/auth.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 -// protoc v4.25.3 +// protoc-gen-go v1.34.2 +// protoc v5.29.2 // source: proto/user/v1/auth.proto package userv1 @@ -33,9 +33,11 @@ type LoginPasswordRequest struct { func (x *LoginPasswordRequest) Reset() { *x = LoginPasswordRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *LoginPasswordRequest) String() string { @@ -46,7 +48,7 @@ func (*LoginPasswordRequest) ProtoMessage() {} func (x *LoginPasswordRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -112,9 +114,11 @@ type LoginThirdPartyRequest struct { func (x *LoginThirdPartyRequest) Reset() { *x = LoginThirdPartyRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *LoginThirdPartyRequest) String() string { @@ -125,7 +129,7 @@ func (*LoginThirdPartyRequest) ProtoMessage() {} func (x *LoginThirdPartyRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -294,9 +298,11 @@ type AuthResponse struct { func (x *AuthResponse) Reset() { *x = AuthResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AuthResponse) String() string { @@ -307,7 +313,7 @@ func (*AuthResponse) ProtoMessage() {} func (x *AuthResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -363,9 +369,11 @@ type SetPasswordRequest struct { func (x *SetPasswordRequest) Reset() { *x = SetPasswordRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetPasswordRequest) String() string { @@ -376,7 +384,7 @@ func (*SetPasswordRequest) ProtoMessage() {} func (x *SetPasswordRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -423,9 +431,11 @@ type SetPasswordResponse struct { func (x *SetPasswordResponse) Reset() { *x = SetPasswordResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetPasswordResponse) String() string { @@ -436,7 +446,7 @@ func (*SetPasswordResponse) ProtoMessage() {} func (x *SetPasswordResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -470,9 +480,11 @@ type RefreshTokenRequest struct { func (x *RefreshTokenRequest) Reset() { *x = RefreshTokenRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RefreshTokenRequest) String() string { @@ -483,7 +495,7 @@ func (*RefreshTokenRequest) ProtoMessage() {} func (x *RefreshTokenRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -523,9 +535,11 @@ type RefreshTokenResponse struct { func (x *RefreshTokenResponse) Reset() { *x = RefreshTokenResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RefreshTokenResponse) String() string { @@ -536,7 +550,7 @@ func (*RefreshTokenResponse) ProtoMessage() {} func (x *RefreshTokenResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -571,9 +585,11 @@ type LogoutRequest struct { func (x *LogoutRequest) Reset() { *x = LogoutRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *LogoutRequest) String() string { @@ -584,7 +600,7 @@ func (*LogoutRequest) ProtoMessage() {} func (x *LogoutRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -631,9 +647,11 @@ type LogoutResponse struct { func (x *LogoutResponse) Reset() { *x = LogoutResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *LogoutResponse) String() string { @@ -644,7 +662,7 @@ func (*LogoutResponse) ProtoMessage() {} func (x *LogoutResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -682,9 +700,11 @@ type RecordLoginBlockedRequest struct { func (x *RecordLoginBlockedRequest) Reset() { *x = RecordLoginBlockedRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RecordLoginBlockedRequest) String() string { @@ -695,7 +715,7 @@ func (*RecordLoginBlockedRequest) ProtoMessage() {} func (x *RecordLoginBlockedRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -763,9 +783,11 @@ type RecordLoginBlockedResponse struct { func (x *RecordLoginBlockedResponse) Reset() { *x = RecordLoginBlockedResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_auth_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RecordLoginBlockedResponse) String() string { @@ -776,7 +798,7 @@ func (*RecordLoginBlockedResponse) ProtoMessage() {} func (x *RecordLoginBlockedResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_auth_proto_msgTypes[10] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1017,6 +1039,140 @@ func file_proto_user_v1_auth_proto_init() { return } file_proto_user_v1_user_proto_init() + if !protoimpl.UnsafeEnabled { + file_proto_user_v1_auth_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*LoginPasswordRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*LoginThirdPartyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*AuthResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*SetPasswordRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*SetPasswordResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*RefreshTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*RefreshTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*LogoutRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*LogoutResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*RecordLoginBlockedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_auth_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*RecordLoginBlockedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/proto/user/v1/auth_grpc.pb.go b/api/proto/user/v1/auth_grpc.pb.go index 052bc3b9..0100fe96 100644 --- a/api/proto/user/v1/auth_grpc.pb.go +++ b/api/proto/user/v1/auth_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v4.25.3 +// - protoc v5.29.2 // source: proto/user/v1/auth.proto package userv1 diff --git a/api/proto/user/v1/host.pb.go b/api/proto/user/v1/host.pb.go index bf600401..0f7dca8c 100644 --- a/api/proto/user/v1/host.pb.go +++ b/api/proto/user/v1/host.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 -// protoc v4.25.3 +// protoc-gen-go v1.34.2 +// protoc v5.29.2 // source: proto/user/v1/host.proto package userv1 @@ -39,9 +39,11 @@ type HostProfile struct { func (x *HostProfile) Reset() { *x = HostProfile{} - mi := &file_proto_user_v1_host_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *HostProfile) String() string { @@ -52,7 +54,7 @@ func (*HostProfile) ProtoMessage() {} func (x *HostProfile) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -151,9 +153,11 @@ type Agency struct { func (x *Agency) Reset() { *x = Agency{} - mi := &file_proto_user_v1_host_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Agency) String() string { @@ -164,7 +168,7 @@ func (*Agency) ProtoMessage() {} func (x *Agency) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -274,9 +278,11 @@ type BDProfile struct { func (x *BDProfile) Reset() { *x = BDProfile{} - mi := &file_proto_user_v1_host_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *BDProfile) String() string { @@ -287,7 +293,7 @@ func (*BDProfile) ProtoMessage() {} func (x *BDProfile) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -374,9 +380,11 @@ type CoinSellerProfile struct { func (x *CoinSellerProfile) Reset() { *x = CoinSellerProfile{} - mi := &file_proto_user_v1_host_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CoinSellerProfile) String() string { @@ -387,7 +395,7 @@ func (*CoinSellerProfile) ProtoMessage() {} func (x *CoinSellerProfile) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -466,9 +474,11 @@ type AgencyMembership struct { func (x *AgencyMembership) Reset() { *x = AgencyMembership{} - mi := &file_proto_user_v1_host_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AgencyMembership) String() string { @@ -479,7 +489,7 @@ func (*AgencyMembership) ProtoMessage() {} func (x *AgencyMembership) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -599,9 +609,11 @@ type AgencyApplication struct { func (x *AgencyApplication) Reset() { *x = AgencyApplication{} - mi := &file_proto_user_v1_host_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AgencyApplication) String() string { @@ -612,7 +624,7 @@ func (*AgencyApplication) ProtoMessage() {} func (x *AgencyApplication) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -730,9 +742,11 @@ type RoleInvitation struct { func (x *RoleInvitation) Reset() { *x = RoleInvitation{} - mi := &file_proto_user_v1_host_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RoleInvitation) String() string { @@ -743,7 +757,7 @@ func (*RoleInvitation) ProtoMessage() {} func (x *RoleInvitation) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -883,9 +897,11 @@ type SearchAgenciesRequest struct { func (x *SearchAgenciesRequest) Reset() { *x = SearchAgenciesRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SearchAgenciesRequest) String() string { @@ -896,7 +912,7 @@ func (*SearchAgenciesRequest) ProtoMessage() {} func (x *SearchAgenciesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -949,9 +965,11 @@ type SearchAgenciesResponse struct { func (x *SearchAgenciesResponse) Reset() { *x = SearchAgenciesResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SearchAgenciesResponse) String() string { @@ -962,7 +980,7 @@ func (*SearchAgenciesResponse) ProtoMessage() {} func (x *SearchAgenciesResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -997,9 +1015,11 @@ type ApplyToAgencyRequest struct { func (x *ApplyToAgencyRequest) Reset() { *x = ApplyToAgencyRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ApplyToAgencyRequest) String() string { @@ -1010,7 +1030,7 @@ func (*ApplyToAgencyRequest) ProtoMessage() {} func (x *ApplyToAgencyRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1063,9 +1083,11 @@ type ApplyToAgencyResponse struct { func (x *ApplyToAgencyResponse) Reset() { *x = ApplyToAgencyResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ApplyToAgencyResponse) String() string { @@ -1076,7 +1098,7 @@ func (*ApplyToAgencyResponse) ProtoMessage() {} func (x *ApplyToAgencyResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[10] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1113,9 +1135,11 @@ type ReviewAgencyApplicationRequest struct { func (x *ReviewAgencyApplicationRequest) Reset() { *x = ReviewAgencyApplicationRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ReviewAgencyApplicationRequest) String() string { @@ -1126,7 +1150,7 @@ func (*ReviewAgencyApplicationRequest) ProtoMessage() {} func (x *ReviewAgencyApplicationRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[11] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1195,9 +1219,11 @@ type ReviewAgencyApplicationResponse struct { func (x *ReviewAgencyApplicationResponse) Reset() { *x = ReviewAgencyApplicationResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ReviewAgencyApplicationResponse) String() string { @@ -1208,7 +1234,7 @@ func (*ReviewAgencyApplicationResponse) ProtoMessage() {} func (x *ReviewAgencyApplicationResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[12] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1259,9 +1285,11 @@ type KickAgencyHostRequest struct { func (x *KickAgencyHostRequest) Reset() { *x = KickAgencyHostRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *KickAgencyHostRequest) String() string { @@ -1272,7 +1300,7 @@ func (*KickAgencyHostRequest) ProtoMessage() {} func (x *KickAgencyHostRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[13] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1340,9 +1368,11 @@ type KickAgencyHostResponse struct { func (x *KickAgencyHostResponse) Reset() { *x = KickAgencyHostResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *KickAgencyHostResponse) String() string { @@ -1353,7 +1383,7 @@ func (*KickAgencyHostResponse) ProtoMessage() {} func (x *KickAgencyHostResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[14] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1396,9 +1426,11 @@ type InviteAgencyRequest struct { func (x *InviteAgencyRequest) Reset() { *x = InviteAgencyRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *InviteAgencyRequest) String() string { @@ -1409,7 +1441,7 @@ func (*InviteAgencyRequest) ProtoMessage() {} func (x *InviteAgencyRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[15] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1469,9 +1501,11 @@ type InviteAgencyResponse struct { func (x *InviteAgencyResponse) Reset() { *x = InviteAgencyResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *InviteAgencyResponse) String() string { @@ -1482,7 +1516,7 @@ func (*InviteAgencyResponse) ProtoMessage() {} func (x *InviteAgencyResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[16] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1517,9 +1551,11 @@ type InviteBDRequest struct { func (x *InviteBDRequest) Reset() { *x = InviteBDRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *InviteBDRequest) String() string { @@ -1530,7 +1566,7 @@ func (*InviteBDRequest) ProtoMessage() {} func (x *InviteBDRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[17] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1583,9 +1619,11 @@ type InviteBDResponse struct { func (x *InviteBDResponse) Reset() { *x = InviteBDResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *InviteBDResponse) String() string { @@ -1596,7 +1634,7 @@ func (*InviteBDResponse) ProtoMessage() {} func (x *InviteBDResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[18] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1633,9 +1671,11 @@ type ProcessRoleInvitationRequest struct { func (x *ProcessRoleInvitationRequest) Reset() { *x = ProcessRoleInvitationRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ProcessRoleInvitationRequest) String() string { @@ -1646,7 +1686,7 @@ func (*ProcessRoleInvitationRequest) ProtoMessage() {} func (x *ProcessRoleInvitationRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[19] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1717,9 +1757,11 @@ type ProcessRoleInvitationResponse struct { func (x *ProcessRoleInvitationResponse) Reset() { *x = ProcessRoleInvitationResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ProcessRoleInvitationResponse) String() string { @@ -1730,7 +1772,7 @@ func (*ProcessRoleInvitationResponse) ProtoMessage() {} func (x *ProcessRoleInvitationResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[20] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1791,9 +1833,11 @@ type GetHostProfileRequest struct { func (x *GetHostProfileRequest) Reset() { *x = GetHostProfileRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetHostProfileRequest) String() string { @@ -1804,7 +1848,7 @@ func (*GetHostProfileRequest) ProtoMessage() {} func (x *GetHostProfileRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[21] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1843,9 +1887,11 @@ type GetHostProfileResponse struct { func (x *GetHostProfileResponse) Reset() { *x = GetHostProfileResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetHostProfileResponse) String() string { @@ -1856,7 +1902,7 @@ func (*GetHostProfileResponse) ProtoMessage() {} func (x *GetHostProfileResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[22] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1889,9 +1935,11 @@ type GetBDProfileRequest struct { func (x *GetBDProfileRequest) Reset() { *x = GetBDProfileRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetBDProfileRequest) String() string { @@ -1902,7 +1950,7 @@ func (*GetBDProfileRequest) ProtoMessage() {} func (x *GetBDProfileRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[23] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1941,9 +1989,11 @@ type GetBDProfileResponse struct { func (x *GetBDProfileResponse) Reset() { *x = GetBDProfileResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetBDProfileResponse) String() string { @@ -1954,7 +2004,7 @@ func (*GetBDProfileResponse) ProtoMessage() {} func (x *GetBDProfileResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[24] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1987,9 +2037,11 @@ type GetCoinSellerProfileRequest struct { func (x *GetCoinSellerProfileRequest) Reset() { *x = GetCoinSellerProfileRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetCoinSellerProfileRequest) String() string { @@ -2000,7 +2052,7 @@ func (*GetCoinSellerProfileRequest) ProtoMessage() {} func (x *GetCoinSellerProfileRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[25] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2039,9 +2091,11 @@ type GetCoinSellerProfileResponse struct { func (x *GetCoinSellerProfileResponse) Reset() { *x = GetCoinSellerProfileResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetCoinSellerProfileResponse) String() string { @@ -2052,7 +2106,7 @@ func (*GetCoinSellerProfileResponse) ProtoMessage() {} func (x *GetCoinSellerProfileResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[26] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2086,9 +2140,11 @@ type GetAgencyMembersRequest struct { func (x *GetAgencyMembersRequest) Reset() { *x = GetAgencyMembersRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAgencyMembersRequest) String() string { @@ -2099,7 +2155,7 @@ func (*GetAgencyMembersRequest) ProtoMessage() {} func (x *GetAgencyMembersRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[27] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2145,9 +2201,11 @@ type GetAgencyMembersResponse struct { func (x *GetAgencyMembersResponse) Reset() { *x = GetAgencyMembersResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAgencyMembersResponse) String() string { @@ -2158,7 +2216,7 @@ func (*GetAgencyMembersResponse) ProtoMessage() {} func (x *GetAgencyMembersResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[28] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2192,9 +2250,11 @@ type GetAgencyApplicationsRequest struct { func (x *GetAgencyApplicationsRequest) Reset() { *x = GetAgencyApplicationsRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAgencyApplicationsRequest) String() string { @@ -2205,7 +2265,7 @@ func (*GetAgencyApplicationsRequest) ProtoMessage() {} func (x *GetAgencyApplicationsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[29] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2251,9 +2311,11 @@ type GetAgencyApplicationsResponse struct { func (x *GetAgencyApplicationsResponse) Reset() { *x = GetAgencyApplicationsResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAgencyApplicationsResponse) String() string { @@ -2264,7 +2326,7 @@ func (*GetAgencyApplicationsResponse) ProtoMessage() {} func (x *GetAgencyApplicationsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[30] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2301,9 +2363,11 @@ type CreateBDLeaderRequest struct { func (x *CreateBDLeaderRequest) Reset() { *x = CreateBDLeaderRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateBDLeaderRequest) String() string { @@ -2314,7 +2378,7 @@ func (*CreateBDLeaderRequest) ProtoMessage() {} func (x *CreateBDLeaderRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[31] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2381,9 +2445,11 @@ type CreateBDLeaderResponse struct { func (x *CreateBDLeaderResponse) Reset() { *x = CreateBDLeaderResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateBDLeaderResponse) String() string { @@ -2394,7 +2460,7 @@ func (*CreateBDLeaderResponse) ProtoMessage() {} func (x *CreateBDLeaderResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[32] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2431,9 +2497,11 @@ type CreateBDRequest struct { func (x *CreateBDRequest) Reset() { *x = CreateBDRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateBDRequest) String() string { @@ -2444,7 +2512,7 @@ func (*CreateBDRequest) ProtoMessage() {} func (x *CreateBDRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[33] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2511,9 +2579,11 @@ type CreateBDResponse struct { func (x *CreateBDResponse) Reset() { *x = CreateBDResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateBDResponse) String() string { @@ -2524,7 +2594,7 @@ func (*CreateBDResponse) ProtoMessage() {} func (x *CreateBDResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[34] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2561,9 +2631,11 @@ type SetBDStatusRequest struct { func (x *SetBDStatusRequest) Reset() { *x = SetBDStatusRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetBDStatusRequest) String() string { @@ -2574,7 +2646,7 @@ func (*SetBDStatusRequest) ProtoMessage() {} func (x *SetBDStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[35] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2641,9 +2713,11 @@ type SetBDStatusResponse struct { func (x *SetBDStatusResponse) Reset() { *x = SetBDStatusResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetBDStatusResponse) String() string { @@ -2654,7 +2728,7 @@ func (*SetBDStatusResponse) ProtoMessage() {} func (x *SetBDStatusResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[36] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2690,9 +2764,11 @@ type CreateCoinSellerRequest struct { func (x *CreateCoinSellerRequest) Reset() { *x = CreateCoinSellerRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateCoinSellerRequest) String() string { @@ -2703,7 +2779,7 @@ func (*CreateCoinSellerRequest) ProtoMessage() {} func (x *CreateCoinSellerRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[37] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2763,9 +2839,11 @@ type CreateCoinSellerResponse struct { func (x *CreateCoinSellerResponse) Reset() { *x = CreateCoinSellerResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateCoinSellerResponse) String() string { @@ -2776,7 +2854,7 @@ func (*CreateCoinSellerResponse) ProtoMessage() {} func (x *CreateCoinSellerResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[38] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2813,9 +2891,11 @@ type SetCoinSellerStatusRequest struct { func (x *SetCoinSellerStatusRequest) Reset() { *x = SetCoinSellerStatusRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetCoinSellerStatusRequest) String() string { @@ -2826,7 +2906,7 @@ func (*SetCoinSellerStatusRequest) ProtoMessage() {} func (x *SetCoinSellerStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[39] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2893,9 +2973,11 @@ type SetCoinSellerStatusResponse struct { func (x *SetCoinSellerStatusResponse) Reset() { *x = SetCoinSellerStatusResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetCoinSellerStatusResponse) String() string { @@ -2906,7 +2988,7 @@ func (*SetCoinSellerStatusResponse) ProtoMessage() {} func (x *SetCoinSellerStatusResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[40] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2946,9 +3028,11 @@ type CreateAgencyRequest struct { func (x *CreateAgencyRequest) Reset() { *x = CreateAgencyRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateAgencyRequest) String() string { @@ -2959,7 +3043,7 @@ func (*CreateAgencyRequest) ProtoMessage() {} func (x *CreateAgencyRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[41] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3049,9 +3133,11 @@ type CreateAgencyResponse struct { func (x *CreateAgencyResponse) Reset() { *x = CreateAgencyResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[42] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateAgencyResponse) String() string { @@ -3062,7 +3148,7 @@ func (*CreateAgencyResponse) ProtoMessage() {} func (x *CreateAgencyResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[42] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3112,9 +3198,11 @@ type CloseAgencyRequest struct { func (x *CloseAgencyRequest) Reset() { *x = CloseAgencyRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CloseAgencyRequest) String() string { @@ -3125,7 +3213,7 @@ func (*CloseAgencyRequest) ProtoMessage() {} func (x *CloseAgencyRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[43] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3185,9 +3273,11 @@ type CloseAgencyResponse struct { func (x *CloseAgencyResponse) Reset() { *x = CloseAgencyResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CloseAgencyResponse) String() string { @@ -3198,7 +3288,7 @@ func (*CloseAgencyResponse) ProtoMessage() {} func (x *CloseAgencyResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[44] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3235,9 +3325,11 @@ type SetAgencyJoinEnabledRequest struct { func (x *SetAgencyJoinEnabledRequest) Reset() { *x = SetAgencyJoinEnabledRequest{} - mi := &file_proto_user_v1_host_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetAgencyJoinEnabledRequest) String() string { @@ -3248,7 +3340,7 @@ func (*SetAgencyJoinEnabledRequest) ProtoMessage() {} func (x *SetAgencyJoinEnabledRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[45] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3315,9 +3407,11 @@ type SetAgencyJoinEnabledResponse struct { func (x *SetAgencyJoinEnabledResponse) Reset() { *x = SetAgencyJoinEnabledResponse{} - mi := &file_proto_user_v1_host_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_host_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetAgencyJoinEnabledResponse) String() string { @@ -3328,7 +3422,7 @@ func (*SetAgencyJoinEnabledResponse) ProtoMessage() {} func (x *SetAgencyJoinEnabledResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_host_proto_msgTypes[46] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4211,6 +4305,572 @@ func file_proto_user_v1_host_proto_init() { return } file_proto_user_v1_user_proto_init() + if !protoimpl.UnsafeEnabled { + file_proto_user_v1_host_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*HostProfile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*Agency); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*BDProfile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*CoinSellerProfile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*AgencyMembership); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*AgencyApplication); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*RoleInvitation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*SearchAgenciesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*SearchAgenciesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*ApplyToAgencyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*ApplyToAgencyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*ReviewAgencyApplicationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*ReviewAgencyApplicationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*KickAgencyHostRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*KickAgencyHostResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*InviteAgencyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*InviteAgencyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*InviteBDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*InviteBDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*ProcessRoleInvitationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[20].Exporter = func(v any, i int) any { + switch v := v.(*ProcessRoleInvitationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[21].Exporter = func(v any, i int) any { + switch v := v.(*GetHostProfileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[22].Exporter = func(v any, i int) any { + switch v := v.(*GetHostProfileResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[23].Exporter = func(v any, i int) any { + switch v := v.(*GetBDProfileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[24].Exporter = func(v any, i int) any { + switch v := v.(*GetBDProfileResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[25].Exporter = func(v any, i int) any { + switch v := v.(*GetCoinSellerProfileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[26].Exporter = func(v any, i int) any { + switch v := v.(*GetCoinSellerProfileResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[27].Exporter = func(v any, i int) any { + switch v := v.(*GetAgencyMembersRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[28].Exporter = func(v any, i int) any { + switch v := v.(*GetAgencyMembersResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[29].Exporter = func(v any, i int) any { + switch v := v.(*GetAgencyApplicationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[30].Exporter = func(v any, i int) any { + switch v := v.(*GetAgencyApplicationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[31].Exporter = func(v any, i int) any { + switch v := v.(*CreateBDLeaderRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[32].Exporter = func(v any, i int) any { + switch v := v.(*CreateBDLeaderResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[33].Exporter = func(v any, i int) any { + switch v := v.(*CreateBDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[34].Exporter = func(v any, i int) any { + switch v := v.(*CreateBDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[35].Exporter = func(v any, i int) any { + switch v := v.(*SetBDStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[36].Exporter = func(v any, i int) any { + switch v := v.(*SetBDStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[37].Exporter = func(v any, i int) any { + switch v := v.(*CreateCoinSellerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[38].Exporter = func(v any, i int) any { + switch v := v.(*CreateCoinSellerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[39].Exporter = func(v any, i int) any { + switch v := v.(*SetCoinSellerStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[40].Exporter = func(v any, i int) any { + switch v := v.(*SetCoinSellerStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[41].Exporter = func(v any, i int) any { + switch v := v.(*CreateAgencyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[42].Exporter = func(v any, i int) any { + switch v := v.(*CreateAgencyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[43].Exporter = func(v any, i int) any { + switch v := v.(*CloseAgencyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[44].Exporter = func(v any, i int) any { + switch v := v.(*CloseAgencyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[45].Exporter = func(v any, i int) any { + switch v := v.(*SetAgencyJoinEnabledRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_host_proto_msgTypes[46].Exporter = func(v any, i int) any { + switch v := v.(*SetAgencyJoinEnabledResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/proto/user/v1/host_grpc.pb.go b/api/proto/user/v1/host_grpc.pb.go index b0c77cff..f101d280 100644 --- a/api/proto/user/v1/host_grpc.pb.go +++ b/api/proto/user/v1/host_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v4.25.3 +// - protoc v5.29.2 // source: proto/user/v1/host.proto package userv1 diff --git a/api/proto/user/v1/user.pb.go b/api/proto/user/v1/user.pb.go index ea9a1e4d..a1dcd8db 100644 --- a/api/proto/user/v1/user.pb.go +++ b/api/proto/user/v1/user.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 -// protoc v4.25.3 +// protoc-gen-go v1.34.2 +// protoc v5.29.2 // source: proto/user/v1/user.proto package userv1 @@ -96,9 +96,11 @@ type RequestMeta struct { func (x *RequestMeta) Reset() { *x = RequestMeta{} - mi := &file_proto_user_v1_user_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RequestMeta) String() string { @@ -109,7 +111,7 @@ func (*RequestMeta) ProtoMessage() {} func (x *RequestMeta) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -233,9 +235,11 @@ type App struct { func (x *App) Reset() { *x = App{} - mi := &file_proto_user_v1_user_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *App) String() string { @@ -246,7 +250,7 @@ func (*App) ProtoMessage() {} func (x *App) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -331,9 +335,11 @@ type ResolveAppRequest struct { func (x *ResolveAppRequest) Reset() { *x = ResolveAppRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResolveAppRequest) String() string { @@ -344,7 +350,7 @@ func (*ResolveAppRequest) ProtoMessage() {} func (x *ResolveAppRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -397,9 +403,11 @@ type ResolveAppResponse struct { func (x *ResolveAppResponse) Reset() { *x = ResolveAppResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResolveAppResponse) String() string { @@ -410,7 +418,7 @@ func (*ResolveAppResponse) ProtoMessage() {} func (x *ResolveAppResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -470,9 +478,11 @@ type User struct { func (x *User) Reset() { *x = User{} - mi := &file_proto_user_v1_user_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *User) String() string { @@ -483,7 +493,7 @@ func (*User) ProtoMessage() {} func (x *User) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -709,9 +719,11 @@ type InviteOverview struct { func (x *InviteOverview) Reset() { *x = InviteOverview{} - mi := &file_proto_user_v1_user_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *InviteOverview) String() string { @@ -722,7 +734,7 @@ func (*InviteOverview) ProtoMessage() {} func (x *InviteOverview) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -785,9 +797,11 @@ type InviteBinding struct { func (x *InviteBinding) Reset() { *x = InviteBinding{} - mi := &file_proto_user_v1_user_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *InviteBinding) String() string { @@ -798,7 +812,7 @@ func (*InviteBinding) ProtoMessage() {} func (x *InviteBinding) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -852,9 +866,11 @@ type UserMicLifetimeStats struct { func (x *UserMicLifetimeStats) Reset() { *x = UserMicLifetimeStats{} - mi := &file_proto_user_v1_user_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UserMicLifetimeStats) String() string { @@ -865,7 +881,7 @@ func (*UserMicLifetimeStats) ProtoMessage() {} func (x *UserMicLifetimeStats) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -948,9 +964,11 @@ type GetUserMicLifetimeStatsRequest struct { func (x *GetUserMicLifetimeStatsRequest) Reset() { *x = GetUserMicLifetimeStatsRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetUserMicLifetimeStatsRequest) String() string { @@ -961,7 +979,7 @@ func (*GetUserMicLifetimeStatsRequest) ProtoMessage() {} func (x *GetUserMicLifetimeStatsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1000,9 +1018,11 @@ type GetUserMicLifetimeStatsResponse struct { func (x *GetUserMicLifetimeStatsResponse) Reset() { *x = GetUserMicLifetimeStatsResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetUserMicLifetimeStatsResponse) String() string { @@ -1013,7 +1033,7 @@ func (*GetUserMicLifetimeStatsResponse) ProtoMessage() {} func (x *GetUserMicLifetimeStatsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1052,9 +1072,11 @@ type CronBatchRequest struct { func (x *CronBatchRequest) Reset() { *x = CronBatchRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CronBatchRequest) String() string { @@ -1065,7 +1087,7 @@ func (*CronBatchRequest) ProtoMessage() {} func (x *CronBatchRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[10] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1144,9 +1166,11 @@ type CronBatchResponse struct { func (x *CronBatchResponse) Reset() { *x = CronBatchResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CronBatchResponse) String() string { @@ -1157,7 +1181,7 @@ func (*CronBatchResponse) ProtoMessage() {} func (x *CronBatchResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[11] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1230,9 +1254,11 @@ type AuthToken struct { func (x *AuthToken) Reset() { *x = AuthToken{} - mi := &file_proto_user_v1_user_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AuthToken) String() string { @@ -1243,7 +1269,7 @@ func (*AuthToken) ProtoMessage() {} func (x *AuthToken) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[12] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1361,9 +1387,11 @@ type GetUserRequest struct { func (x *GetUserRequest) Reset() { *x = GetUserRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetUserRequest) String() string { @@ -1374,7 +1402,7 @@ func (*GetUserRequest) ProtoMessage() {} func (x *GetUserRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[13] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1414,9 +1442,11 @@ type GetUserResponse struct { func (x *GetUserResponse) Reset() { *x = GetUserResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetUserResponse) String() string { @@ -1427,7 +1457,7 @@ func (*GetUserResponse) ProtoMessage() {} func (x *GetUserResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[14] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1461,9 +1491,11 @@ type BatchGetUsersRequest struct { func (x *BatchGetUsersRequest) Reset() { *x = BatchGetUsersRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *BatchGetUsersRequest) String() string { @@ -1474,7 +1506,7 @@ func (*BatchGetUsersRequest) ProtoMessage() {} func (x *BatchGetUsersRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[15] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1514,9 +1546,11 @@ type BatchGetUsersResponse struct { func (x *BatchGetUsersResponse) Reset() { *x = BatchGetUsersResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *BatchGetUsersResponse) String() string { @@ -1527,7 +1561,7 @@ func (*BatchGetUsersResponse) ProtoMessage() {} func (x *BatchGetUsersResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[16] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1565,9 +1599,11 @@ type ListUserIDsRequest struct { func (x *ListUserIDsRequest) Reset() { *x = ListUserIDsRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListUserIDsRequest) String() string { @@ -1578,7 +1614,7 @@ func (*ListUserIDsRequest) ProtoMessage() {} func (x *ListUserIDsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[17] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1648,9 +1684,11 @@ type ListUserIDsResponse struct { func (x *ListUserIDsResponse) Reset() { *x = ListUserIDsResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListUserIDsResponse) String() string { @@ -1661,7 +1699,7 @@ func (*ListUserIDsResponse) ProtoMessage() {} func (x *ListUserIDsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[18] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1713,9 +1751,11 @@ type UpdateUserProfileRequest struct { func (x *UpdateUserProfileRequest) Reset() { *x = UpdateUserProfileRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpdateUserProfileRequest) String() string { @@ -1726,7 +1766,7 @@ func (*UpdateUserProfileRequest) ProtoMessage() {} func (x *UpdateUserProfileRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[19] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1794,9 +1834,11 @@ type UpdateUserProfileResponse struct { func (x *UpdateUserProfileResponse) Reset() { *x = UpdateUserProfileResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpdateUserProfileResponse) String() string { @@ -1807,7 +1849,7 @@ func (*UpdateUserProfileResponse) ProtoMessage() {} func (x *UpdateUserProfileResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[20] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1842,9 +1884,11 @@ type ChangeUserCountryRequest struct { func (x *ChangeUserCountryRequest) Reset() { *x = ChangeUserCountryRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ChangeUserCountryRequest) String() string { @@ -1855,7 +1899,7 @@ func (*ChangeUserCountryRequest) ProtoMessage() {} func (x *ChangeUserCountryRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[21] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1899,13 +1943,18 @@ type ChangeUserCountryResponse struct { User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` NextChangeAllowedAtMs int64 `protobuf:"varint,2,opt,name=next_change_allowed_at_ms,json=nextChangeAllowedAtMs,proto3" json:"next_change_allowed_at_ms,omitempty"` + OldRegionId int64 `protobuf:"varint,3,opt,name=old_region_id,json=oldRegionId,proto3" json:"old_region_id,omitempty"` + NewRegionId int64 `protobuf:"varint,4,opt,name=new_region_id,json=newRegionId,proto3" json:"new_region_id,omitempty"` + RegionChanged bool `protobuf:"varint,5,opt,name=region_changed,json=regionChanged,proto3" json:"region_changed,omitempty"` } func (x *ChangeUserCountryResponse) Reset() { *x = ChangeUserCountryResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ChangeUserCountryResponse) String() string { @@ -1916,7 +1965,7 @@ func (*ChangeUserCountryResponse) ProtoMessage() {} func (x *ChangeUserCountryResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[22] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1945,6 +1994,27 @@ func (x *ChangeUserCountryResponse) GetNextChangeAllowedAtMs() int64 { return 0 } +func (x *ChangeUserCountryResponse) GetOldRegionId() int64 { + if x != nil { + return x.OldRegionId + } + return 0 +} + +func (x *ChangeUserCountryResponse) GetNewRegionId() int64 { + if x != nil { + return x.NewRegionId + } + return 0 +} + +func (x *ChangeUserCountryResponse) GetRegionChanged() bool { + if x != nil { + return x.RegionChanged + } + return false +} + // CompleteOnboardingRequest 是注册页唯一资料提交入口。 type CompleteOnboardingRequest struct { state protoimpl.MessageState @@ -1962,9 +2032,11 @@ type CompleteOnboardingRequest struct { func (x *CompleteOnboardingRequest) Reset() { *x = CompleteOnboardingRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CompleteOnboardingRequest) String() string { @@ -1975,7 +2047,7 @@ func (*CompleteOnboardingRequest) ProtoMessage() {} func (x *CompleteOnboardingRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[23] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2055,9 +2127,11 @@ type CompleteOnboardingResponse struct { func (x *CompleteOnboardingResponse) Reset() { *x = CompleteOnboardingResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CompleteOnboardingResponse) String() string { @@ -2068,7 +2142,7 @@ func (*CompleteOnboardingResponse) ProtoMessage() {} func (x *CompleteOnboardingResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[24] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2145,9 +2219,11 @@ type BindPushTokenRequest struct { func (x *BindPushTokenRequest) Reset() { *x = BindPushTokenRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *BindPushTokenRequest) String() string { @@ -2158,7 +2234,7 @@ func (*BindPushTokenRequest) ProtoMessage() {} func (x *BindPushTokenRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[25] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2247,9 +2323,11 @@ type BindPushTokenResponse struct { func (x *BindPushTokenResponse) Reset() { *x = BindPushTokenResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *BindPushTokenResponse) String() string { @@ -2260,7 +2338,7 @@ func (*BindPushTokenResponse) ProtoMessage() {} func (x *BindPushTokenResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[26] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2304,9 +2382,11 @@ type DeletePushTokenRequest struct { func (x *DeletePushTokenRequest) Reset() { *x = DeletePushTokenRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *DeletePushTokenRequest) String() string { @@ -2317,7 +2397,7 @@ func (*DeletePushTokenRequest) ProtoMessage() {} func (x *DeletePushTokenRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[27] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2371,9 +2451,11 @@ type DeletePushTokenResponse struct { func (x *DeletePushTokenResponse) Reset() { *x = DeletePushTokenResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *DeletePushTokenResponse) String() string { @@ -2384,7 +2466,7 @@ func (*DeletePushTokenResponse) ProtoMessage() {} func (x *DeletePushTokenResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[28] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2436,9 +2518,11 @@ type Country struct { func (x *Country) Reset() { *x = Country{} - mi := &file_proto_user_v1_user_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Country) String() string { @@ -2449,7 +2533,7 @@ func (*Country) ProtoMessage() {} func (x *Country) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[29] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2574,9 +2658,11 @@ type Region struct { func (x *Region) Reset() { *x = Region{} - mi := &file_proto_user_v1_user_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Region) String() string { @@ -2587,7 +2673,7 @@ func (*Region) ProtoMessage() {} func (x *Region) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[30] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2676,9 +2762,11 @@ type ListCountriesRequest struct { func (x *ListCountriesRequest) Reset() { *x = ListCountriesRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListCountriesRequest) String() string { @@ -2689,7 +2777,7 @@ func (*ListCountriesRequest) ProtoMessage() {} func (x *ListCountriesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[31] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2728,9 +2816,11 @@ type ListCountriesResponse struct { func (x *ListCountriesResponse) Reset() { *x = ListCountriesResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListCountriesResponse) String() string { @@ -2741,7 +2831,7 @@ func (*ListCountriesResponse) ProtoMessage() {} func (x *ListCountriesResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[32] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2783,9 +2873,11 @@ type UpdateCountryRequest struct { func (x *UpdateCountryRequest) Reset() { *x = UpdateCountryRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpdateCountryRequest) String() string { @@ -2796,7 +2888,7 @@ func (*UpdateCountryRequest) ProtoMessage() {} func (x *UpdateCountryRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[33] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2891,9 +2983,11 @@ type CountryResponse struct { func (x *CountryResponse) Reset() { *x = CountryResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CountryResponse) String() string { @@ -2904,7 +2998,7 @@ func (*CountryResponse) ProtoMessage() {} func (x *CountryResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[34] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2936,9 +3030,11 @@ type ListRegistrationCountriesRequest struct { func (x *ListRegistrationCountriesRequest) Reset() { *x = ListRegistrationCountriesRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRegistrationCountriesRequest) String() string { @@ -2949,7 +3045,7 @@ func (*ListRegistrationCountriesRequest) ProtoMessage() {} func (x *ListRegistrationCountriesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[35] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2981,9 +3077,11 @@ type ListRegistrationCountriesResponse struct { func (x *ListRegistrationCountriesResponse) Reset() { *x = ListRegistrationCountriesResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRegistrationCountriesResponse) String() string { @@ -2994,7 +3092,7 @@ func (*ListRegistrationCountriesResponse) ProtoMessage() {} func (x *ListRegistrationCountriesResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[36] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3027,9 +3125,11 @@ type ListRegionsRequest struct { func (x *ListRegionsRequest) Reset() { *x = ListRegionsRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRegionsRequest) String() string { @@ -3040,7 +3140,7 @@ func (*ListRegionsRequest) ProtoMessage() {} func (x *ListRegionsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[37] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3079,9 +3179,11 @@ type ListRegionsResponse struct { func (x *ListRegionsResponse) Reset() { *x = ListRegionsResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRegionsResponse) String() string { @@ -3092,7 +3194,7 @@ func (*ListRegionsResponse) ProtoMessage() {} func (x *ListRegionsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[38] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3125,9 +3227,11 @@ type GetRegionRequest struct { func (x *GetRegionRequest) Reset() { *x = GetRegionRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetRegionRequest) String() string { @@ -3138,7 +3242,7 @@ func (*GetRegionRequest) ProtoMessage() {} func (x *GetRegionRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[39] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3183,9 +3287,11 @@ type UpdateRegionRequest struct { func (x *UpdateRegionRequest) Reset() { *x = UpdateRegionRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpdateRegionRequest) String() string { @@ -3196,7 +3302,7 @@ func (*UpdateRegionRequest) ProtoMessage() {} func (x *UpdateRegionRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[40] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3266,9 +3372,11 @@ type ReplaceRegionCountriesRequest struct { func (x *ReplaceRegionCountriesRequest) Reset() { *x = ReplaceRegionCountriesRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ReplaceRegionCountriesRequest) String() string { @@ -3279,7 +3387,7 @@ func (*ReplaceRegionCountriesRequest) ProtoMessage() {} func (x *ReplaceRegionCountriesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[41] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3332,9 +3440,11 @@ type RegionResponse struct { func (x *RegionResponse) Reset() { *x = RegionResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[42] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RegionResponse) String() string { @@ -3345,7 +3455,7 @@ func (*RegionResponse) ProtoMessage() {} func (x *RegionResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[42] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3384,9 +3494,11 @@ type UserIdentity struct { func (x *UserIdentity) Reset() { *x = UserIdentity{} - mi := &file_proto_user_v1_user_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UserIdentity) String() string { @@ -3397,7 +3509,7 @@ func (*UserIdentity) ProtoMessage() {} func (x *UserIdentity) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[43] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3473,9 +3585,11 @@ type GetUserIdentityRequest struct { func (x *GetUserIdentityRequest) Reset() { *x = GetUserIdentityRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetUserIdentityRequest) String() string { @@ -3486,7 +3600,7 @@ func (*GetUserIdentityRequest) ProtoMessage() {} func (x *GetUserIdentityRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[44] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3526,9 +3640,11 @@ type GetUserIdentityResponse struct { func (x *GetUserIdentityResponse) Reset() { *x = GetUserIdentityResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetUserIdentityResponse) String() string { @@ -3539,7 +3655,7 @@ func (*GetUserIdentityResponse) ProtoMessage() {} func (x *GetUserIdentityResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[45] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3573,9 +3689,11 @@ type ResolveDisplayUserIDRequest struct { func (x *ResolveDisplayUserIDRequest) Reset() { *x = ResolveDisplayUserIDRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResolveDisplayUserIDRequest) String() string { @@ -3586,7 +3704,7 @@ func (*ResolveDisplayUserIDRequest) ProtoMessage() {} func (x *ResolveDisplayUserIDRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[46] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3626,9 +3744,11 @@ type ResolveDisplayUserIDResponse struct { func (x *ResolveDisplayUserIDResponse) Reset() { *x = ResolveDisplayUserIDResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResolveDisplayUserIDResponse) String() string { @@ -3639,7 +3759,7 @@ func (*ResolveDisplayUserIDResponse) ProtoMessage() {} func (x *ResolveDisplayUserIDResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[47] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3676,9 +3796,11 @@ type ChangeDisplayUserIDRequest struct { func (x *ChangeDisplayUserIDRequest) Reset() { *x = ChangeDisplayUserIDRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[48] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ChangeDisplayUserIDRequest) String() string { @@ -3689,7 +3811,7 @@ func (*ChangeDisplayUserIDRequest) ProtoMessage() {} func (x *ChangeDisplayUserIDRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[48] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3750,9 +3872,11 @@ type ChangeDisplayUserIDResponse struct { func (x *ChangeDisplayUserIDResponse) Reset() { *x = ChangeDisplayUserIDResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[49] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ChangeDisplayUserIDResponse) String() string { @@ -3763,7 +3887,7 @@ func (*ChangeDisplayUserIDResponse) ProtoMessage() {} func (x *ChangeDisplayUserIDResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[49] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3800,9 +3924,11 @@ type ApplyPrettyDisplayUserIDRequest struct { func (x *ApplyPrettyDisplayUserIDRequest) Reset() { *x = ApplyPrettyDisplayUserIDRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[50] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ApplyPrettyDisplayUserIDRequest) String() string { @@ -3813,7 +3939,7 @@ func (*ApplyPrettyDisplayUserIDRequest) ProtoMessage() {} func (x *ApplyPrettyDisplayUserIDRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[50] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3875,9 +4001,11 @@ type ApplyPrettyDisplayUserIDResponse struct { func (x *ApplyPrettyDisplayUserIDResponse) Reset() { *x = ApplyPrettyDisplayUserIDResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[51] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ApplyPrettyDisplayUserIDResponse) String() string { @@ -3888,7 +4016,7 @@ func (*ApplyPrettyDisplayUserIDResponse) ProtoMessage() {} func (x *ApplyPrettyDisplayUserIDResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[51] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3930,9 +4058,11 @@ type ExpirePrettyDisplayUserIDRequest struct { func (x *ExpirePrettyDisplayUserIDRequest) Reset() { *x = ExpirePrettyDisplayUserIDRequest{} - mi := &file_proto_user_v1_user_proto_msgTypes[52] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ExpirePrettyDisplayUserIDRequest) String() string { @@ -3943,7 +4073,7 @@ func (*ExpirePrettyDisplayUserIDRequest) ProtoMessage() {} func (x *ExpirePrettyDisplayUserIDRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[52] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3990,9 +4120,11 @@ type ExpirePrettyDisplayUserIDResponse struct { func (x *ExpirePrettyDisplayUserIDResponse) Reset() { *x = ExpirePrettyDisplayUserIDResponse{} - mi := &file_proto_user_v1_user_proto_msgTypes[53] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_user_v1_user_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ExpirePrettyDisplayUserIDResponse) String() string { @@ -4003,7 +4135,7 @@ func (*ExpirePrettyDisplayUserIDResponse) ProtoMessage() {} func (x *ExpirePrettyDisplayUserIDResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_user_v1_user_proto_msgTypes[53] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4348,15 +4480,22 @@ var file_proto_user_v1_user_proto_rawDesc = []byte{ 0x6d, 0x65, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x7e, 0x0a, 0x19, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x38, 0x0a, - 0x19, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x15, 0x6e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x22, 0xeb, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x70, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xed, 0x01, 0x0a, 0x19, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x38, + 0x0a, 0x19, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x15, 0x6e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x6c, 0x6c, + 0x6f, 0x77, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x6c, 0x64, 0x5f, + 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0b, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, + 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0xeb, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, @@ -5033,6 +5172,656 @@ func file_proto_user_v1_user_proto_init() { if File_proto_user_v1_user_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_proto_user_v1_user_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*RequestMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*App); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ResolveAppRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*ResolveAppResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*User); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*InviteOverview); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*InviteBinding); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*UserMicLifetimeStats); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*GetUserMicLifetimeStatsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*GetUserMicLifetimeStatsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*CronBatchRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*CronBatchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*AuthToken); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*GetUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*GetUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*BatchGetUsersRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*BatchGetUsersResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*ListUserIDsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*ListUserIDsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*UpdateUserProfileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[20].Exporter = func(v any, i int) any { + switch v := v.(*UpdateUserProfileResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[21].Exporter = func(v any, i int) any { + switch v := v.(*ChangeUserCountryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[22].Exporter = func(v any, i int) any { + switch v := v.(*ChangeUserCountryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[23].Exporter = func(v any, i int) any { + switch v := v.(*CompleteOnboardingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[24].Exporter = func(v any, i int) any { + switch v := v.(*CompleteOnboardingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[25].Exporter = func(v any, i int) any { + switch v := v.(*BindPushTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[26].Exporter = func(v any, i int) any { + switch v := v.(*BindPushTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[27].Exporter = func(v any, i int) any { + switch v := v.(*DeletePushTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[28].Exporter = func(v any, i int) any { + switch v := v.(*DeletePushTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[29].Exporter = func(v any, i int) any { + switch v := v.(*Country); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[30].Exporter = func(v any, i int) any { + switch v := v.(*Region); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[31].Exporter = func(v any, i int) any { + switch v := v.(*ListCountriesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[32].Exporter = func(v any, i int) any { + switch v := v.(*ListCountriesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[33].Exporter = func(v any, i int) any { + switch v := v.(*UpdateCountryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[34].Exporter = func(v any, i int) any { + switch v := v.(*CountryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[35].Exporter = func(v any, i int) any { + switch v := v.(*ListRegistrationCountriesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[36].Exporter = func(v any, i int) any { + switch v := v.(*ListRegistrationCountriesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[37].Exporter = func(v any, i int) any { + switch v := v.(*ListRegionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[38].Exporter = func(v any, i int) any { + switch v := v.(*ListRegionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[39].Exporter = func(v any, i int) any { + switch v := v.(*GetRegionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[40].Exporter = func(v any, i int) any { + switch v := v.(*UpdateRegionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[41].Exporter = func(v any, i int) any { + switch v := v.(*ReplaceRegionCountriesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[42].Exporter = func(v any, i int) any { + switch v := v.(*RegionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[43].Exporter = func(v any, i int) any { + switch v := v.(*UserIdentity); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[44].Exporter = func(v any, i int) any { + switch v := v.(*GetUserIdentityRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[45].Exporter = func(v any, i int) any { + switch v := v.(*GetUserIdentityResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[46].Exporter = func(v any, i int) any { + switch v := v.(*ResolveDisplayUserIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*ResolveDisplayUserIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[48].Exporter = func(v any, i int) any { + switch v := v.(*ChangeDisplayUserIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[49].Exporter = func(v any, i int) any { + switch v := v.(*ChangeDisplayUserIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[50].Exporter = func(v any, i int) any { + switch v := v.(*ApplyPrettyDisplayUserIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[51].Exporter = func(v any, i int) any { + switch v := v.(*ApplyPrettyDisplayUserIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[52].Exporter = func(v any, i int) any { + switch v := v.(*ExpirePrettyDisplayUserIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_user_v1_user_proto_msgTypes[53].Exporter = func(v any, i int) any { + switch v := v.(*ExpirePrettyDisplayUserIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } file_proto_user_v1_user_proto_msgTypes[19].OneofWrappers = []any{} file_proto_user_v1_user_proto_msgTypes[31].OneofWrappers = []any{} type x struct{} diff --git a/api/proto/user/v1/user.proto b/api/proto/user/v1/user.proto index 9802ca57..415eaeac 100644 --- a/api/proto/user/v1/user.proto +++ b/api/proto/user/v1/user.proto @@ -225,6 +225,9 @@ message ChangeUserCountryRequest { message ChangeUserCountryResponse { User user = 1; int64 next_change_allowed_at_ms = 2; + int64 old_region_id = 3; + int64 new_region_id = 4; + bool region_changed = 5; } // CompleteOnboardingRequest 是注册页唯一资料提交入口。 diff --git a/api/proto/user/v1/user_grpc.pb.go b/api/proto/user/v1/user_grpc.pb.go index 469f0237..9f949d5b 100644 --- a/api/proto/user/v1/user_grpc.pb.go +++ b/api/proto/user/v1/user_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v4.25.3 +// - protoc v5.29.2 // source: proto/user/v1/user.proto package userv1 diff --git a/api/proto/wallet/v1/wallet.pb.go b/api/proto/wallet/v1/wallet.pb.go index 9408550c..814bffaf 100644 --- a/api/proto/wallet/v1/wallet.pb.go +++ b/api/proto/wallet/v1/wallet.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 -// protoc v4.25.3 +// protoc-gen-go v1.34.2 +// protoc v5.29.2 // source: proto/wallet/v1/wallet.proto package walletv1 @@ -41,9 +41,11 @@ type DebitGiftRequest struct { func (x *DebitGiftRequest) Reset() { *x = DebitGiftRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *DebitGiftRequest) String() string { @@ -54,7 +56,7 @@ func (*DebitGiftRequest) ProtoMessage() {} func (x *DebitGiftRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -152,9 +154,11 @@ type DebitGiftResponse struct { func (x *DebitGiftResponse) Reset() { *x = DebitGiftResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *DebitGiftResponse) String() string { @@ -165,7 +169,7 @@ func (*DebitGiftResponse) ProtoMessage() {} func (x *DebitGiftResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -258,9 +262,11 @@ type AssetBalance struct { func (x *AssetBalance) Reset() { *x = AssetBalance{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AssetBalance) String() string { @@ -271,7 +277,7 @@ func (*AssetBalance) ProtoMessage() {} func (x *AssetBalance) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -335,9 +341,11 @@ type GetBalancesRequest struct { func (x *GetBalancesRequest) Reset() { *x = GetBalancesRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetBalancesRequest) String() string { @@ -348,7 +356,7 @@ func (*GetBalancesRequest) ProtoMessage() {} func (x *GetBalancesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -401,9 +409,11 @@ type GetBalancesResponse struct { func (x *GetBalancesResponse) Reset() { *x = GetBalancesResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetBalancesResponse) String() string { @@ -414,7 +424,7 @@ func (*GetBalancesResponse) ProtoMessage() {} func (x *GetBalancesResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[4] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -454,9 +464,11 @@ type AdminCreditAssetRequest struct { func (x *AdminCreditAssetRequest) Reset() { *x = AdminCreditAssetRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AdminCreditAssetRequest) String() string { @@ -467,7 +479,7 @@ func (*AdminCreditAssetRequest) ProtoMessage() {} func (x *AdminCreditAssetRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[5] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -549,9 +561,11 @@ type AdminCreditAssetResponse struct { func (x *AdminCreditAssetResponse) Reset() { *x = AdminCreditAssetResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AdminCreditAssetResponse) String() string { @@ -562,7 +576,7 @@ func (*AdminCreditAssetResponse) ProtoMessage() {} func (x *AdminCreditAssetResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[6] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -612,9 +626,11 @@ type AdminCreditCoinSellerStockRequest struct { func (x *AdminCreditCoinSellerStockRequest) Reset() { *x = AdminCreditCoinSellerStockRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AdminCreditCoinSellerStockRequest) String() string { @@ -625,7 +641,7 @@ func (*AdminCreditCoinSellerStockRequest) ProtoMessage() {} func (x *AdminCreditCoinSellerStockRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[7] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -735,9 +751,11 @@ type AdminCreditCoinSellerStockResponse struct { func (x *AdminCreditCoinSellerStockResponse) Reset() { *x = AdminCreditCoinSellerStockResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AdminCreditCoinSellerStockResponse) String() string { @@ -748,7 +766,7 @@ func (*AdminCreditCoinSellerStockResponse) ProtoMessage() {} func (x *AdminCreditCoinSellerStockResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[8] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -845,9 +863,11 @@ type TransferCoinFromSellerRequest struct { func (x *TransferCoinFromSellerRequest) Reset() { *x = TransferCoinFromSellerRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *TransferCoinFromSellerRequest) String() string { @@ -858,7 +878,7 @@ func (*TransferCoinFromSellerRequest) ProtoMessage() {} func (x *TransferCoinFromSellerRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[9] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -949,9 +969,11 @@ type TransferCoinFromSellerResponse struct { func (x *TransferCoinFromSellerResponse) Reset() { *x = TransferCoinFromSellerResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *TransferCoinFromSellerResponse) String() string { @@ -962,7 +984,7 @@ func (*TransferCoinFromSellerResponse) ProtoMessage() {} func (x *TransferCoinFromSellerResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[10] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1077,9 +1099,11 @@ type Resource struct { func (x *Resource) Reset() { *x = Resource{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Resource) String() string { @@ -1090,7 +1114,7 @@ func (*Resource) ProtoMessage() {} func (x *Resource) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[11] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1266,9 +1290,11 @@ type ResourceGroupItem struct { func (x *ResourceGroupItem) Reset() { *x = ResourceGroupItem{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceGroupItem) String() string { @@ -1279,7 +1305,7 @@ func (*ResourceGroupItem) ProtoMessage() {} func (x *ResourceGroupItem) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[12] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1399,9 +1425,11 @@ type ResourceGroup struct { func (x *ResourceGroup) Reset() { *x = ResourceGroup{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceGroup) String() string { @@ -1412,7 +1440,7 @@ func (*ResourceGroup) ProtoMessage() {} func (x *ResourceGroup) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[13] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1542,9 +1570,11 @@ type GiftConfig struct { func (x *GiftConfig) Reset() { *x = GiftConfig{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GiftConfig) String() string { @@ -1555,7 +1585,7 @@ func (*GiftConfig) ProtoMessage() {} func (x *GiftConfig) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[14] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1746,9 +1776,11 @@ type UserResourceEntitlement struct { func (x *UserResourceEntitlement) Reset() { *x = UserResourceEntitlement{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UserResourceEntitlement) String() string { @@ -1759,7 +1791,7 @@ func (*UserResourceEntitlement) ProtoMessage() {} func (x *UserResourceEntitlement) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[15] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1884,9 +1916,11 @@ type ResourceGrantItem struct { func (x *ResourceGrantItem) Reset() { *x = ResourceGrantItem{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceGrantItem) String() string { @@ -1897,7 +1931,7 @@ func (*ResourceGrantItem) ProtoMessage() {} func (x *ResourceGrantItem) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[16] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2004,9 +2038,11 @@ type ResourceGrant struct { func (x *ResourceGrant) Reset() { *x = ResourceGrant{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceGrant) String() string { @@ -2017,7 +2053,7 @@ func (*ResourceGrant) ProtoMessage() {} func (x *ResourceGrant) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[17] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2139,9 +2175,11 @@ type ResourceGroupItemInput struct { func (x *ResourceGroupItemInput) Reset() { *x = ResourceGroupItemInput{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceGroupItemInput) String() string { @@ -2152,7 +2190,7 @@ func (*ResourceGroupItemInput) ProtoMessage() {} func (x *ResourceGroupItemInput) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[18] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2233,9 +2271,11 @@ type ListResourcesRequest struct { func (x *ListResourcesRequest) Reset() { *x = ListResourcesRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListResourcesRequest) String() string { @@ -2246,7 +2286,7 @@ func (*ListResourcesRequest) ProtoMessage() {} func (x *ListResourcesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[19] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2328,9 +2368,11 @@ type ListResourcesResponse struct { func (x *ListResourcesResponse) Reset() { *x = ListResourcesResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListResourcesResponse) String() string { @@ -2341,7 +2383,7 @@ func (*ListResourcesResponse) ProtoMessage() {} func (x *ListResourcesResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[20] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2382,9 +2424,11 @@ type GetResourceRequest struct { func (x *GetResourceRequest) Reset() { *x = GetResourceRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetResourceRequest) String() string { @@ -2395,7 +2439,7 @@ func (*GetResourceRequest) ProtoMessage() {} func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[21] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2441,9 +2485,11 @@ type GetResourceResponse struct { func (x *GetResourceResponse) Reset() { *x = GetResourceResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetResourceResponse) String() string { @@ -2454,7 +2500,7 @@ func (*GetResourceResponse) ProtoMessage() {} func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[22] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2502,9 +2548,11 @@ type CreateResourceRequest struct { func (x *CreateResourceRequest) Reset() { *x = CreateResourceRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateResourceRequest) String() string { @@ -2515,7 +2563,7 @@ func (*CreateResourceRequest) ProtoMessage() {} func (x *CreateResourceRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[23] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2676,9 +2724,11 @@ type UpdateResourceRequest struct { func (x *UpdateResourceRequest) Reset() { *x = UpdateResourceRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpdateResourceRequest) String() string { @@ -2689,7 +2739,7 @@ func (*UpdateResourceRequest) ProtoMessage() {} func (x *UpdateResourceRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[24] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2844,9 +2894,11 @@ type SetResourceStatusRequest struct { func (x *SetResourceStatusRequest) Reset() { *x = SetResourceStatusRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetResourceStatusRequest) String() string { @@ -2857,7 +2909,7 @@ func (*SetResourceStatusRequest) ProtoMessage() {} func (x *SetResourceStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[25] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2917,9 +2969,11 @@ type ResourceResponse struct { func (x *ResourceResponse) Reset() { *x = ResourceResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceResponse) String() string { @@ -2930,7 +2984,7 @@ func (*ResourceResponse) ProtoMessage() {} func (x *ResourceResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[26] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2968,9 +3022,11 @@ type ListResourceGroupsRequest struct { func (x *ListResourceGroupsRequest) Reset() { *x = ListResourceGroupsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListResourceGroupsRequest) String() string { @@ -2981,7 +3037,7 @@ func (*ListResourceGroupsRequest) ProtoMessage() {} func (x *ListResourceGroupsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[27] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3056,9 +3112,11 @@ type ListResourceGroupsResponse struct { func (x *ListResourceGroupsResponse) Reset() { *x = ListResourceGroupsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListResourceGroupsResponse) String() string { @@ -3069,7 +3127,7 @@ func (*ListResourceGroupsResponse) ProtoMessage() {} func (x *ListResourceGroupsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[28] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3110,9 +3168,11 @@ type GetResourceGroupRequest struct { func (x *GetResourceGroupRequest) Reset() { *x = GetResourceGroupRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetResourceGroupRequest) String() string { @@ -3123,7 +3183,7 @@ func (*GetResourceGroupRequest) ProtoMessage() {} func (x *GetResourceGroupRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[29] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3169,9 +3229,11 @@ type GetResourceGroupResponse struct { func (x *GetResourceGroupResponse) Reset() { *x = GetResourceGroupResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetResourceGroupResponse) String() string { @@ -3182,7 +3244,7 @@ func (*GetResourceGroupResponse) ProtoMessage() {} func (x *GetResourceGroupResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[30] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3222,9 +3284,11 @@ type CreateResourceGroupRequest struct { func (x *CreateResourceGroupRequest) Reset() { *x = CreateResourceGroupRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateResourceGroupRequest) String() string { @@ -3235,7 +3299,7 @@ func (*CreateResourceGroupRequest) ProtoMessage() {} func (x *CreateResourceGroupRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[31] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3332,9 +3396,11 @@ type UpdateResourceGroupRequest struct { func (x *UpdateResourceGroupRequest) Reset() { *x = UpdateResourceGroupRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpdateResourceGroupRequest) String() string { @@ -3345,7 +3411,7 @@ func (*UpdateResourceGroupRequest) ProtoMessage() {} func (x *UpdateResourceGroupRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[32] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3444,9 +3510,11 @@ type SetResourceGroupStatusRequest struct { func (x *SetResourceGroupStatusRequest) Reset() { *x = SetResourceGroupStatusRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetResourceGroupStatusRequest) String() string { @@ -3457,7 +3525,7 @@ func (*SetResourceGroupStatusRequest) ProtoMessage() {} func (x *SetResourceGroupStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[33] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3517,9 +3585,11 @@ type ResourceGroupResponse struct { func (x *ResourceGroupResponse) Reset() { *x = ResourceGroupResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceGroupResponse) String() string { @@ -3530,7 +3600,7 @@ func (*ResourceGroupResponse) ProtoMessage() {} func (x *ResourceGroupResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[34] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3570,9 +3640,11 @@ type ListGiftConfigsRequest struct { func (x *ListGiftConfigsRequest) Reset() { *x = ListGiftConfigsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListGiftConfigsRequest) String() string { @@ -3583,7 +3655,7 @@ func (*ListGiftConfigsRequest) ProtoMessage() {} func (x *ListGiftConfigsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[35] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3672,9 +3744,11 @@ type ListGiftConfigsResponse struct { func (x *ListGiftConfigsResponse) Reset() { *x = ListGiftConfigsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListGiftConfigsResponse) String() string { @@ -3685,7 +3759,7 @@ func (*ListGiftConfigsResponse) ProtoMessage() {} func (x *ListGiftConfigsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[36] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3743,9 +3817,11 @@ type CreateGiftConfigRequest struct { func (x *CreateGiftConfigRequest) Reset() { *x = CreateGiftConfigRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreateGiftConfigRequest) String() string { @@ -3756,7 +3832,7 @@ func (*CreateGiftConfigRequest) ProtoMessage() {} func (x *CreateGiftConfigRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[37] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3940,9 +4016,11 @@ type UpdateGiftConfigRequest struct { func (x *UpdateGiftConfigRequest) Reset() { *x = UpdateGiftConfigRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *UpdateGiftConfigRequest) String() string { @@ -3953,7 +4031,7 @@ func (*UpdateGiftConfigRequest) ProtoMessage() {} func (x *UpdateGiftConfigRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[38] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4122,9 +4200,11 @@ type SetGiftConfigStatusRequest struct { func (x *SetGiftConfigStatusRequest) Reset() { *x = SetGiftConfigStatusRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *SetGiftConfigStatusRequest) String() string { @@ -4135,7 +4215,7 @@ func (*SetGiftConfigStatusRequest) ProtoMessage() {} func (x *SetGiftConfigStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[39] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4195,9 +4275,11 @@ type GiftConfigResponse struct { func (x *GiftConfigResponse) Reset() { *x = GiftConfigResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GiftConfigResponse) String() string { @@ -4208,7 +4290,7 @@ func (*GiftConfigResponse) ProtoMessage() {} func (x *GiftConfigResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[40] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4248,9 +4330,11 @@ type GrantResourceRequest struct { func (x *GrantResourceRequest) Reset() { *x = GrantResourceRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GrantResourceRequest) String() string { @@ -4261,7 +4345,7 @@ func (*GrantResourceRequest) ProtoMessage() {} func (x *GrantResourceRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[41] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4355,9 +4439,11 @@ type GrantResourceGroupRequest struct { func (x *GrantResourceGroupRequest) Reset() { *x = GrantResourceGroupRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[42] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GrantResourceGroupRequest) String() string { @@ -4368,7 +4454,7 @@ func (*GrantResourceGroupRequest) ProtoMessage() {} func (x *GrantResourceGroupRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[42] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4442,9 +4528,11 @@ type ResourceGrantResponse struct { func (x *ResourceGrantResponse) Reset() { *x = ResourceGrantResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ResourceGrantResponse) String() string { @@ -4455,7 +4543,7 @@ func (*ResourceGrantResponse) ProtoMessage() {} func (x *ResourceGrantResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[43] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4491,9 +4579,11 @@ type ListUserResourcesRequest struct { func (x *ListUserResourcesRequest) Reset() { *x = ListUserResourcesRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListUserResourcesRequest) String() string { @@ -4504,7 +4594,7 @@ func (*ListUserResourcesRequest) ProtoMessage() {} func (x *ListUserResourcesRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[44] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4564,9 +4654,11 @@ type ListUserResourcesResponse struct { func (x *ListUserResourcesResponse) Reset() { *x = ListUserResourcesResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListUserResourcesResponse) String() string { @@ -4577,7 +4669,7 @@ func (*ListUserResourcesResponse) ProtoMessage() {} func (x *ListUserResourcesResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[45] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4613,9 +4705,11 @@ type EquipUserResourceRequest struct { func (x *EquipUserResourceRequest) Reset() { *x = EquipUserResourceRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *EquipUserResourceRequest) String() string { @@ -4626,7 +4720,7 @@ func (*EquipUserResourceRequest) ProtoMessage() {} func (x *EquipUserResourceRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[46] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4686,9 +4780,11 @@ type EquipUserResourceResponse struct { func (x *EquipUserResourceResponse) Reset() { *x = EquipUserResourceResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *EquipUserResourceResponse) String() string { @@ -4699,7 +4795,7 @@ func (*EquipUserResourceResponse) ProtoMessage() {} func (x *EquipUserResourceResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[47] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4736,9 +4832,11 @@ type ListResourceGrantsRequest struct { func (x *ListResourceGrantsRequest) Reset() { *x = ListResourceGrantsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[48] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListResourceGrantsRequest) String() string { @@ -4749,7 +4847,7 @@ func (*ListResourceGrantsRequest) ProtoMessage() {} func (x *ListResourceGrantsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[48] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4817,9 +4915,11 @@ type ListResourceGrantsResponse struct { func (x *ListResourceGrantsResponse) Reset() { *x = ListResourceGrantsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[49] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListResourceGrantsResponse) String() string { @@ -4830,7 +4930,7 @@ func (*ListResourceGrantsResponse) ProtoMessage() {} func (x *ListResourceGrantsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[49] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4886,9 +4986,11 @@ type RechargeBill struct { func (x *RechargeBill) Reset() { *x = RechargeBill{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[50] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *RechargeBill) String() string { @@ -4899,7 +5001,7 @@ func (*RechargeBill) ProtoMessage() {} func (x *RechargeBill) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[50] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5061,9 +5163,11 @@ type ListRechargeBillsRequest struct { func (x *ListRechargeBillsRequest) Reset() { *x = ListRechargeBillsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[51] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRechargeBillsRequest) String() string { @@ -5074,7 +5178,7 @@ func (*ListRechargeBillsRequest) ProtoMessage() {} func (x *ListRechargeBillsRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[51] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5184,9 +5288,11 @@ type ListRechargeBillsResponse struct { func (x *ListRechargeBillsResponse) Reset() { *x = ListRechargeBillsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[52] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ListRechargeBillsResponse) String() string { @@ -5197,7 +5303,7 @@ func (*ListRechargeBillsResponse) ProtoMessage() {} func (x *ListRechargeBillsResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[52] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5244,9 +5350,11 @@ type CreditTaskRewardRequest struct { func (x *CreditTaskRewardRequest) Reset() { *x = CreditTaskRewardRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[53] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreditTaskRewardRequest) String() string { @@ -5257,7 +5365,7 @@ func (*CreditTaskRewardRequest) ProtoMessage() {} func (x *CreditTaskRewardRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[53] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5342,9 +5450,11 @@ type CreditTaskRewardResponse struct { func (x *CreditTaskRewardResponse) Reset() { *x = CreditTaskRewardResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[54] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *CreditTaskRewardResponse) String() string { @@ -5355,7 +5465,7 @@ func (*CreditTaskRewardResponse) ProtoMessage() {} func (x *CreditTaskRewardResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_wallet_v1_wallet_proto_msgTypes[54] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6733,6 +6843,668 @@ func file_proto_wallet_v1_wallet_proto_init() { if File_proto_wallet_v1_wallet_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_proto_wallet_v1_wallet_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*DebitGiftRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*DebitGiftResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*AssetBalance); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetBalancesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetBalancesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*AdminCreditAssetRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*AdminCreditAssetResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*AdminCreditCoinSellerStockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*AdminCreditCoinSellerStockResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*TransferCoinFromSellerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*TransferCoinFromSellerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*Resource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*ResourceGroupItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*ResourceGroup); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*GiftConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*UserResourceEntitlement); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*ResourceGrantItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*ResourceGrant); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*ResourceGroupItemInput); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*ListResourcesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[20].Exporter = func(v any, i int) any { + switch v := v.(*ListResourcesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[21].Exporter = func(v any, i int) any { + switch v := v.(*GetResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[22].Exporter = func(v any, i int) any { + switch v := v.(*GetResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[23].Exporter = func(v any, i int) any { + switch v := v.(*CreateResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[24].Exporter = func(v any, i int) any { + switch v := v.(*UpdateResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[25].Exporter = func(v any, i int) any { + switch v := v.(*SetResourceStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[26].Exporter = func(v any, i int) any { + switch v := v.(*ResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[27].Exporter = func(v any, i int) any { + switch v := v.(*ListResourceGroupsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[28].Exporter = func(v any, i int) any { + switch v := v.(*ListResourceGroupsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[29].Exporter = func(v any, i int) any { + switch v := v.(*GetResourceGroupRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[30].Exporter = func(v any, i int) any { + switch v := v.(*GetResourceGroupResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[31].Exporter = func(v any, i int) any { + switch v := v.(*CreateResourceGroupRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[32].Exporter = func(v any, i int) any { + switch v := v.(*UpdateResourceGroupRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[33].Exporter = func(v any, i int) any { + switch v := v.(*SetResourceGroupStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[34].Exporter = func(v any, i int) any { + switch v := v.(*ResourceGroupResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[35].Exporter = func(v any, i int) any { + switch v := v.(*ListGiftConfigsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[36].Exporter = func(v any, i int) any { + switch v := v.(*ListGiftConfigsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[37].Exporter = func(v any, i int) any { + switch v := v.(*CreateGiftConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[38].Exporter = func(v any, i int) any { + switch v := v.(*UpdateGiftConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[39].Exporter = func(v any, i int) any { + switch v := v.(*SetGiftConfigStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[40].Exporter = func(v any, i int) any { + switch v := v.(*GiftConfigResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[41].Exporter = func(v any, i int) any { + switch v := v.(*GrantResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[42].Exporter = func(v any, i int) any { + switch v := v.(*GrantResourceGroupRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[43].Exporter = func(v any, i int) any { + switch v := v.(*ResourceGrantResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[44].Exporter = func(v any, i int) any { + switch v := v.(*ListUserResourcesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[45].Exporter = func(v any, i int) any { + switch v := v.(*ListUserResourcesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[46].Exporter = func(v any, i int) any { + switch v := v.(*EquipUserResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*EquipUserResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[48].Exporter = func(v any, i int) any { + switch v := v.(*ListResourceGrantsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[49].Exporter = func(v any, i int) any { + switch v := v.(*ListResourceGrantsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[50].Exporter = func(v any, i int) any { + switch v := v.(*RechargeBill); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[51].Exporter = func(v any, i int) any { + switch v := v.(*ListRechargeBillsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[52].Exporter = func(v any, i int) any { + switch v := v.(*ListRechargeBillsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[53].Exporter = func(v any, i int) any { + switch v := v.(*CreditTaskRewardRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_wallet_v1_wallet_proto_msgTypes[54].Exporter = func(v any, i int) any { + switch v := v.(*CreditTaskRewardResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/proto/wallet/v1/wallet_grpc.pb.go b/api/proto/wallet/v1/wallet_grpc.pb.go index 3d4ec788..85ed1ea8 100644 --- a/api/proto/wallet/v1/wallet_grpc.pb.go +++ b/api/proto/wallet/v1/wallet_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v4.25.3 +// - protoc v5.29.2 // source: proto/wallet/v1/wallet.proto package walletv1 diff --git a/docker-compose.yml b/docker-compose.yml index b22d85a8..b08cfc0f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,8 @@ services: context: . dockerfile: services/gateway-service/Dockerfile container_name: gateway-service + environment: + TZ: UTC ports: - "13000:13000" depends_on: @@ -25,6 +27,8 @@ services: context: . dockerfile: services/room-service/Dockerfile container_name: room-service + environment: + TZ: UTC ports: - "13001:13001" depends_on: @@ -46,6 +50,8 @@ services: context: . dockerfile: services/wallet-service/Dockerfile container_name: wallet-service + environment: + TZ: UTC ports: - "13004:13004" depends_on: @@ -67,6 +73,8 @@ services: context: . dockerfile: services/user-service/Dockerfile container_name: user-service + environment: + TZ: UTC ports: - "13005:13005" depends_on: @@ -84,6 +92,8 @@ services: context: . dockerfile: services/activity-service/Dockerfile container_name: activity-service + environment: + TZ: UTC ports: - "13006:13006" depends_on: @@ -103,6 +113,8 @@ services: context: . dockerfile: services/cron-service/Dockerfile container_name: cron-service + environment: + TZ: UTC ports: - "13007:13007" depends_on: @@ -125,7 +137,9 @@ services: command: - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" + - "--default-time-zone=+00:00" environment: + TZ: UTC MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: hyapp_room MYSQL_USER: hyapp @@ -152,6 +166,8 @@ services: redis: image: redis:7.4-alpine container_name: hyapp-redis + environment: + TZ: UTC ports: - "13379:6379" healthcheck: diff --git a/docs/cron-service-architecture.md b/docs/cron-service-architecture.md index 4a7e8eb8..e4f1417b 100644 --- a/docs/cron-service-architecture.md +++ b/docs/cron-service-architecture.md @@ -137,7 +137,7 @@ service_name: cron-service node_id: cron-local environment: local grpc_addr: ":13007" -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=UTC" user_service_addr: "127.0.0.1:13005" activity_service_addr: "127.0.0.1:13006" diff --git a/docs/daily-task-system-architecture.md b/docs/daily-task-system-architecture.md index 1aa344eb..22b10985 100644 --- a/docs/daily-task-system-architecture.md +++ b/docs/daily-task-system-architecture.md @@ -6,7 +6,7 @@ - 后台增加 `活动管理` 一级菜单,`每日任务` 作为活动管理下的二级菜单。 - `每日任务` 页面包含两个 Tab:`每日任务`、`专属任务`。 -- 每日任务按服务器统一时区每天刷新,当天只能领取一次,超额完成不结转到明天。 +- 每日任务按 UTC 自然日刷新,当天只能领取一次,超额完成不结转到明天。 - 专属任务是用户维度终身只能完成并领取一次的任务。 - 任务奖励统一发金币,金币发放必须走 `wallet-service` 账本。 - 任务进度由服务端事实事件驱动,客户端不能上报任务进度。 @@ -72,7 +72,7 @@ flowchart LR 上麦任务默认读取 `user_mic_daily_stats.mic_online_ms` 或消费 `UserMicSessionClosed` 派生事件。`mic_online_ms` 只从确认发流开始累计,未发声、只占麦、pending_publish 不计入有效麦上时间。 -跨天上麦必须按服务器任务时区拆分到不同 `task_day`,不能把整段时长归到下麦当天。 +跨天上麦必须按 UTC 自然日拆分到不同 `task_day`,不能把整段时长归到下麦当天。 ### 幸运礼物任务口径 @@ -89,9 +89,9 @@ flowchart LR ### 每日任务 -- 周期 key 使用服务器统一时区计算,例如 `Asia/Shanghai` 下的 `2026-05-09`。 -- 服务器时区是系统配置,不使用用户手机时区。 -- 事件归属日按 `occurred_at_ms` 转服务器时区计算,不按消费时间。 +- 周期 key 使用 UTC 自然日计算,例如 UTC 下的 `2026-05-09`。 +- 任务周期不读取机器本地时区、用户手机时区或请求 IP 所在时区。 +- 事件归属日按 `occurred_at_ms` 转 UTC 计算,不按消费时间。 - 用户当天完成后只能领取一次。 - 当天超额完成只保留当天进度,不结转到明天。 - 每日刷新不需要批量清空用户数据;查询时按当前 `task_day` 读取或懒创建进度。 @@ -288,7 +288,7 @@ UNIQUE(app_code, user_id, task_id, cycle_key) | `event_type` | 来源事件类型 | | `source_service` | room / wallet / user | | `user_id` | 事件归属用户 | -| `task_day` | 服务器时区日期 | +| `task_day` | UTC 日期 | | `status` | consumed / skipped / failed | | `skip_reason` | 跳过原因 | | `created_at_ms` | 创建时间 | @@ -390,22 +390,16 @@ sequenceDiagram ## 边界和补充规则 -### 1. 服务器时区 +### 1. UTC 周期 -必须定义全局任务时区,例如: - -```yaml -task_timezone: "Asia/Shanghai" -``` - -所有 daily 周期都按这个时区计算: +所有 daily 周期都按 UTC 计算: - `task_day` - `cycle_start_ms` - `cycle_end_ms` - `next_refresh_at_ms` -不要使用用户手机时区,不要使用请求 IP 所在时区。 +不要使用用户手机时区、请求 IP 所在时区或服务器部署所在地时区。 ### 2. 任务定义修改 @@ -462,7 +456,7 @@ CP 任务以成功组成 CP 的事件为准。后续解除 CP 不回滚已完成 跨天麦位 session 必须拆分到不同 `task_day`。 -例如服务器时区 23:50 上麦,00:10 下麦: +例如 UTC 23:50 上麦,次日 UTC 00:10 下麦: ```text 前一天 +10 分钟 @@ -571,9 +565,8 @@ task_definitions + user_task_progress ## 需要提前确认的问题 -1. 服务器任务时区使用哪个 IANA 时区,是否所有 App 共用。 -2. 幸运礼物任务首版是“消耗金币”或“中奖金币”二选一,还是需要 AND 条件。 -3. 充值任务是否包含币商转金币、后台补偿、活动赠币;建议首版只包含真实充值和币商转普通金币。 -4. daily 任务是否允许次日补领;建议首版不允许。 -5. 专属任务是否全体用户可见,还是需要后台指定用户或人群。 -6. 游戏消耗金币的事件来源和业务类型枚举需要先统一,否则任务无法区分普通扣费和游戏扣费。 +1. 幸运礼物任务首版是“消耗金币”或“中奖金币”二选一,还是需要 AND 条件。 +2. 充值任务是否包含币商转金币、后台补偿、活动赠币;建议首版只包含真实充值和币商转普通金币。 +3. daily 任务是否允许次日补领;建议首版不允许。 +4. 专属任务是否全体用户可见,还是需要后台指定用户或人群。 +5. 游戏消耗金币的事件来源和业务类型枚举需要先统一,否则任务无法区分普通扣费和游戏扣费。 diff --git a/docs/host-agency-bd-admin-architecture.md b/docs/host-agency-bd-admin-architecture.md index 7c9e4755..02d389fd 100644 --- a/docs/host-agency-bd-admin-architecture.md +++ b/docs/host-agency-bd-admin-architecture.md @@ -90,7 +90,7 @@ admin_operation_logs( resource_id VARCHAR(80) NOT NULL DEFAULT '', status VARCHAR(32) NOT NULL, detail TEXT, - created_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, INDEX idx_admin_operation_logs_request_id (request_id), INDEX idx_admin_operation_logs_resource_id (resource_id), INDEX idx_admin_operation_logs_action (action) diff --git a/docs/im-global-region-broadcast-architecture.md b/docs/im-global-region-broadcast-architecture.md new file mode 100644 index 00000000..08eef552 --- /dev/null +++ b/docs/im-global-region-broadcast-architecture.md @@ -0,0 +1,462 @@ +# IM 全局/区域播报群架构 + +本文定义腾讯云 IM 全局/区域播报群的架构。它服务红包、区域运营通知、贵重礼物播报等实时入口消息,不替代房间群、公屏、系统 inbox、钱包账务或 Room Cell 状态。 + +相关文档: + +```text +docs/voice-room-basic-loop-implementation.md +docs/voice-room-client-api-flow.md +docs/app-message-tab-architecture.md +docs/room-outbox-compensation-development.md +``` + +## Current State + +当前仓库只有房间 IM 群: + +| Capability | Current Owner | Current Rule | +| --- | --- | --- | +| IM UserSig | `gateway-service` | `/api/v1/im/usersig` 只签发 `sdk_app_id/user_id/user_sig/expire_at_ms` | +| 房间群建群 | `room-service` | `CreateRoom` 调腾讯 IM REST `create_group`,`GroupID = room_id` | +| 房间系统消息 | `room-service` | Room Cell 命令成功后向 `GroupID = room_id` 发 `room_*` 自定义消息 | +| IM 入群/发言回调 | `gateway-service` | 当前把所有 `GroupId` 都当作 `room_id`,再回查 `room-service` guard | +| 系统/活动 inbox | `activity-service` | backend inbox/fanout,非实时 IM 群 | + +因此,直接新建 `global` 或 `region` 群会被现有 IM callback 误判为房间群并拒绝。必须先增加 GroupID 类型识别和 callback 分流。 + +## Scope + +本阶段新增: + +| Capability | Owner | Required Result | +| --- | --- | --- | +| 全局/区域 GroupID 规则 | shared package | 任何服务都用同一套解析和生成规则 | +| 播报群建群 reconciler | `activity-service` | 启动和定时补齐全局群、active 区域群 | +| `/im/usersig` join 列表 | `gateway-service` | 返回当前用户应加入的全局/区域播报群 | +| IM callback 分流 | `gateway-service` | 房间群走 room guard;播报群走用户状态/区域校验 | +| 播报发送能力 | `activity-service` | 服务端向全局/区域播报群发送自定义消息 | +| 旧区域群成员移除 | `activity-service` | 用户区域变化后,对旧区域群执行 `delete_group_member(user_id)` | +| 贵重礼物播报触发 | `activity-service` consuming room outbox | 基于 `RoomGiftSent` 事实判断阈值并发区域播报 | + +本阶段不做: + +| Excluded | Reason | +| --- | --- | +| 把全局/区域群状态放进 `room-service` | `room-service` 只拥有房间状态和房间群桥接 | +| 用 IM 群承载红包资金事实 | 红包金额、领取、退款和并发扣减必须由 wallet/red-packet 领域持久化 | +| 为每个红包建群 | 红包是业务消息,不是会话边界 | +| 客户端自报区域入群 | 用户区域归属只来自 `user-service` | +| 普通用户向播报群发消息 | 播报群是服务端只写通道 | + +## GroupID Rules + +GroupID 必须稳定、短、可解析,并满足腾讯 IM 自定义 GroupID 长度约束。推荐规则: + +| Group Type | GroupID | Meaning | +| --- | --- | --- | +| room | `` | 现有房间群,必须满足 `pkg/roomid` 规则 | +| global_broadcast | `hy__bc_g` | App 内全局播报群 | +| region_broadcast | `hy__bc_r_` | App 内指定区域播报群 | + +规则: + +- `app_code` 必须使用 `appcode.Normalize` 后的值。 +- `region_id <= 0` 不能生成区域播报群。 +- GroupID 解析必须返回 `{type, app_code, region_id}`,不能靠调用方手写字符串判断。 +- 全局/区域播报 GroupID 不得被 `roomid.ValidStringID` 误判后进入 room guard;callback 必须先识别 broadcast 前缀。 +- 如果未来 `app_code` 可能很长,需要在 App 注册表中约束可用于 GroupID 的短码,不能截断后拼接。 + +建议新增共享包: + +```text +pkg/imgroup +``` + +核心 API: + +```go +type Kind string + +const ( + KindRoom Kind = "room" + KindGlobalBroadcast Kind = "global_broadcast" + KindRegionBroadcast Kind = "region_broadcast" +) + +type ParsedGroup struct { + Kind Kind + AppCode string + RegionID int64 + RoomID string +} + +func GlobalBroadcastGroupID(appCode string) (string, error) +func RegionBroadcastGroupID(appCode string, regionID int64) (string, error) +func Parse(groupID string) ParsedGroup +``` + +## Ownership Boundaries + +| Area | Owner | Rule | +| --- | --- | --- | +| 用户身份、资料完成、区域归属 | `user-service` | gateway callback 和 `/im/usersig` 只信 user-service | +| 房间群、公屏、房间系统消息 | `room-service` | `GroupID = room_id`,仍由 Room Cell 和 room outbox 驱动 | +| 全局/区域播报群 | `activity-service` | 作为消息/播报能力,不写 Room Cell 核心状态 | +| 红包资金事实 | `wallet-service` 或独立 red-packet domain | IM 只携带入口和展示字段 | +| 客户端 IM 长连接 | Tencent IM SDK | 本仓库不自建 WebSocket | + +`room-service` 只需要继续产出 `RoomGiftSent` outbox 事实。贵重礼物是否需要区域播报,由 `activity-service` 消费 outbox 后判断,这样不会把区域播报策略塞进 Room Cell 主链路。 + +## Client Flow + +```mermaid +sequenceDiagram + participant C as Client + participant G as gateway-service + participant U as user-service + participant IM as Tencent IM SDK + + C->>G: GET /api/v1/im/usersig + G->>U: GetUser(user_id) + U-->>G: user.region_id, profile_completed + G-->>C: UserSig + join_groups + C->>IM: login(user_id, user_sig) + C->>IM: joinGroup(hy__bc_g) + C->>IM: joinGroup(hy__bc_r_) +``` + +`/api/v1/im/usersig` response 增加 `join_groups`,客户端必须按返回列表加入播报群: + +```json +{ + "sdk_app_id": 20036101, + "user_id": "42", + "user_sig": "xxx", + "expire_at_ms": 1770000000000, + "join_groups": [ + { + "group_id": "hy_lalu_bc_g", + "type": "global_broadcast" + }, + { + "group_id": "hy_lalu_bc_r_1001", + "type": "region_broadcast", + "region_id": 1001 + } + ] +} +``` + +客户端规则: + +- 用户完成资料后才允许请求 IM UserSig。 +- 登录 IM 后先 join `join_groups`,进入房间时再 join 房间群。 +- 区域变化后,下一次 `/im/usersig` 或 profile refresh 应返回新区域群;客户端应退出旧区域群并加入新区域群。 +- 全局群可配置为默认返回或按开关返回;区域群是主要实时播报通道。 + +## User Region Change Flow + +用户国家变化可能改变 `users.region_id`。区域变化时要更新的是“这个用户在旧区域群里的成员关系”,不是区域群生命周期: + +```text +不能做: + destroy_group(hy__bc_r_) + 或清空旧区域群成员 + +应该做: + delete_group_member(group_id=hy__bc_r_, user_id=) +``` + +职责拆分: + +| Step | Owner | Rule | +| --- | --- | --- | +| App 用户改国家 | `gateway-service -> user-service` | `user-service` 更新 `country/region_id` 并返回 old/new region | +| 后台改用户国家 | `hyapp-admin-server` | 后台写 `users.country/region_id` 后对比 old/new region | +| 移除旧区域成员关系 | `activity-service` | 调腾讯云 IM `delete_group_member`,只移除该 user,不删除群 | +| 加入新区群 | App | 重新拉 profile 或 `/im/usersig`,按新的 `join_groups` join 新区群 | +| 准入兜底 | `gateway-service` callback | 用户再次尝试 join 旧区域群时按当前 `user.region_id` 拒绝 | + +实现规则: + +- `activity-service` 暴露 `BroadcastService.RemoveRegionBroadcastMember`,入参是 `user_id + old_region_id`。 +- `old_region_id <= 0` 是 no-op,因为 GLOBAL/未知区域没有区域播报群。 +- `gateway-service` 和 `hyapp-admin-server` 在国家修改成功后 best-effort 调用该 RPC;IM 外部副作用失败不回滚已提交的用户主数据。 +- 失败必须写结构化日志,后续可由后台补偿或用户下次刷新 join 列表修正;callback 仍然保证用户不能重新加入错误区域群。 +- 区域群由 reconciler 长期维护,不因为单个用户离开而解散。 + +## Group Lifecycle + +播报群建群不应该在 `/im/usersig` 请求路径同步调用腾讯 REST,避免登录入口被外部建群耗时拖垮。 + +推荐由 `activity-service` 增加 broadcast group reconciler: + +| Trigger | Action | +| --- | --- | +| service startup | ensure `hy__bc_g` and all active region groups | +| periodic reconcile | 扫 active regions,补齐缺失群 | +| region created/enabled | ensure corresponding region group | +| region disabled | 停止返回该区域群;是否解散群按运营策略单独处理 | + +Tencent REST 建群必须幂等: + +- 已存在视为成功。 +- 建群失败写结构化日志和指标,等待下一轮 reconcile。 +- 不把 SecretKey、UserSig、完整外部响应写入业务错误。 + +播报群建议使用腾讯 IM 普通群能力,并开启 callback: + +- `ApplyJoinOption` 允许用户申请/加入,但最终由 callback 判定。 +- 普通用户发言由 `CallbackBeforeSendMsg` 拒绝。 +- 服务端通过管理员 REST `send_group_msg` 发布自定义消息。 + +## Callback Routing + +gateway 的腾讯 IM callback 必须先解析 `GroupId`: + +```text +GroupID = room_id + Join: VerifyRoomPresence(room_id, user_id) + Send: CheckSpeakPermission(room_id, user_id) + +GroupID = hy__bc_g + Join: user exists + profile_completed + app_code matched + Send: reject ordinary users; allow Tencent admin/server sender only + +GroupID = hy__bc_r_ + Join: user exists + profile_completed + user.region_id == region_id + app_code matched + Send: reject ordinary users; allow Tencent admin/server sender only +``` + +失败策略: + +- callback 鉴权失败必须 fail-closed。 +- SDKAppID 不匹配必须 fail-closed。 +- 无法解析用户 ID 必须拒绝。 +- user-service 不可用时,播报群 join 必须拒绝;不能用客户端缓存区域兜底。 +- 未知 GroupID 类型可按 room 群处理,但不得绕过现有 room guard。 + +## Broadcast Message Contract + +所有播报都使用 `TIMCustomElem`,`CloudCustomData` 带完整 JSON。客户端只根据 `broadcast_type` 和 `action.type` 分发 UI 行为。 + +公共字段: + +```json +{ + "event_id": "stable-id", + "broadcast_type": "super_gift", + "scope": "region", + "app_code": "lalu", + "region_id": 1001, + "room_id": "lalu_room_xxx", + "sender_user_id": 42, + "sent_at_ms": 1770000000000, + "action": { + "type": "enter_room", + "room_id": "lalu_room_xxx" + } +} +``` + +贵重礼物播报: + +```json +{ + "event_id": "gift_broadcast:lalu_room_xxx:cmd_send_gift_1", + "broadcast_type": "super_gift", + "scope": "region", + "app_code": "lalu", + "region_id": 1001, + "room_id": "lalu_room_xxx", + "sender_user_id": 42, + "target_user_id": 43, + "gift_id": "gift_rocket", + "gift_count": 1, + "gift_value": 999999, + "room_title": "Room title", + "sent_at_ms": 1770000000000, + "action": { + "type": "enter_room", + "room_id": "lalu_room_xxx" + } +} +``` + +红包播报: + +```json +{ + "event_id": "red_packet:rp_1000001", + "broadcast_type": "red_packet", + "scope": "region", + "app_code": "lalu", + "region_id": 1001, + "room_id": "lalu_room_xxx", + "red_packet_id": "rp_1000001", + "sender_user_id": 42, + "sent_at_ms": 1770000000000, + "action": { + "type": "open_red_packet", + "red_packet_id": "rp_1000001", + "room_id": "lalu_room_xxx" + } +} +``` + +客户端点击播报进入房间时,仍必须走正常房间入口: + +```text +JoinRoom(room_id) -> join room IM group -> RTC token if needed +``` + +播报消息不能直接授予进房、抢红包或发言权限。 + +## Server Broadcast Sending + +建议 `activity-service` 增加 `BroadcastService` 内部能力: + +```text +PublishRegionBroadcast(app_code, region_id, payload) +PublishGlobalBroadcast(app_code, payload) +EnsureBroadcastGroups(app_code) +``` + +实现规则: + +- 发送前通过 `pkg/imgroup` 生成 GroupID。 +- payload 必须包含稳定 `event_id`。 +- REST 发送失败不能影响原业务事实提交。 +- 重试必须依赖本地 outbox,不能只依赖 Tencent REST 返回。 + +建议新增表: + +```sql +CREATE TABLE im_broadcast_outbox ( + app_code VARCHAR(32) NOT NULL, + event_id VARCHAR(128) NOT NULL, + scope VARCHAR(32) NOT NULL, + group_id VARCHAR(64) NOT NULL, + payload_json JSON NOT NULL, + status VARCHAR(32) NOT NULL, + attempt_count INT NOT NULL DEFAULT 0, + next_retry_at_ms BIGINT NOT NULL DEFAULT 0, + last_error VARCHAR(512) NOT NULL DEFAULT '', + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, + PRIMARY KEY (app_code, event_id), + KEY idx_im_broadcast_outbox_pending (app_code, status, next_retry_at_ms) +); +``` + +如果第一阶段不落表,也必须明确只支持 best-effort 实时播报;红包入口和重要运营消息不能依赖 best-effort。 + +## High Value Gift Broadcast + +推荐链路: + +```mermaid +sequenceDiagram + participant C as Client + participant G as gateway-service + participant R as room-service + participant W as wallet-service + participant A as activity-service + participant IM as Tencent IM + + C->>G: POST /api/v1/rooms/gift/send + G->>R: SendGift + R->>W: DebitGift + W-->>R: receipt + settlement + R->>R: Room Cell heat/rank + RoomGiftSent outbox + R-->>G: SendGiftResponse + G-->>C: room result + A->>R: consume room outbox / event stream + A->>A: threshold decision + A->>IM: send_group_msg(region broadcast group) +``` + +阈值策略属于播报配置,不属于 Room Cell: + +| Config | Meaning | +| --- | --- | +| `super_gift_min_value` | 单次礼物总价值达到该值才播报 | +| `broadcast_scope` | `region` by default, `global` only for special campaign | +| `cooldown_ms` | 同一房间/同一用户短时间内去重,避免刷屏 | + +`RoomGiftSent` 必须携带足够字段让 activity-service 判断: + +- `room_id` +- `visible_region_id` +- `sender_user_id` +- `target_user_id` +- `gift_id` +- `gift_count` +- `gift_value` or `gift_point_added` +- `command_id` +- `room_version` + +如果现有事件字段不足,应优先扩展 protobuf event,而不是让 activity-service 反查多个服务拼凑事实。 + +## Red Packet Broadcast + +红包资金事实必须由 wallet/red-packet 领域持久化: + +| Fact | Owner | +| --- | --- | +| 红包创建、总金额、份数 | wallet/red-packet domain | +| 抢红包并发扣减 | wallet/red-packet domain | +| 领取记录 | wallet/red-packet domain | +| 过期退款 | wallet/red-packet domain + cron | +| IM 播报 | activity-service broadcast | + +红包创建成功后,红包领域写 `RedPacketCreated` 事件,activity-service 转成区域/全局播报。客户端点击播报只打开红包入口,领取时必须调用后端接口,不能信任 IM payload 中的金额。 + +## App Code And Region Safety + +- `app_code` 必须从 request context 或服务配置取得,不能从客户端 body 读取。 +- 区域群 join 校验必须使用 user-service 当前 `region_id`。 +- 用户改国家/区域后,应在下一次 token refresh 或 profile refresh 中返回新区域群。 +- 旧区域群成员可能短期残留,因此敏感消息不能只靠 IM 群成员做授权;客户端点击后的后端接口仍要校验当前用户区域/资格。 + +## Observability + +必须打点: + +| Metric / Log | Labels | +| --- | --- | +| `im_broadcast_group_ensure_total` | `app_code, group_type, result` | +| `im_broadcast_send_total` | `app_code, scope, result, broadcast_type` | +| `im_broadcast_outbox_pending` | `app_code, scope` | +| `im_callback_route_total` | `group_type, command, result` | +| `im_callback_region_denied_total` | `app_code, region_id, reason` | + +日志必须包含 `request_id/event_id/group_id/app_code/region_id`,不能包含 Tencent SecretKey、UserSig 或完整私密响应。 + +## Implementation Sequence + +1. 新增 `pkg/imgroup`,覆盖 global/region/room GroupID 生成和解析单测。 +2. 扩展 `pkg/tencentim.RESTClient`,增加通用 `EnsureGroup` 和 `PublishGroupCustomMessage`,保留现有 `EnsureRoomGroup/PublishRoomEvent` wrapper。 +3. `gateway-service` 扩展 `/api/v1/im/usersig`,查询 user-service 并返回 `join_groups`。 +4. `gateway-service` 改造 Tencent IM callback 分流,房间群和播报群走不同 guard。 +5. `activity-service` 增加 broadcast group reconciler,启动时确保全局和 active 区域群。 +6. `activity-service` 增加 `PublishRegionBroadcast/PublishGlobalBroadcast` 和 broadcast outbox。 +7. 扩展 `RoomGiftSent` 事件字段,activity-service 消费后按阈值发 `super_gift` 区域播报。 +8. 红包领域落账务事实后,复用同一播报能力发送 `red_packet` 消息。 + +## Test Expectations + +必须覆盖: + +| Test | Expected | +| --- | --- | +| GroupID parse/generate | global、region、room 可稳定识别;非法 region 拒绝 | +| `/im/usersig` | 已完成资料用户返回 global + current region group | +| IM callback room group | 仍走 `VerifyRoomPresence` / `CheckSpeakPermission` | +| IM callback region join | region 匹配允许,不匹配拒绝 | +| IM callback broadcast send | 普通用户拒绝,服务端 sender 允许 | +| group reconciler | 已存在群视为成功,失败可重试 | +| broadcast outbox | 同一 `event_id` 幂等,失败后 retry | +| super gift | 未达阈值不播报,达阈值发送到用户房间所在区域群 | +| red packet | IM payload 不影响领取接口的后端金额校验 | diff --git a/docs/room-cell-state-machines.md b/docs/room-cell-state-machines.md index f9d4fdb6..55553f6d 100644 --- a/docs/room-cell-state-machines.md +++ b/docs/room-cell-state-machines.md @@ -120,7 +120,7 @@ stateDiagram-v2 规则: -- `ClaimPendingOutbox` 必须把事件从 `pending/retryable` 原子改成 `delivering`,并写入 `worker_id` 和 `lock_until`。 +- `ClaimPendingOutbox` 必须把事件从 `pending/retryable` 原子改成 `delivering`,并写入 `worker_id` 和 `lock_until_ms`。 - 其他 worker 不能抢到未过期的 `delivering` 事件。 - 投递成功后才能标记 `delivered`。 - 投递失败必须保留 envelope 和 last_error,转入 `retryable` 等待下一轮抢占。 diff --git a/docs/room-outbox-compensation-development.md b/docs/room-outbox-compensation-development.md index 0a54aa43..844a020b 100644 --- a/docs/room-outbox-compensation-development.md +++ b/docs/room-outbox-compensation-development.md @@ -60,7 +60,7 @@ Room Cell command applied ```text claim room_outbox where status in (pending, retryable) - -> status=delivering, set worker_id and lock_until + -> status=delivering, set worker_id and lock_until_ms -> publish one EventEnvelope to configured OutboxPublisher -> success: status=delivered, last_error=NULL -> failure: status=retryable, retry_count=retry_count+1, last_error= @@ -166,7 +166,7 @@ type App struct { - 不能在 worker 退出前关闭 MySQL,否则可能无法标记投递结果。 - worker 收到 cancel 后不再拉取新批次;已经进入投递的事件可以完成成功标记或失败标记。 -- 如果进程被强杀,已抢占未完成的记录保持 `delivering`,`lock_until` 过期后下次启动继续补偿。 +- 如果进程被强杀,已抢占未完成的记录保持 `delivering`,`lock_until_ms` 过期后下次启动继续补偿。 ## Worker API @@ -202,7 +202,7 @@ func (s *Service) ProcessPendingOutbox(ctx context.Context, options OutboxWorker 处理规则: -- 每轮调用 `repository.ClaimPendingOutbox(ctx, worker_id, batch_size, lock_until)`,把 `pending/retryable` 事件抢占为 `delivering`。 +- 每轮调用 `repository.ClaimPendingOutbox(ctx, worker_id, batch_size, lock_until_ms)`,把 `pending/retryable` 事件抢占为 `delivering`。 - 每条记录单独创建 `context.WithTimeout(ctx, publish_timeout)`。 - `PublishOutboxEvent` 成功后调用 `MarkOutboxDelivered`。 - `PublishOutboxEvent` 失败后调用 `MarkOutboxFailed`。 @@ -238,7 +238,7 @@ V1 采用固定间隔无限重试: | 腾讯云 IM 返回可重试错误 | `retry_count + 1`,转为 `retryable`,下一轮继续 | | envelope 反序列化失败 | worker 本轮返回错误,不删除记录;后续需要人工排查或补工具 | | 不需要推 IM 的事件类型 | no-op success,标记 `delivered` | -| 进程退出 | 已抢占未完成的记录保持 `delivering`,`lock_until` 过期后可被重新抢占 | +| 进程退出 | 已抢占未完成的记录保持 `delivering`,`lock_until_ms` 过期后可被重新抢占 | 为什么不加最大重试次数: diff --git a/docs/service-foundation-technical-design.md b/docs/service-foundation-technical-design.md index 8a65356a..e5b710a0 100644 --- a/docs/service-foundation-technical-design.md +++ b/docs/service-foundation-technical-design.md @@ -100,7 +100,7 @@ jwt: `wallet-service`: ```yaml -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC" mysql_auto_migrate: false ``` diff --git a/docs/user-id-technical-design.md b/docs/user-id-technical-design.md index 72571b0e..7fc08bf6 100644 --- a/docs/user-id-technical-design.md +++ b/docs/user-id-technical-design.md @@ -550,7 +550,7 @@ sequenceDiagram U->>DB: check pretty display_user_id availability U->>DB: mark default display_user_id held U->>DB: insert pretty_display_user_id_leases(active) - U->>DB: insert user_display_user_ids(pretty,active,expires_at) + U->>DB: insert user_display_user_ids(pretty,active,expires_at_ms) U->>DB: update users.current_display_user_id=pretty U->>DB: insert display_user_id_change_logs(change_type=pretty_apply) U->>DB: commit diff --git a/docs/user-region-country-development.md b/docs/user-region-country-development.md index eb877464..9edf6069 100644 --- a/docs/user-region-country-development.md +++ b/docs/user-region-country-development.md @@ -154,6 +154,7 @@ source_assignment_status - 管理端调整区域国家时,创建重算任务,按 country 分页刷新已有用户的 `region_id`。 - 后台创建 BD Leader 是关系管理命令,可以显式把目标用户迁到后台选择的 active 区域;该动作由 `hyapp-admin-server` 鉴权审计,由 user-service host domain 在同一事务里写 `users.region_id` 和 `bd_profiles.region_id`,不修改 `users.country`。 - 后台修改 App 用户国家是用户资料管理命令,必须校验目标国家 `enabled=true`,并在同一次更新中按 active 国家映射写入新的 `users.region_id`;该动作不受普通用户国家修改冷却限制。 +- 当国家修改导致 `old_region_id != new_region_id` 时,后端要调用 `activity-service` 的 `RemoveRegionBroadcastMember`,用腾讯云 IM `delete_group_member` 只把该用户从旧区域播报群移除;不能删除或解散区域群。 ### User Region Change Sources @@ -162,8 +163,8 @@ source_assignment_status | 场景 | 入口 | 是否修改 `users.country` | `users.region_id` 写入方式 | 审计/日志 | | --- | --- | --- | --- | --- | | 首次注册或首次完成资料 | App/gateway 调 user-service 注册/资料完成链路 | 是,写用户选择的 enabled 国家 | user-service 在同一事务内按 active 国家映射解析并写入;无映射时写空 | 注册/资料完成链路日志,不写国家修改冷却日志 | -| 用户主动修改国家 | App/gateway 调 `ChangeUserCountry` | 是,写新 enabled 国家 | user-service 在同一事务内按新国家 active 映射重算;无映射时写空 | 写 `user_country_change_logs`,受国家修改冷却限制 | -| 后台修改 App 用户国家 | `hyapp-admin-server` 的 App 用户管理接口 | 是,写后台选择的 enabled 国家 | `hyapp-admin-server` 在同一次用户更新中按 active 国家映射重算;无映射时写空 | 写后台操作审计,不写 App 自助国家修改冷却日志 | +| 用户主动修改国家 | App/gateway 调 `ChangeUserCountry` | 是,写新 enabled 国家 | user-service 在同一事务内按新国家 active 映射重算;无映射时写空;gateway 成功后 best-effort 移除旧区域群成员关系 | 写 `user_country_change_logs`,受国家修改冷却限制;IM 移除失败写 gateway 结构化日志 | +| 后台修改 App 用户国家 | `hyapp-admin-server` 的 App 用户管理接口 | 是,写后台选择的 enabled 国家 | `hyapp-admin-server` 在同一次用户更新中按 active 国家映射重算;无映射时写空;成功后 best-effort 移除旧区域群成员关系 | 写后台操作审计,不写 App 自助国家修改冷却日志;IM 移除失败写 admin 结构化日志 | | 管理端调整区域国家映射 | 后台创建/停用区域、替换区域国家归属后触发 rebuild | 否 | rebuild worker 按受影响 `country` 分页刷新历史用户 `region_id`,最终一致 | 写区域变更审计和 rebuild task,不写用户国家修改日志 | | 后台创建 BD Leader | `hyapp-admin-server` 的 host 关系管理命令 | 否 | user-service 校验所选区域 active,锁目标用户行,并在创建 `bd_profiles` 的同一事务内把目标用户迁到所选区域 | 写后台操作审计和 host 命令幂等结果,不写用户国家修改日志 | diff --git a/docs/vip-system-architecture.md b/docs/vip-system-architecture.md index 66fc6b0c..41da143e 100644 --- a/docs/vip-system-architecture.md +++ b/docs/vip-system-architecture.md @@ -136,9 +136,9 @@ VIP 属于 `wallet-service` 的账务和权益域,不放在 `user-service`。 | 场景 | 处理 | | ---------------------- | ------------------------------------------------------------------------ | -| 无有效 VIP | 可以购买任意 active 等级,`expires_at = now + 7d` | -| 有效 VIP,购买同等级 | 续期,`expires_at = current_expires_at + 7d` | -| 有效 VIP,购买更高等级 | 立即升级,`level = target_level`,`expires_at = current_expires_at + 7d` | +| 无有效 VIP | 可以购买任意 active 等级,`expires_at_ms = now_ms + 7d_ms` | +| 有效 VIP,购买同等级 | 续期,`expires_at_ms = current_expires_at_ms + 7d_ms` | +| 有效 VIP,购买更高等级 | 立即升级,`level = target_level`,`expires_at_ms = current_expires_at_ms + 7d_ms` | | 有效 VIP,购买更低等级 | 拒绝,返回 `VIP_DOWNGRADE_NOT_ALLOWED` | | VIP 已过期 | 按无有效 VIP 处理,可以购买任意 active 等级 | diff --git a/pkg/clock/clock.go b/pkg/clock/clock.go index f96a50e1..6bea2193 100644 --- a/pkg/clock/clock.go +++ b/pkg/clock/clock.go @@ -12,5 +12,5 @@ type System struct{} // Now 返回当前系统时间。 func (System) Now() time.Time { - return time.Now() + return time.Now().UTC() } diff --git a/pkg/imgroup/imgroup.go b/pkg/imgroup/imgroup.go new file mode 100644 index 00000000..968cf0d9 --- /dev/null +++ b/pkg/imgroup/imgroup.go @@ -0,0 +1,126 @@ +// Package imgroup 定义腾讯云 IM GroupID 的唯一生成和解析规则。 +// gateway、room-service、activity-service 必须共享这里的规则,避免某个服务手写字符串后把播报群误当房间群。 +package imgroup + +import ( + "fmt" + "strconv" + "strings" + + "hyapp/pkg/appcode" + "hyapp/pkg/roomid" +) + +const ( + // KindUnknown 表示 GroupID 既不是本项目播报群,也不是合法房间群;回调层必须 fail-closed。 + KindUnknown Kind = "unknown" + // KindRoom 保持已有房间群规则:腾讯 IM GroupID 直接等于内部 room_id。 + KindRoom Kind = "room" + // KindGlobalBroadcast 是 App 维度全局播报群,只允许服务端管理员账号发消息。 + KindGlobalBroadcast Kind = "global_broadcast" + // KindRegionBroadcast 是区域播报群,用户只能加入自己 user-service 归属的区域群。 + KindRegionBroadcast Kind = "region_broadcast" + + // globalSuffix/regionToken 是可解析协议的一部分;不要在业务代码里重复拼接这些片段。 + globalSuffix = "_bc_g" + regionToken = "_bc_r_" +) + +// Kind 是回调分流和客户端 join 列表使用的稳定分类,不直接暴露腾讯云原始字符串判断。 +type Kind string + +// ParsedGroup 是 GroupID 的强类型解析结果;只有对应 Kind 的字段才有业务含义。 +type ParsedGroup struct { + Kind Kind + AppCode string + RegionID int64 + RoomID string +} + +// GlobalBroadcastGroupID 生成 App 全局播报群 ID。 +// app_code 先 Normalize 再进入 GroupID,确保 HTTP、gRPC、outbox 和腾讯回调看到的是同一租户标识。 +func GlobalBroadcastGroupID(value string) (string, error) { + app := appcode.Normalize(value) + if err := validateAppCodeForGroupID(app); err != nil { + return "", err + } + groupID := "hy_" + app + globalSuffix + if len(groupID) > roomid.MaxStringIDLength { + return "", fmt.Errorf("global broadcast group_id is too long") + } + return groupID, nil +} + +// RegionBroadcastGroupID 生成区域播报群 ID。 +// region_id <= 0 被拒绝,GLOBAL/未知区域不能变成一个可 join 的区域群。 +func RegionBroadcastGroupID(value string, regionID int64) (string, error) { + app := appcode.Normalize(value) + if err := validateAppCodeForGroupID(app); err != nil { + return "", err + } + if regionID <= 0 { + return "", fmt.Errorf("region_id must be positive") + } + groupID := "hy_" + app + regionToken + strconv.FormatInt(regionID, 10) + if len(groupID) > roomid.MaxStringIDLength { + return "", fmt.Errorf("region broadcast group_id is too long") + } + return groupID, nil +} + +// Parse 在调用任何 room guard 前完成 GroupID 分类。 +// 解析顺序必须先播报群、后房间群;否则 hy__bc_* 这类合法短字符串可能被 roomid 规则吞掉。 +func Parse(groupID string) ParsedGroup { + groupID = strings.TrimSpace(groupID) + if groupID == "" { + return ParsedGroup{Kind: KindUnknown} + } + + if strings.HasPrefix(groupID, "hy_") && strings.HasSuffix(groupID, globalSuffix) { + app := strings.TrimSuffix(strings.TrimPrefix(groupID, "hy_"), globalSuffix) + if validateAppCodeForGroupID(app) == nil { + return ParsedGroup{Kind: KindGlobalBroadcast, AppCode: app} + } + return ParsedGroup{Kind: KindUnknown} + } + + if strings.HasPrefix(groupID, "hy_") { + body := strings.TrimPrefix(groupID, "hy_") + tokenIndex := strings.LastIndex(body, regionToken) + if tokenIndex >= 0 { + app := body[:tokenIndex] + rawRegion := body[tokenIndex+len(regionToken):] + regionID, err := strconv.ParseInt(rawRegion, 10, 64) + if err == nil && regionID > 0 && validateAppCodeForGroupID(app) == nil { + return ParsedGroup{Kind: KindRegionBroadcast, AppCode: app, RegionID: regionID} + } + return ParsedGroup{Kind: KindUnknown} + } + } + + if roomid.ValidStringID(groupID) { + return ParsedGroup{Kind: KindRoom, RoomID: groupID} + } + return ParsedGroup{Kind: KindUnknown} +} + +func validateAppCodeForGroupID(app string) error { + if app == "" { + return fmt.Errorf("app_code is required") + } + // GroupID 是腾讯云侧长期存在的外部标识,只允许稳定 ASCII 子集,避免大小写、空格或 Unicode 造成不可逆映射。 + for i := 0; i < len(app); i++ { + char := app[i] + if char >= 'a' && char <= 'z' { + continue + } + if char >= '0' && char <= '9' { + continue + } + if char == '_' || char == '-' { + continue + } + return fmt.Errorf("app_code contains unsupported character") + } + return nil +} diff --git a/pkg/imgroup/imgroup_test.go b/pkg/imgroup/imgroup_test.go new file mode 100644 index 00000000..5f618fa2 --- /dev/null +++ b/pkg/imgroup/imgroup_test.go @@ -0,0 +1,44 @@ +package imgroup + +import "testing" + +func TestBroadcastGroupIDGenerateAndParse(t *testing.T) { + global, err := GlobalBroadcastGroupID(" LaLu ") + if err != nil { + t.Fatalf("GlobalBroadcastGroupID failed: %v", err) + } + if global != "hy_lalu_bc_g" { + t.Fatalf("global group mismatch: %s", global) + } + parsedGlobal := Parse(global) + if parsedGlobal.Kind != KindGlobalBroadcast || parsedGlobal.AppCode != "lalu" || parsedGlobal.RegionID != 0 { + t.Fatalf("global parse mismatch: %+v", parsedGlobal) + } + + region, err := RegionBroadcastGroupID("lalu", 1001) + if err != nil { + t.Fatalf("RegionBroadcastGroupID failed: %v", err) + } + if region != "hy_lalu_bc_r_1001" { + t.Fatalf("region group mismatch: %s", region) + } + parsedRegion := Parse(region) + if parsedRegion.Kind != KindRegionBroadcast || parsedRegion.AppCode != "lalu" || parsedRegion.RegionID != 1001 { + t.Fatalf("region parse mismatch: %+v", parsedRegion) + } +} + +func TestParseRoomAndRejectInvalidBroadcast(t *testing.T) { + if parsed := Parse("room-1001"); parsed.Kind != KindRoom || parsed.RoomID != "room-1001" { + t.Fatalf("room parse mismatch: %+v", parsed) + } + if parsed := Parse("hy_lalu_bc_r_0"); parsed.Kind != KindUnknown { + t.Fatalf("zero region must be rejected: %+v", parsed) + } + if _, err := RegionBroadcastGroupID("lalu", 0); err == nil { + t.Fatal("zero region must not generate a region broadcast group") + } + if _, err := GlobalBroadcastGroupID("bad app"); err == nil { + t.Fatal("app_code with spaces must be rejected") + } +} diff --git a/pkg/tencentim/rest_client.go b/pkg/tencentim/rest_client.go index e9730f8c..6aba6219 100644 --- a/pkg/tencentim/rest_client.go +++ b/pkg/tencentim/rest_client.go @@ -16,37 +16,59 @@ import ( ) const ( - // DefaultEndpoint is Tencent Cloud Chat's China REST API endpoint. + // DefaultEndpoint 是腾讯云 IM 国内 REST 默认入口;海外部署可在配置中覆盖为对应地域域名。 DefaultEndpoint = "console.tim.qq.com" - // DefaultGroupType keeps room messages recoverable; AVChatRoom has no history storage. + // DefaultGroupType 使用 ChatRoom,保留消息历史能力;AVChatRoom 不适合需要补偿和漫游的房间消息。 DefaultGroupType = "ChatRoom" - // createGroupCommand is Tencent Cloud Chat REST command for group creation. + // createGroupCommand 是建群 REST 命令;房间群、全局播报群、区域播报群都复用这一个能力。 createGroupCommand = "v4/group_open_http_svc/create_group" - // sendGroupMsgCommand is Tencent Cloud Chat REST command for group message sending. + // sendGroupMsgCommand 是服务端发群消息 REST 命令;播报只走服务端管理员账号,不开放客户端直发。 sendGroupMsgCommand = "v4/group_open_http_svc/send_group_msg" - // deleteGroupMemberCommand removes users from a Tencent Cloud Chat group. + // destroyGroupCommand 用于真实 IM smoke test 或明确运维动作的临时群清理,业务代码不应自动解散播报群。 + destroyGroupCommand = "v4/group_open_http_svc/destroy_group" + // deleteGroupMemberCommand 用于把已离房用户从腾讯群里移除,防止 IM 群成员残留扩大消息面。 deleteGroupMemberCommand = "v4/group_open_http_svc/delete_group_member" ) -// RESTConfig contains Tencent Cloud Chat server-side REST API settings. +// RESTConfig 保存服务端调用腾讯云 IM REST API 所需配置。 type RESTConfig struct { - // SDKAppID is the application ID assigned by Tencent Cloud Chat. + // SDKAppID 是腾讯云 IM 应用 ID;回调校验和 UserSig 签发都必须使用同一个值。 SDKAppID int64 - // SecretKey signs the admin UserSig used by REST API calls. + // SecretKey 只用于服务端签 admin UserSig,不能返回给客户端或写入错误日志。 SecretKey string - // AdminIdentifier is the App administrator account configured in Tencent Cloud Chat. + // AdminIdentifier 是腾讯云控制台配置的管理员账号,播报群消息用它证明“服务端发送”。 AdminIdentifier string - // AdminUserSigTTL controls the cached admin UserSig lifetime. + // AdminUserSigTTL 控制 REST 调用签名有效期;过短会增加签发频率,过长会扩大泄露影响面。 AdminUserSigTTL time.Duration - // Endpoint is the regional REST API host, such as adminapisgp.im.qcloud.com. + // Endpoint 是 REST 地域入口,例如 adminapisgp.im.qcloud.com;不要把地域选择写死在业务里。 Endpoint string - // GroupType is the Tencent group type used for voice rooms. + // GroupType 是房间和播报群共用的腾讯群类型;当前保持 ChatRoom 以保留历史能力。 GroupType string - // HTTPClient allows tests to inject a fake transport. + // HTTPClient 允许测试注入 fake transport,也让上层统一设置超时。 HTTPClient *http.Client } -// RoomEvent is the backend-owned room system event sent to Tencent Cloud Chat. +// GroupSpec 是项目内部的建群请求,屏蔽腾讯 REST 字段命名差异。 +type GroupSpec struct { + GroupID string + Name string + OwnerAccount string + Type string + ApplyJoinOption string +} + +// CustomGroupMessage 表示一条服务端发出的 TIMCustomElem 群消息。 +// PayloadJSON 同时写入 Data 和 CloudCustomData,客户端和排障侧都能按 event_id 做幂等和追踪。 +type CustomGroupMessage struct { + GroupID string + EventID string + Desc string + Ext string + FromAccount string + PayloadJSON json.RawMessage +} + +// RoomEvent 是 room-service 发给腾讯 IM 的房间系统消息负载。 type RoomEvent struct { EventID string `json:"event_id"` RoomID string `json:"room_id"` @@ -61,18 +83,18 @@ type RoomEvent struct { Attributes map[string]string `json:"attributes,omitempty"` } -// RESTClient wraps Tencent Cloud Chat REST API and hides UserSig/query boilerplate. +// RESTClient 封装腾讯云 IM REST API,把 UserSig、endpoint query 和错误码处理收敛在一个边界。 type RESTClient struct { - // cfg is immutable after construction so calls can safely run concurrently. + // cfg 初始化后不再修改,因此同一个 client 可以被多个 worker 并发复用。 cfg RESTConfig - // httpClient is reused for keep-alive; Tencent recommends long connections for REST API. + // httpClient 复用 keep-alive,避免高频播报时每条消息都重新建连接。 httpClient *http.Client } -// NewRESTClient validates config and creates a Tencent Cloud Chat REST client. +// NewRESTClient 校验必需配置并创建 REST client。 func NewRESTClient(cfg RESTConfig) (*RESTClient, error) { if cfg.SDKAppID <= 0 || cfg.SecretKey == "" || strings.TrimSpace(cfg.AdminIdentifier) == "" { - // REST API requires an App administrator identifier and a valid admin UserSig. + // REST API 依赖管理员账号和 admin UserSig;缺任何一个都不能伪造成功。 return nil, fmt.Errorf("tencent im rest config is incomplete") } if cfg.AdminUserSigTTL <= 0 { @@ -94,7 +116,8 @@ func NewRESTClient(cfg RESTConfig) (*RESTClient, error) { }, nil } -// EnsureRoomGroup creates the Tencent Cloud Chat group for a voice room. +// EnsureRoomGroup 为房间创建腾讯云 IM 群。 +// ownerUserID 暂不映射为腾讯群主,房间状态 owner 仍是 Room Cell,腾讯群只做投递通道。 func (c *RESTClient) EnsureRoomGroup(ctx context.Context, roomID string, ownerUserID int64) error { roomID = strings.TrimSpace(roomID) if roomID == "" { @@ -102,11 +125,41 @@ func (c *RESTClient) EnsureRoomGroup(ctx context.Context, roomID string, ownerUs } _ = ownerUserID - request := createGroupRequest{ - Type: c.cfg.GroupType, + return c.EnsureGroup(ctx, GroupSpec{ GroupID: roomID, Name: roomID, + Type: c.cfg.GroupType, ApplyJoinOption: "FreeAccess", + }) +} + +// EnsureGroup 创建服务端拥有的腾讯云 IM 群,并把“自定义 GroupID 已存在”视为成功。 +// 这样启动 reconciler、CreateRoom 重试或发布补偿重复执行时,都不会因为已建群而中断主流程。 +func (c *RESTClient) EnsureGroup(ctx context.Context, spec GroupSpec) error { + spec.GroupID = strings.TrimSpace(spec.GroupID) + spec.Name = strings.TrimSpace(spec.Name) + spec.Type = strings.TrimSpace(spec.Type) + spec.ApplyJoinOption = strings.TrimSpace(spec.ApplyJoinOption) + spec.OwnerAccount = strings.TrimSpace(spec.OwnerAccount) + if spec.GroupID == "" { + return fmt.Errorf("group_id is required") + } + if spec.Name == "" { + spec.Name = spec.GroupID + } + if spec.Type == "" { + spec.Type = c.cfg.GroupType + } + if spec.ApplyJoinOption == "" { + spec.ApplyJoinOption = "FreeAccess" + } + + request := createGroupRequest{ + Type: spec.Type, + GroupID: spec.GroupID, + Name: spec.Name, + OwnerAccount: spec.OwnerAccount, + ApplyJoinOption: spec.ApplyJoinOption, } var response restResponse @@ -114,17 +167,17 @@ func (c *RESTClient) EnsureRoomGroup(ctx context.Context, roomID string, ownerUs return err } if response.ErrorCode == 10021 || response.ErrorCode == 10025 { - // Custom GroupId already exists; for idempotent CreateRoom retry this is success. + // 腾讯云不同接口版本可能返回 10021/10025 表示群已存在;建群语义要求幂等。 return nil } return response.err() } -// PublishRoomEvent converts a room system event into a Tencent group custom message. +// PublishRoomEvent 把房间系统事件转换为腾讯云群自定义消息。 func (c *RESTClient) PublishRoomEvent(ctx context.Context, event RoomEvent) error { if strings.TrimSpace(event.RoomID) == "" || strings.TrimSpace(event.EventID) == "" { - // event_id is Tencent-side idempotency anchor in CloudCustomData. + // event_id 是客户端去重、日志追踪和补偿投递判断的共同锚点。 return fmt.Errorf("room event is incomplete") } @@ -133,21 +186,44 @@ func (c *RESTClient) PublishRoomEvent(ctx context.Context, event RoomEvent) erro return err } + return c.PublishGroupCustomMessage(ctx, CustomGroupMessage{ + GroupID: event.RoomID, + EventID: event.EventID, + Desc: event.EventType, + Ext: "room_system_message", + PayloadJSON: eventPayload, + }) +} + +// PublishGroupCustomMessage 向任意服务端拥有的腾讯云 IM 群发送 TIMCustomElem。 +// 该方法不判断业务类型,调用方必须已经通过 room/broadcast service 完成权限、幂等和持久化决策。 +func (c *RESTClient) PublishGroupCustomMessage(ctx context.Context, message CustomGroupMessage) error { + message.GroupID = strings.TrimSpace(message.GroupID) + message.EventID = strings.TrimSpace(message.EventID) + message.Desc = strings.TrimSpace(message.Desc) + message.Ext = strings.TrimSpace(message.Ext) + message.FromAccount = strings.TrimSpace(message.FromAccount) + payload := bytes.TrimSpace(message.PayloadJSON) + if message.GroupID == "" || message.EventID == "" || len(payload) == 0 { + return fmt.Errorf("group custom message is incomplete") + } + request := sendGroupMsgRequest{ - GroupID: event.RoomID, - Random: randomUint32(), + GroupID: message.GroupID, + Random: randomUint32(), + CloudCustomData: string(payload), + FromAccount: message.FromAccount, MsgBody: []messageElement{ { MsgType: "TIMCustomElem", MsgContent: customMsgContent{ - Data: string(eventPayload), - Desc: event.EventType, - Ext: "room_system_message", + Data: string(payload), + Desc: message.Desc, + Ext: message.Ext, Sound: "", }, }, }, - CloudCustomData: string(eventPayload), } var response restResponse @@ -158,15 +234,33 @@ func (c *RESTClient) PublishRoomEvent(ctx context.Context, event RoomEvent) erro return response.err() } -// DeleteRoomGroupMember removes a room user from the Tencent Cloud Chat group. -func (c *RESTClient) DeleteRoomGroupMember(ctx context.Context, roomID string, userID int64) error { - roomID = strings.TrimSpace(roomID) - if roomID == "" || userID <= 0 { - return fmt.Errorf("room group member removal is incomplete") +// DestroyGroup 解散一个腾讯云 IM 群。 +// 生产播报群不应该在业务流里自动调用该方法;它主要用于真实 IM 测试后的临时群清理或显式运维操作。 +func (c *RESTClient) DestroyGroup(ctx context.Context, groupID string) error { + groupID = strings.TrimSpace(groupID) + if groupID == "" { + return fmt.Errorf("group_id is required") + } + + request := destroyGroupRequest{GroupID: groupID} + var response restResponse + if err := c.post(ctx, destroyGroupCommand, request, &response); err != nil { + return err + } + + return response.err() +} + +// DeleteGroupMember 从指定腾讯云 IM 群移除一个用户。 +// 它只改变“这个用户在这个群里的成员关系”,不会删除群,也不会影响其他成员。 +func (c *RESTClient) DeleteGroupMember(ctx context.Context, groupID string, userID int64) error { + groupID = strings.TrimSpace(groupID) + if groupID == "" || userID <= 0 { + return fmt.Errorf("group member removal is incomplete") } request := deleteGroupMemberRequest{ - GroupID: roomID, + GroupID: groupID, MemberToDelAccount: []string{FormatUserID(userID)}, Silence: 1, } @@ -179,9 +273,14 @@ func (c *RESTClient) DeleteRoomGroupMember(ctx context.Context, roomID string, u return response.err() } -// FormatUserID converts the internal immutable user_id to the Tencent Chat identifier. +// DeleteRoomGroupMember 从房间 IM 群移除用户;这是 presence 清理的外部副作用,不改变房间权威状态。 +func (c *RESTClient) DeleteRoomGroupMember(ctx context.Context, roomID string, userID int64) error { + return c.DeleteGroupMember(ctx, roomID, userID) +} + +// FormatUserID 把内部不可变 user_id 映射成腾讯云账号字符串。 func FormatUserID(userID int64) string { - // Decimal user_id is stable across services and avoids exposing mutable display_user_id. + // 十进制 user_id 跨服务稳定,也避免把可变 display_user_id 暴露给 IM 账号体系。 return strconv.FormatInt(userID, 10) } @@ -208,7 +307,7 @@ func (c *RESTClient) post(ctx context.Context, command string, payload any, out return err } if response.StatusCode < 200 || response.StatusCode >= 300 { - // Tencent REST normally returns HTTP 200 with ErrorCode; non-2xx is transport failure. + // 腾讯 REST 正常业务失败通常是 HTTP 200 + ErrorCode;非 2xx 视为网络/网关层失败。 return fmt.Errorf("tencent im http status %d: %s", response.StatusCode, string(responseBody)) } if err := json.Unmarshal(responseBody, out); err != nil { @@ -223,7 +322,7 @@ func (c *RESTClient) endpoint(command string) string { SDKAppID: c.cfg.SDKAppID, SecretKey: c.cfg.SecretKey, TTL: c.cfg.AdminUserSigTTL, - }, c.cfg.AdminIdentifier, time.Now()) + }, c.cfg.AdminIdentifier, time.Now().UTC()) values := url.Values{} values.Set("sdkappid", strconv.FormatInt(c.cfg.SDKAppID, 10)) @@ -238,7 +337,7 @@ func (c *RESTClient) endpoint(command string) string { func randomUint32() uint32 { var payload [4]byte if _, err := rand.Read(payload[:]); err != nil { - // Cryptographic randomness is preferred, but REST random only needs dedupe entropy. + // REST random 只需要足够的去重熵;加密随机失败时用纳秒时间兜底。 return uint32(time.Now().UnixNano()) } @@ -256,7 +355,7 @@ func (r restResponse) err() error { return nil } if r.ErrorCode == 0 && r.ActionStatus == "" { - // Some tests only decode partial responses; keep zero-code as success. + // 部分测试只构造 ErrorCode;腾讯语义里 0 即成功,因此允许空 ActionStatus。 return nil } @@ -279,6 +378,10 @@ type sendGroupMsgRequest struct { FromAccount string `json:"From_Account,omitempty"` } +type destroyGroupRequest struct { + GroupID string `json:"GroupId"` +} + type deleteGroupMemberRequest struct { GroupID string `json:"GroupId"` MemberToDelAccount []string `json:"MemberToDel_Account"` diff --git a/pkg/tencentim/rest_client_real_test.go b/pkg/tencentim/rest_client_real_test.go new file mode 100644 index 00000000..877741f9 --- /dev/null +++ b/pkg/tencentim/rest_client_real_test.go @@ -0,0 +1,151 @@ +package tencentim + +import ( + "context" + "encoding/json" + "fmt" + "os" + "strconv" + "strings" + "testing" + "time" +) + +func TestRealTencentIMCreateSendAndDestroyGroup(t *testing.T) { + if os.Getenv("TENCENT_IM_REAL_TEST") != "1" { + t.Skip("set TENCENT_IM_REAL_TEST=1 and Tencent IM env vars to run the real REST smoke test") + } + + cfg := realRESTConfigFromEnv(t) + client, err := NewRESTClient(cfg) + if err != nil { + t.Fatalf("NewRESTClient failed: %v", err) + } + + nowMS := time.Now().UTC().UnixMilli() + groupID := fmt.Sprintf("hy_codex_bc_r_%d", nowMS) + eventID := fmt.Sprintf("codex_real_im_%d", nowMS) + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + + // 真实 IM 测试必须使用临时 GroupID,避免污染业务全局/区域播报群。 + if err := client.EnsureGroup(ctx, GroupSpec{ + GroupID: groupID, + Name: "codex real im smoke", + Type: DefaultGroupType, + ApplyJoinOption: "FreeAccess", + }); err != nil { + t.Fatalf("real Tencent IM create group failed: %v", err) + } + t.Cleanup(func() { + cleanupCtx, cleanupCancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cleanupCancel() + if err := client.DestroyGroup(cleanupCtx, groupID); err != nil { + t.Errorf("real Tencent IM destroy group cleanup failed: %v", err) + } + }) + memberUserID := nowMS % 9_000_000_000 + if err := realImportAccount(ctx, client, memberUserID); err != nil { + t.Fatalf("real Tencent IM account import failed: %v", err) + } + if err := realAddGroupMember(ctx, client, groupID, memberUserID); err != nil { + t.Fatalf("real Tencent IM add group member failed: %v", err) + } + + payload, err := json.Marshal(map[string]any{ + "event_id": eventID, + "broadcast_type": "codex_real_im_smoke", + "scope": "region", + "app_code": "codex", + "region_id": 210, + "sent_at_ms": nowMS, + "action": map[string]any{ + "type": "enter_room", + "room_id": "codex-room-smoke", + }, + }) + if err != nil { + t.Fatalf("marshal smoke payload failed: %v", err) + } + + // 真正向腾讯云 IM REST 发送 TIMCustomElem;成功只表示腾讯服务端接受消息,不代表有客户端在线展示。 + if err := client.PublishGroupCustomMessage(ctx, CustomGroupMessage{ + GroupID: groupID, + EventID: eventID, + Desc: "codex_real_im_smoke", + Ext: "im_broadcast", + PayloadJSON: payload, + }); err != nil { + t.Fatalf("real Tencent IM send group custom message failed: %v", err) + } + if err := client.DeleteGroupMember(ctx, groupID, memberUserID); err != nil { + t.Fatalf("real Tencent IM delete group member failed: %v", err) + } + + t.Logf("real Tencent IM smoke passed: sdk_app_id=%d group_id=%s event_id=%s removed_user_id=%d", cfg.SDKAppID, groupID, eventID, memberUserID) +} + +func realImportAccount(ctx context.Context, client *RESTClient, userID int64) error { + var response restResponse + if err := client.post(ctx, "v4/im_open_login_svc/account_import", map[string]any{ + "UserID": strconv.FormatInt(userID, 10), + "Nick": "codex-im-smoke", + }, &response); err != nil { + return err + } + return response.err() +} + +func realAddGroupMember(ctx context.Context, client *RESTClient, groupID string, userID int64) error { + var response restResponse + if err := client.post(ctx, "v4/group_open_http_svc/add_group_member", map[string]any{ + "GroupId": groupID, + "Silence": 1, + "MemberList": []map[string]any{ + {"Member_Account": strconv.FormatInt(userID, 10)}, + }, + }, &response); err != nil { + return err + } + return response.err() +} + +func realRESTConfigFromEnv(t *testing.T) RESTConfig { + t.Helper() + + sdkAppID, err := strconv.ParseInt(requiredEnv(t, "TENCENT_IM_SDK_APP_ID"), 10, 64) + if err != nil || sdkAppID <= 0 { + t.Fatalf("TENCENT_IM_SDK_APP_ID is invalid") + } + endpoint := strings.TrimSpace(os.Getenv("TENCENT_IM_ENDPOINT")) + if endpoint == "" { + endpoint = DefaultEndpoint + } + adminUserSigTTL := time.Hour + if rawTTL := strings.TrimSpace(os.Getenv("TENCENT_IM_ADMIN_USERSIG_TTL")); rawTTL != "" { + parsed, err := time.ParseDuration(rawTTL) + if err != nil || parsed <= 0 { + t.Fatalf("TENCENT_IM_ADMIN_USERSIG_TTL is invalid") + } + adminUserSigTTL = parsed + } + + return RESTConfig{ + SDKAppID: sdkAppID, + SecretKey: requiredEnv(t, "TENCENT_IM_SECRET_KEY"), + AdminIdentifier: requiredEnv(t, "TENCENT_IM_ADMIN_IDENTIFIER"), + AdminUserSigTTL: adminUserSigTTL, + Endpoint: endpoint, + GroupType: DefaultGroupType, + } +} + +func requiredEnv(t *testing.T, key string) string { + t.Helper() + + value := strings.TrimSpace(os.Getenv(key)) + if value == "" { + t.Fatalf("%s is required for real Tencent IM smoke test", key) + } + return value +} diff --git a/pkg/tencentim/rest_client_test.go b/pkg/tencentim/rest_client_test.go index 43154a31..18550de2 100644 --- a/pkg/tencentim/rest_client_test.go +++ b/pkg/tencentim/rest_client_test.go @@ -93,6 +93,60 @@ func TestRESTClientPublishRoomEventBuildsCustomMessage(t *testing.T) { } } +func TestRESTClientPublishGroupCustomMessageBuildsBroadcastPayload(t *testing.T) { + var capturedBody map[string]any + client := newTestRESTClient(t, func(request *http.Request) (*http.Response, error) { + if err := json.NewDecoder(request.Body).Decode(&capturedBody); err != nil { + t.Fatalf("decode request body failed: %v", err) + } + return okRESTResponse(), nil + }) + + err := client.PublishGroupCustomMessage(context.Background(), CustomGroupMessage{ + GroupID: "hy_lalu_bc_r_1001", + EventID: "gift_broadcast:room-1:cmd-1", + Desc: "super_gift", + Ext: "im_broadcast", + FromAccount: "administrator", + PayloadJSON: json.RawMessage(`{"event_id":"gift_broadcast:room-1:cmd-1","broadcast_type":"super_gift"}`), + }) + if err != nil { + t.Fatalf("PublishGroupCustomMessage failed: %v", err) + } + + if capturedBody["GroupId"] != "hy_lalu_bc_r_1001" || capturedBody["From_Account"] != "administrator" { + t.Fatalf("broadcast target mismatch: %+v", capturedBody) + } + if capturedBody["CloudCustomData"] != `{"event_id":"gift_broadcast:room-1:cmd-1","broadcast_type":"super_gift"}` { + t.Fatalf("cloud custom data mismatch: %+v", capturedBody) + } +} + +// TestRESTClientDestroyGroupBuildsTencentRequest 锁定临时群清理的 REST 请求。 +func TestRESTClientDestroyGroupBuildsTencentRequest(t *testing.T) { + var capturedPath string + var capturedBody map[string]any + client := newTestRESTClient(t, func(request *http.Request) (*http.Response, error) { + capturedPath = request.URL.Path + if err := json.NewDecoder(request.Body).Decode(&capturedBody); err != nil { + t.Fatalf("decode request body failed: %v", err) + } + + return okRESTResponse(), nil + }) + + if err := client.DestroyGroup(context.Background(), "hy_codex_bc_r_210"); err != nil { + t.Fatalf("DestroyGroup failed: %v", err) + } + + if capturedPath != "/"+destroyGroupCommand { + t.Fatalf("path mismatch: got %q", capturedPath) + } + if capturedBody["GroupId"] != "hy_codex_bc_r_210" { + t.Fatalf("unexpected destroy group body: %+v", capturedBody) + } +} + // TestRESTClientDeleteRoomGroupMemberBuildsTencentRequest 锁定踢出 IM 群成员的 REST 请求。 func TestRESTClientDeleteRoomGroupMemberBuildsTencentRequest(t *testing.T) { var capturedPath string diff --git a/server/admin/cmd/server/main.go b/server/admin/cmd/server/main.go index 4919d14c..b6f38c4a 100644 --- a/server/admin/cmd/server/main.go +++ b/server/admin/cmd/server/main.go @@ -82,7 +82,12 @@ func main() { LogLevel: logger.Warn, IgnoreRecordNotFoundError: true, }) - db, err := gorm.Open(mysql.Open(cfg.MySQLDSN), &gorm.Config{Logger: dbLogger}) + db, err := gorm.Open(mysql.Open(cfg.MySQLDSN), &gorm.Config{ + Logger: dbLogger, + NowFunc: func() time.Time { + return time.Now().UTC() + }, + }) if err != nil { fatalRuntime("connect_mysql_failed", err) } @@ -91,7 +96,9 @@ func main() { fatalRuntime("mysql_db_handle_failed", err) } if cfg.Migrations.Enabled { - if err := migration.Apply(context.Background(), sqlDB, cfg.Migrations.Dir); err != nil { + if err := migration.ApplyWithOptions(context.Background(), sqlDB, cfg.Migrations.Dir, migration.Options{ + AllowChecksumRepair: cfg.Migrations.AllowChecksumRepair, + }); err != nil { fatalRuntime("apply_migrations_failed", err) } } @@ -191,7 +198,7 @@ func main() { AdminUser: adminusermodule.New(store, cfg, auditHandler), AppConfig: appconfigmodule.New(store, auditHandler), AppRegistry: appregistrymodule.New(userDB), - AppUser: appusermodule.New(userclient.NewGRPC(userConn), userDB, walletDB, cfg, auditHandler), + AppUser: appusermodule.New(userclient.NewGRPC(userConn), activityclient.NewGRPC(activityConn), userDB, walletDB, cfg, auditHandler), CountryRegion: countryregionmodule.New(userclient.NewGRPC(userConn), userDB, cfg, auditHandler), DailyTask: dailytaskmodule.New(activityclient.NewGRPC(activityConn), auditHandler), Dashboard: dashboardmodule.New(store), diff --git a/server/admin/configs/config.yaml b/server/admin/configs/config.yaml index 706be4d2..6cf3bfc6 100644 --- a/server/admin/configs/config.yaml +++ b/server/admin/configs/config.yaml @@ -8,14 +8,16 @@ log: include_response_body: false max_payload_bytes: 2048 http_addr: ":13100" -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=Local" -user_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=Local" -wallet_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local" -room_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=UTC" +user_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=UTC" +wallet_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC" +room_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC" mysql_auto_migrate: true migrations: enabled: true dir: "migrations" + # 本地开发阶段允许历史 migration 文件被修改后修复 checksum;staging/prod 必须关闭。 + allow_checksum_repair: true jwt_secret: "dev-shared-secret" access_token_ttl: "30m" refresh_token_ttl: "168h" diff --git a/server/admin/internal/config/config.go b/server/admin/internal/config/config.go index 6560c7e7..e1b74168 100644 --- a/server/admin/internal/config/config.go +++ b/server/admin/internal/config/config.go @@ -40,8 +40,9 @@ type Config struct { } type MigrationConfig struct { - Enabled bool `yaml:"enabled"` - Dir string `yaml:"dir"` + Enabled bool `yaml:"enabled"` + Dir string `yaml:"dir"` + AllowChecksumRepair bool `yaml:"allow_checksum_repair"` } type UserServiceConfig struct { @@ -101,14 +102,15 @@ func Default() Config { Environment: "local", Log: logging.DefaultConfig(), HTTPAddr: ":13100", - MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=Local", - UserMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=Local", - WalletMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local", - RoomMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local", + MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=UTC", + UserMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=UTC", + WalletMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC", + RoomMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC", MySQLAutoMigrate: true, Migrations: MigrationConfig{ - Enabled: true, - Dir: "migrations", + Enabled: true, + Dir: "migrations", + AllowChecksumRepair: true, }, JWTSecret: "dev-shared-secret", AccessTokenTTL: 30 * time.Minute, @@ -260,6 +262,9 @@ func (cfg Config) Validate() error { if cfg.Migrations.Enabled && strings.TrimSpace(cfg.Migrations.Dir) == "" { return errors.New("migrations.dir is required when migrations are enabled") } + if isLockedEnvironment(cfg.Environment) && cfg.Migrations.AllowChecksumRepair { + return errors.New("migrations.allow_checksum_repair must be false outside local/dev") + } if strings.TrimSpace(cfg.JWTSecret) == "" { return errors.New("jwt_secret is required") } diff --git a/server/admin/internal/config/config_test.go b/server/admin/internal/config/config_test.go index c6ecf7a3..deb90d30 100644 --- a/server/admin/internal/config/config_test.go +++ b/server/admin/internal/config/config_test.go @@ -15,10 +15,10 @@ func TestLoadConfigYAML(t *testing.T) { if cfg.HTTPAddr != ":13100" { t.Fatalf("HTTPAddr = %q", cfg.HTTPAddr) } - if cfg.MySQLDSN != "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=Local" { + if cfg.MySQLDSN != "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=UTC" { t.Fatalf("MySQLDSN = %q", cfg.MySQLDSN) } - if cfg.UserMySQLDSN != "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=Local" { + if cfg.UserMySQLDSN != "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=UTC" { t.Fatalf("UserMySQLDSN = %q", cfg.UserMySQLDSN) } if cfg.AccessTokenTTL != 30*time.Minute { @@ -27,6 +27,9 @@ func TestLoadConfigYAML(t *testing.T) { if cfg.RefreshTokenTTL != 7*24*time.Hour { t.Fatalf("RefreshTokenTTL = %s", cfg.RefreshTokenTTL) } + if !cfg.Migrations.AllowChecksumRepair { + t.Fatalf("Migrations.AllowChecksumRepair = false, want true for local config") + } if !cfg.TencentCOS.Enabled || cfg.TencentCOS.BucketName != "yumi-assets-1420526837" || cfg.TencentCOS.ObjectPrefix != "admin" { t.Fatalf("TencentCOS = %#v", cfg.TencentCOS) } diff --git a/server/admin/internal/integration/activityclient/client.go b/server/admin/internal/integration/activityclient/client.go index 1fcf4b6c..1254f89c 100644 --- a/server/admin/internal/integration/activityclient/client.go +++ b/server/admin/internal/integration/activityclient/client.go @@ -13,24 +13,33 @@ type Client interface { ListTaskDefinitions(ctx context.Context, req *activityv1.ListTaskDefinitionsRequest) (*activityv1.ListTaskDefinitionsResponse, error) UpsertTaskDefinition(ctx context.Context, req *activityv1.UpsertTaskDefinitionRequest) (*activityv1.UpsertTaskDefinitionResponse, error) SetTaskDefinitionStatus(ctx context.Context, req *activityv1.SetTaskDefinitionStatusRequest) (*activityv1.SetTaskDefinitionStatusResponse, error) + RemoveRegionBroadcastMember(ctx context.Context, req *activityv1.RemoveRegionBroadcastMemberRequest) (*activityv1.RemoveRegionBroadcastMemberResponse, error) } type GRPCClient struct { - client activityv1.AdminTaskServiceClient + taskClient activityv1.AdminTaskServiceClient + broadcastClient activityv1.BroadcastServiceClient } func NewGRPC(conn grpc.ClientConnInterface) *GRPCClient { - return &GRPCClient{client: activityv1.NewAdminTaskServiceClient(conn)} + return &GRPCClient{ + taskClient: activityv1.NewAdminTaskServiceClient(conn), + broadcastClient: activityv1.NewBroadcastServiceClient(conn), + } } func (c *GRPCClient) ListTaskDefinitions(ctx context.Context, req *activityv1.ListTaskDefinitionsRequest) (*activityv1.ListTaskDefinitionsResponse, error) { - return c.client.ListTaskDefinitions(ctx, req) + return c.taskClient.ListTaskDefinitions(ctx, req) } func (c *GRPCClient) UpsertTaskDefinition(ctx context.Context, req *activityv1.UpsertTaskDefinitionRequest) (*activityv1.UpsertTaskDefinitionResponse, error) { - return c.client.UpsertTaskDefinition(ctx, req) + return c.taskClient.UpsertTaskDefinition(ctx, req) } func (c *GRPCClient) SetTaskDefinitionStatus(ctx context.Context, req *activityv1.SetTaskDefinitionStatusRequest) (*activityv1.SetTaskDefinitionStatusResponse, error) { - return c.client.SetTaskDefinitionStatus(ctx, req) + return c.taskClient.SetTaskDefinitionStatus(ctx, req) +} + +func (c *GRPCClient) RemoveRegionBroadcastMember(ctx context.Context, req *activityv1.RemoveRegionBroadcastMemberRequest) (*activityv1.RemoveRegionBroadcastMemberResponse, error) { + return c.broadcastClient.RemoveRegionBroadcastMember(ctx, req) } diff --git a/server/admin/internal/job/runner.go b/server/admin/internal/job/runner.go index 5faf32bb..c660a5d2 100644 --- a/server/admin/internal/job/runner.go +++ b/server/admin/internal/job/runner.go @@ -204,8 +204,8 @@ func (r *Runner) writeUserExport(job *model.AdminJob, users []model.User) (strin _ = writer.Write([]string{"ID", "账号", "姓名", "角色", "团队", "状态", "MFA", "最后登录"}) for _, user := range users { lastLogin := "" - if user.LastLoginAt != nil { - lastLogin = user.LastLoginAt.Format("2006-01-02 15:04:05") + if user.LastLoginAtMS != nil { + lastLogin = time.UnixMilli(*user.LastLoginAtMS).UTC().Format("2006-01-02 15:04:05") } _ = writer.Write([]string{ fmt.Sprintf("%d", user.ID), diff --git a/server/admin/internal/middleware/request.go b/server/admin/internal/middleware/request.go index d5e2d6f6..2450289b 100644 --- a/server/admin/internal/middleware/request.go +++ b/server/admin/internal/middleware/request.go @@ -42,5 +42,5 @@ func newRequestID() string { if _, err := rand.Read(raw[:]); err == nil { return hex.EncodeToString(raw[:]) } - return hex.EncodeToString([]byte(time.Now().Format("20060102150405.000000000"))) + return hex.EncodeToString([]byte(time.Now().UTC().Format("20060102150405.000000000"))) } diff --git a/server/admin/internal/migration/migration.go b/server/admin/internal/migration/migration.go index dfcf4d35..d63a562b 100644 --- a/server/admin/internal/migration/migration.go +++ b/server/admin/internal/migration/migration.go @@ -11,9 +11,21 @@ import ( "path/filepath" "sort" "strings" + "time" ) +// Options controls migration repair behavior. +type Options struct { + // AllowChecksumRepair lets local/dev databases accept edited historical migrations. + // Production-like environments must keep this false so checksum drift fails closed. + AllowChecksumRepair bool +} + func Apply(ctx context.Context, db *sql.DB, dir string) error { + return ApplyWithOptions(ctx, db, dir, Options{}) +} + +func ApplyWithOptions(ctx context.Context, db *sql.DB, dir string, options Options) error { if strings.TrimSpace(dir) == "" { return errors.New("migration dir is required") } @@ -30,7 +42,7 @@ func Apply(ctx context.Context, db *sql.DB, dir string) error { } for _, file := range files { version := filepath.Base(file) - applied, err := isApplied(ctx, db, version, file) + applied, err := isApplied(ctx, db, version, file, options) if err != nil { return err } @@ -50,14 +62,17 @@ CREATE TABLE IF NOT EXISTS schema_migrations ( version VARCHAR(128) PRIMARY KEY, checksum CHAR(64) NOT NULL DEFAULT '', dirty BOOLEAN NOT NULL DEFAULT FALSE, - applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + applied_at_ms BIGINT NOT NULL DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`); err != nil { return err } if err := ensureColumn(ctx, db, "checksum", "ALTER TABLE schema_migrations ADD COLUMN checksum CHAR(64) NOT NULL DEFAULT '' AFTER version"); err != nil { return err } - return ensureColumn(ctx, db, "dirty", "ALTER TABLE schema_migrations ADD COLUMN dirty BOOLEAN NOT NULL DEFAULT FALSE AFTER checksum") + if err := ensureColumn(ctx, db, "dirty", "ALTER TABLE schema_migrations ADD COLUMN dirty BOOLEAN NOT NULL DEFAULT FALSE AFTER checksum"); err != nil { + return err + } + return ensureColumn(ctx, db, "applied_at_ms", "ALTER TABLE schema_migrations ADD COLUMN applied_at_ms BIGINT NOT NULL DEFAULT 0 AFTER dirty") } func ensureColumn(ctx context.Context, db *sql.DB, column string, alter string) error { @@ -92,7 +107,7 @@ func migrationFiles(dir string) ([]string, error) { return files, nil } -func isApplied(ctx context.Context, db *sql.DB, version string, file string) (bool, error) { +func isApplied(ctx context.Context, db *sql.DB, version string, file string, options Options) (bool, error) { var row migrationRow err := db.QueryRowContext(ctx, "SELECT version, checksum, dirty FROM schema_migrations WHERE version = ?", version).Scan(&row.Version, &row.Checksum, &row.Dirty) if errors.Is(err, sql.ErrNoRows) { @@ -110,6 +125,13 @@ func isApplied(ctx context.Context, db *sql.DB, version string, file string) (bo } sum := checksum(body) if row.Checksum != "" && row.Checksum != sum { + if options.AllowChecksumRepair { + // 本地开发阶段允许直接编辑历史迁移;修复只更新记录,不重放历史 SQL,避免重复 ALTER 破坏现有库。 + if _, err := db.ExecContext(ctx, "UPDATE schema_migrations SET checksum = ? WHERE version = ?", sum, version); err != nil { + return false, err + } + return true, nil + } return false, fmt.Errorf("migration %s checksum changed", version) } if row.Checksum == "" { @@ -151,7 +173,7 @@ func applyFile(ctx context.Context, db *sql.DB, version string, file string) err return fmt.Errorf("apply migration %s: %w", version, err) } } - if _, err := db.ExecContext(ctx, "UPDATE schema_migrations SET dirty = FALSE, checksum = ?, applied_at = CURRENT_TIMESTAMP WHERE version = ?", sum, version); err != nil { + if _, err := db.ExecContext(ctx, "UPDATE schema_migrations SET dirty = FALSE, checksum = ?, applied_at_ms = ? WHERE version = ?", sum, time.Now().UTC().UnixMilli(), version); err != nil { return err } return nil diff --git a/server/admin/internal/model/models.go b/server/admin/internal/model/models.go index d1d85b0f..ebbf228f 100644 --- a/server/admin/internal/model/models.go +++ b/server/admin/internal/model/models.go @@ -1,7 +1,5 @@ package model -import "time" - const ( UserStatusActive = "active" UserStatusLocked = "locked" @@ -15,17 +13,17 @@ const ( ) type User struct { - ID uint `gorm:"primaryKey" json:"id"` - Username string `gorm:"size:64;uniqueIndex;not null" json:"account"` - Name string `gorm:"size:80;not null" json:"name"` - PasswordHash string `gorm:"size:255;not null" json:"-"` - Team string `gorm:"size:80" json:"team"` - Status string `gorm:"size:24;index;not null;default:active" json:"status"` - MFAEnabled bool `gorm:"not null;default:false" json:"mfaEnabled"` - LastLoginAt *time.Time `json:"lastLoginAt"` - Roles []Role `gorm:"many2many:admin_user_roles;" json:"roles"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + Username string `gorm:"size:64;uniqueIndex;not null" json:"account"` + Name string `gorm:"size:80;not null" json:"name"` + PasswordHash string `gorm:"size:255;not null" json:"-"` + Team string `gorm:"size:80" json:"team"` + Status string `gorm:"size:24;index;not null;default:active" json:"status"` + MFAEnabled bool `gorm:"not null;default:false" json:"mfaEnabled"` + LastLoginAtMS *int64 `gorm:"column:last_login_at_ms" json:"lastLoginAtMs"` + Roles []Role `gorm:"many2many:admin_user_roles;" json:"roles"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (User) TableName() string { @@ -39,8 +37,8 @@ type Role struct { Description string `gorm:"size:255" json:"description"` Users []User `gorm:"many2many:admin_user_roles;" json:"-"` Permissions []Permission `gorm:"many2many:admin_role_permissions;" json:"permissions"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (Role) TableName() string { @@ -48,13 +46,13 @@ func (Role) TableName() string { } type Permission struct { - ID uint `gorm:"primaryKey" json:"id"` - Name string `gorm:"size:100;not null" json:"name"` - Code string `gorm:"size:100;uniqueIndex;not null" json:"code"` - Kind string `gorm:"size:32;index;not null" json:"kind"` - Description string `gorm:"size:255" json:"description"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + Name string `gorm:"size:100;not null" json:"name"` + Code string `gorm:"size:100;uniqueIndex;not null" json:"code"` + Kind string `gorm:"size:32;index;not null" json:"kind"` + Description string `gorm:"size:255" json:"description"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (Permission) TableName() string { @@ -62,17 +60,17 @@ func (Permission) TableName() string { } type Menu struct { - ID uint `gorm:"primaryKey" json:"id"` - ParentID *uint `gorm:"index" json:"parentId"` - Title string `gorm:"size:80;not null" json:"label"` - Code string `gorm:"size:100;uniqueIndex;not null" json:"code"` - Path string `gorm:"size:160" json:"path"` - Icon string `gorm:"size:64" json:"icon"` - PermissionCode string `gorm:"size:100;index" json:"permissionCode"` - Sort int `gorm:"not null;default:0" json:"sort"` - Visible bool `gorm:"not null;default:true" json:"visible"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + ParentID *uint `gorm:"index" json:"parentId"` + Title string `gorm:"size:80;not null" json:"label"` + Code string `gorm:"size:100;uniqueIndex;not null" json:"code"` + Path string `gorm:"size:160" json:"path"` + Icon string `gorm:"size:64" json:"icon"` + PermissionCode string `gorm:"size:100;index" json:"permissionCode"` + Sort int `gorm:"not null;default:0" json:"sort"` + Visible bool `gorm:"not null;default:true" json:"visible"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (Menu) TableName() string { @@ -80,13 +78,13 @@ func (Menu) TableName() string { } type AppConfig struct { - ID uint `gorm:"primaryKey" json:"id"` - Group string `gorm:"size:64;index:idx_admin_app_config_group_key,unique;not null" json:"group"` - Key string `gorm:"size:100;index:idx_admin_app_config_group_key,unique;not null" json:"key"` - Value string `gorm:"type:text" json:"value"` - Description string `gorm:"size:255" json:"description"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + Group string `gorm:"size:64;index:idx_admin_app_config_group_key,unique;not null" json:"group"` + Key string `gorm:"size:100;index:idx_admin_app_config_group_key,unique;not null" json:"key"` + Value string `gorm:"type:text" json:"value"` + Description string `gorm:"size:255" json:"description"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (AppConfig) TableName() string { @@ -94,19 +92,19 @@ func (AppConfig) TableName() string { } type AppBanner struct { - ID uint `gorm:"primaryKey" json:"id"` - AppCode string `gorm:"size:32;index:idx_admin_app_banners_app_sort,not null;default:lalu" json:"appCode"` - CoverURL string `gorm:"size:1024;not null" json:"coverUrl"` - BannerType string `gorm:"size:16;not null" json:"bannerType"` - Param string `gorm:"size:2048" json:"param"` - Status string `gorm:"size:24;index:idx_admin_app_banners_app_sort,not null;default:active" json:"status"` - Platform string `gorm:"size:24;index:idx_admin_app_banners_scope,not null" json:"platform"` - SortOrder int `gorm:"index:idx_admin_app_banners_app_sort,not null;default:0" json:"sortOrder"` - RegionID int64 `gorm:"index:idx_admin_app_banners_scope,not null;default:0" json:"regionId"` - CountryCode string `gorm:"size:8;index:idx_admin_app_banners_scope" json:"countryCode"` - Description string `gorm:"size:255" json:"description"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + AppCode string `gorm:"size:32;index:idx_admin_app_banners_app_sort,not null;default:lalu" json:"appCode"` + CoverURL string `gorm:"size:1024;not null" json:"coverUrl"` + BannerType string `gorm:"size:16;not null" json:"bannerType"` + Param string `gorm:"size:2048" json:"param"` + Status string `gorm:"size:24;index:idx_admin_app_banners_app_sort,not null;default:active" json:"status"` + Platform string `gorm:"size:24;index:idx_admin_app_banners_scope,not null" json:"platform"` + SortOrder int `gorm:"index:idx_admin_app_banners_app_sort,not null;default:0" json:"sortOrder"` + RegionID int64 `gorm:"index:idx_admin_app_banners_scope,not null;default:0" json:"regionId"` + CountryCode string `gorm:"size:8;index:idx_admin_app_banners_scope" json:"countryCode"` + Description string `gorm:"size:255" json:"description"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (AppBanner) TableName() string { @@ -114,15 +112,15 @@ func (AppBanner) TableName() string { } type RefreshToken struct { - ID uint `gorm:"primaryKey" json:"id"` - UserID uint `gorm:"index;not null" json:"userId"` - TokenHash string `gorm:"size:128;uniqueIndex;not null" json:"-"` - UserAgent string `gorm:"size:255" json:"userAgent"` - IP string `gorm:"size:64" json:"ip"` - ExpiresAt time.Time `gorm:"index;not null" json:"expiresAt"` - RevokedAt *time.Time `json:"revokedAt"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + UserID uint `gorm:"index;not null" json:"userId"` + TokenHash string `gorm:"size:128;uniqueIndex;not null" json:"-"` + UserAgent string `gorm:"size:255" json:"userAgent"` + IP string `gorm:"size:64" json:"ip"` + ExpiresAtMS int64 `gorm:"column:expires_at_ms;index;not null" json:"expiresAtMs"` + RevokedAtMS *int64 `gorm:"column:revoked_at_ms" json:"revokedAtMs"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (RefreshToken) TableName() string { @@ -130,14 +128,14 @@ func (RefreshToken) TableName() string { } type LoginLog struct { - ID uint `gorm:"primaryKey" json:"id"` - Username string `gorm:"size:64;index" json:"username"` - UserID *uint `gorm:"index" json:"userId"` - IP string `gorm:"size:64" json:"ip"` - UserAgent string `gorm:"size:255" json:"userAgent"` - Status string `gorm:"size:32;index;not null" json:"status"` - Message string `gorm:"size:255" json:"message"` - CreatedAt time.Time `json:"createdAt"` + ID uint `gorm:"primaryKey" json:"id"` + Username string `gorm:"size:64;index" json:"username"` + UserID *uint `gorm:"index" json:"userId"` + IP string `gorm:"size:64" json:"ip"` + UserAgent string `gorm:"size:255" json:"userAgent"` + Status string `gorm:"size:32;index;not null" json:"status"` + Message string `gorm:"size:255" json:"message"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` } func (LoginLog) TableName() string { @@ -145,23 +143,23 @@ func (LoginLog) TableName() string { } type OperationLog struct { - ID uint `gorm:"primaryKey" json:"id"` - RequestID string `gorm:"size:64;index;not null;default:''" json:"requestId"` - UserID uint `gorm:"index;not null" json:"userId"` - Username string `gorm:"size:64;index;not null" json:"username"` - Action string `gorm:"size:80;index;not null" json:"action"` - Resource string `gorm:"size:120;index" json:"resource"` - ResourceID string `gorm:"size:80;index;not null;default:''" json:"resourceId"` - Method string `gorm:"size:12" json:"method"` - Path string `gorm:"size:180" json:"path"` - IP string `gorm:"size:64" json:"ip"` - UserAgent string `gorm:"size:255;not null;default:''" json:"userAgent"` - Status string `gorm:"size:32;index;not null" json:"status"` - HTTPStatus int `gorm:"not null;default:0" json:"httpStatus"` - RiskLevel string `gorm:"size:24;index;not null;default:normal" json:"riskLevel"` - LatencyMS int64 `gorm:"not null;default:0" json:"latencyMs"` - Detail string `gorm:"type:text" json:"detail"` - CreatedAt time.Time `json:"createdAt"` + ID uint `gorm:"primaryKey" json:"id"` + RequestID string `gorm:"size:64;index;not null;default:''" json:"requestId"` + UserID uint `gorm:"index;not null" json:"userId"` + Username string `gorm:"size:64;index;not null" json:"username"` + Action string `gorm:"size:80;index;not null" json:"action"` + Resource string `gorm:"size:120;index" json:"resource"` + ResourceID string `gorm:"size:80;index;not null;default:''" json:"resourceId"` + Method string `gorm:"size:12" json:"method"` + Path string `gorm:"size:180" json:"path"` + IP string `gorm:"size:64" json:"ip"` + UserAgent string `gorm:"size:255;not null;default:''" json:"userAgent"` + Status string `gorm:"size:32;index;not null" json:"status"` + HTTPStatus int `gorm:"not null;default:0" json:"httpStatus"` + RiskLevel string `gorm:"size:24;index;not null;default:normal" json:"riskLevel"` + LatencyMS int64 `gorm:"not null;default:0" json:"latencyMs"` + Detail string `gorm:"type:text" json:"detail"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` } func (OperationLog) TableName() string { @@ -169,13 +167,13 @@ func (OperationLog) TableName() string { } type Notification struct { - ID uint `gorm:"primaryKey" json:"id"` - Title string `gorm:"size:120;not null" json:"title"` - Content string `gorm:"size:500" json:"content"` - Level string `gorm:"size:24;index;not null;default:info" json:"level"` - ReadAt *time.Time `json:"readAt"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + Title string `gorm:"size:120;not null" json:"title"` + Content string `gorm:"size:500" json:"content"` + Level string `gorm:"size:24;index;not null;default:info" json:"level"` + ReadAtMS *int64 `gorm:"column:read_at_ms" json:"readAtMs"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (Notification) TableName() string { @@ -183,12 +181,12 @@ func (Notification) TableName() string { } type DataScope struct { - ID uint `gorm:"primaryKey" json:"id"` - RoleID uint `gorm:"index;not null" json:"roleId"` - ScopeType string `gorm:"size:40;index;not null" json:"scopeType"` - ScopeValue string `gorm:"size:120;index;not null" json:"scopeValue"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + RoleID uint `gorm:"index;not null" json:"roleId"` + ScopeType string `gorm:"size:40;index;not null" json:"scopeType"` + ScopeValue string `gorm:"size:120;index;not null" json:"scopeValue"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (DataScope) TableName() string { @@ -196,23 +194,23 @@ func (DataScope) TableName() string { } type AdminJob struct { - ID uint `gorm:"primaryKey" json:"id"` - Type string `gorm:"size:80;index;not null" json:"type"` - Status string `gorm:"size:32;index;not null" json:"status"` - PayloadJSON string `gorm:"type:text" json:"payload"` - ResultJSON string `gorm:"type:text" json:"result"` - Error string `gorm:"type:text" json:"error"` - Attempt int `gorm:"not null;default:0" json:"attempt"` - MaxAttempts int `gorm:"not null;default:3" json:"maxAttempts"` - LockedBy string `gorm:"size:120;index;not null;default:''" json:"lockedBy"` - LockedUntil *time.Time `gorm:"index" json:"lockedUntil"` - ArtifactPath string `gorm:"size:255;not null;default:''" json:"artifactPath"` - CreatedBy uint `gorm:"index;not null" json:"createdBy"` - CreatedByName string `gorm:"size:64;index;not null" json:"createdByName"` - StartedAt *time.Time `json:"startedAt"` - FinishedAt *time.Time `json:"finishedAt"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID uint `gorm:"primaryKey" json:"id"` + Type string `gorm:"size:80;index;not null" json:"type"` + Status string `gorm:"size:32;index;not null" json:"status"` + PayloadJSON string `gorm:"type:text" json:"payload"` + ResultJSON string `gorm:"type:text" json:"result"` + Error string `gorm:"type:text" json:"error"` + Attempt int `gorm:"not null;default:0" json:"attempt"` + MaxAttempts int `gorm:"not null;default:3" json:"maxAttempts"` + LockedBy string `gorm:"size:120;index;not null;default:''" json:"lockedBy"` + LockedUntilMS *int64 `gorm:"column:locked_until_ms;index" json:"lockedUntilMs"` + ArtifactPath string `gorm:"size:255;not null;default:''" json:"artifactPath"` + CreatedBy uint `gorm:"index;not null" json:"createdBy"` + CreatedByName string `gorm:"size:64;index;not null" json:"createdByName"` + StartedAtMS *int64 `gorm:"column:started_at_ms" json:"startedAtMs"` + FinishedAtMS *int64 `gorm:"column:finished_at_ms" json:"finishedAtMs"` + CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` + UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (AdminJob) TableName() string { diff --git a/server/admin/internal/modules/adminuser/service.go b/server/admin/internal/modules/adminuser/service.go index 19fdcd64..25008d60 100644 --- a/server/admin/internal/modules/adminuser/service.go +++ b/server/admin/internal/modules/adminuser/service.go @@ -5,6 +5,7 @@ import ( "encoding/csv" "fmt" "strings" + "time" "hyapp-admin-server/internal/config" "hyapp-admin-server/internal/model" @@ -152,8 +153,8 @@ func (s *AdminUserService) ExportUsers(actor shared.Actor, options repository.Li _ = writer.Write([]string{"ID", "账号", "姓名", "角色", "团队", "状态", "MFA", "最后登录"}) for _, user := range users { lastLogin := "" - if user.LastLoginAt != nil { - lastLogin = user.LastLoginAt.Format("2006-01-02 15:04:05") + if user.LastLoginAtMS != nil { + lastLogin = time.UnixMilli(*user.LastLoginAtMS).UTC().Format("2006-01-02 15:04:05") } _ = writer.Write([]string{ fmt.Sprintf("%d", user.ID), diff --git a/server/admin/internal/modules/appconfig/service.go b/server/admin/internal/modules/appconfig/service.go index c3cd3d32..3ead6ce5 100644 --- a/server/admin/internal/modules/appconfig/service.go +++ b/server/admin/internal/modules/appconfig/service.go @@ -77,7 +77,7 @@ func (s *AppConfigService) ListH5Links() ([]H5Link, error) { } if config, ok := configByKey[definition.Key]; ok { item.URL = config.Value - item.UpdatedAtMs = config.UpdatedAt.UnixMilli() + item.UpdatedAtMs = config.UpdatedAtMS } items = append(items, item) } @@ -260,8 +260,8 @@ func appBannerFromModel(item model.AppBanner) AppBanner { RegionID: item.RegionID, CountryCode: item.CountryCode, Description: item.Description, - CreatedAtMs: item.CreatedAt.UnixMilli(), - UpdatedAtMs: item.UpdatedAt.UnixMilli(), + CreatedAtMs: item.CreatedAtMS, + UpdatedAtMs: item.UpdatedAtMS, } } diff --git a/server/admin/internal/modules/appuser/handler.go b/server/admin/internal/modules/appuser/handler.go index 0b23db0b..b4f9dac9 100644 --- a/server/admin/internal/modules/appuser/handler.go +++ b/server/admin/internal/modules/appuser/handler.go @@ -8,7 +8,9 @@ import ( "strings" "hyapp-admin-server/internal/config" + "hyapp-admin-server/internal/integration/activityclient" "hyapp-admin-server/internal/integration/userclient" + "hyapp-admin-server/internal/middleware" "hyapp-admin-server/internal/modules/shared" "hyapp-admin-server/internal/response" @@ -21,9 +23,9 @@ type Handler struct { audit shared.OperationLogger } -func New(userClient userclient.Client, userDB *sql.DB, walletDB *sql.DB, cfg config.Config, audit shared.OperationLogger) *Handler { +func New(userClient userclient.Client, activityClient activityclient.Client, userDB *sql.DB, walletDB *sql.DB, cfg config.Config, audit shared.OperationLogger) *Handler { return &Handler{ - service: NewService(userClient, userDB, walletDB), + service: NewService(userClient, activityClient, userDB, walletDB), cfg: cfg, audit: audit, } @@ -87,7 +89,7 @@ func (h *Handler) UpdateUser(c *gin.Context) { response.BadRequest(c, "用户参数不正确") return } - user, err := h.service.UpdateUser(c.Request.Context(), userID, req) + user, err := h.service.UpdateUser(c.Request.Context(), userID, middleware.CurrentRequestID(c), req) if err != nil { writeMutationError(c, err, "更新 App 用户失败") return diff --git a/server/admin/internal/modules/appuser/service.go b/server/admin/internal/modules/appuser/service.go index e5bb0da9..90006f7c 100644 --- a/server/admin/internal/modules/appuser/service.go +++ b/server/admin/internal/modules/appuser/service.go @@ -5,13 +5,16 @@ import ( "database/sql" "errors" "fmt" + "log/slog" "strconv" "strings" "time" "hyapp-admin-server/internal/appctx" + "hyapp-admin-server/internal/integration/activityclient" "hyapp-admin-server/internal/integration/userclient" "hyapp-admin-server/internal/security" + activityv1 "hyapp.local/api/proto/activity/v1" ) var ( @@ -20,9 +23,10 @@ var ( ) type Service struct { - userClient userclient.Client - userDB *sql.DB - walletDB *sql.DB + userClient userclient.Client + activityClient activityclient.Client + userDB *sql.DB + walletDB *sql.DB } type AppUser struct { @@ -44,8 +48,8 @@ type AppUser struct { Username string `json:"username"` } -func NewService(userClient userclient.Client, userDB *sql.DB, walletDB *sql.DB) *Service { - return &Service{userClient: userClient, userDB: userDB, walletDB: walletDB} +func NewService(userClient userclient.Client, activityClient activityclient.Client, userDB *sql.DB, walletDB *sql.DB) *Service { + return &Service{userClient: userClient, activityClient: activityClient, userDB: userDB, walletDB: walletDB} } func (s *Service) ListUsers(ctx context.Context, query listQuery) ([]AppUser, int64, error) { @@ -232,7 +236,7 @@ func (s *Service) GetUser(ctx context.Context, userID int64) (AppUser, error) { return items[0], nil } -func (s *Service) UpdateUser(ctx context.Context, userID int64, req updateUserRequest) (AppUser, error) { +func (s *Service) UpdateUser(ctx context.Context, userID int64, requestID string, req updateUserRequest) (AppUser, error) { if s.userDB == nil { return AppUser{}, fmt.Errorf("user mysql is not configured") } @@ -262,7 +266,13 @@ func (s *Service) UpdateUser(ctx context.Context, userID int64, req updateUserRe sets = append(sets, "gender = ?") args = append(args, nullableString(value)) } + oldRegionID := int64(0) if req.Country != nil { + before, err := s.GetUser(ctx, userID) + if err != nil { + return AppUser{}, err + } + oldRegionID = before.RegionID country, regionID, err := s.resolveCountryRegion(ctx, *req.Country) if err != nil { return AppUser{}, err @@ -289,7 +299,41 @@ func (s *Service) UpdateUser(ctx context.Context, userID int64, req updateUserRe if affected == 0 { return AppUser{}, ErrNotFound } - return s.GetUser(ctx, userID) + updated, err := s.GetUser(ctx, userID) + if err != nil { + return AppUser{}, err + } + if req.Country != nil { + s.removeOldRegionBroadcastMemberBestEffort(ctx, userID, oldRegionID, updated.RegionID, strings.TrimSpace(requestID), "admin_user_country_changed") + } + return updated, nil +} + +func (s *Service) removeOldRegionBroadcastMemberBestEffort(ctx context.Context, userID int64, oldRegionID int64, newRegionID int64, requestID string, reason string) { + if s == nil || s.activityClient == nil || userID <= 0 || oldRegionID <= 0 || oldRegionID == newRegionID { + return + } + _, err := s.activityClient.RemoveRegionBroadcastMember(ctx, &activityv1.RemoveRegionBroadcastMemberRequest{ + Meta: &activityv1.RequestMeta{ + RequestId: strings.TrimSpace(requestID), + Caller: "hyapp-admin-server", + SentAtMs: nowMillis(), + AppCode: appctx.FromContext(ctx), + }, + UserId: userID, + RegionId: oldRegionID, + Reason: reason, + }) + if err != nil { + // 后台国家更新已经写入 users;IM 成员移除是外部副作用,失败不回滚资料,callback 会阻止用户再次加入旧区域群。 + slog.WarnContext(ctx, "admin_im_region_group_member_remove_failed", + slog.Int64("user_id", userID), + slog.Int64("old_region_id", oldRegionID), + slog.Int64("new_region_id", newRegionID), + slog.String("request_id", requestID), + slog.String("error", err.Error()), + ) + } } func (s *Service) SetUserStatus(ctx context.Context, userID int64, status string) (AppUser, error) { diff --git a/server/admin/internal/modules/audit/service.go b/server/admin/internal/modules/audit/service.go index 097457ee..eadb5e46 100644 --- a/server/admin/internal/modules/audit/service.go +++ b/server/admin/internal/modules/audit/service.go @@ -78,7 +78,7 @@ func (s *AuditService) ExportLoginLogs(options repository.ListOptions) (CSVExpor item.IP, item.Status, item.Message, - item.CreatedAt.Format(time.RFC3339), + time.UnixMilli(item.CreatedAtMS).UTC().Format(time.RFC3339), }) } writer.Flush() @@ -109,7 +109,7 @@ func (s *AuditService) ExportOperationLogs(options repository.ListOptions) (CSVE item.RiskLevel, fmt.Sprintf("%d", item.LatencyMS), item.Detail, - item.CreatedAt.Format(time.RFC3339), + time.UnixMilli(item.CreatedAtMS).UTC().Format(time.RFC3339), }) } writer.Flush() diff --git a/server/admin/internal/modules/auth/handler.go b/server/admin/internal/modules/auth/handler.go index f1ca4195..92721afa 100644 --- a/server/admin/internal/modules/auth/handler.go +++ b/server/admin/internal/modules/auth/handler.go @@ -44,7 +44,7 @@ func (h *Handler) Login(c *gin.Context) { h.setRefreshCookie(c, result.RefreshToken, int(h.cfg.RefreshTokenTTL.Seconds())) response.OK(c, gin.H{ "accessToken": result.AccessToken, - "expiresAt": result.ExpiresAt, + "expiresAtMs": result.ExpiresAtMS, "user": shared.UserDTO(result.User), "permissions": result.Permissions, }) @@ -73,7 +73,7 @@ func (h *Handler) Refresh(c *gin.Context) { response.OK(c, gin.H{ "accessToken": result.AccessToken, - "expiresAt": result.ExpiresAt, + "expiresAtMs": result.ExpiresAtMS, "user": shared.UserDTO(result.User), "permissions": result.Permissions, }) diff --git a/server/admin/internal/modules/auth/service.go b/server/admin/internal/modules/auth/service.go index c06ff053..d6ed78c5 100644 --- a/server/admin/internal/modules/auth/service.go +++ b/server/admin/internal/modules/auth/service.go @@ -29,7 +29,7 @@ type LoginInput struct { type LoginResult struct { AccessToken string RefreshToken string - ExpiresAt time.Time + ExpiresAtMS int64 User model.User Permissions []string } @@ -59,17 +59,17 @@ func (s *AuthFlowService) Login(input LoginInput) (LoginResult, error) { return LoginResult{}, err } if err := s.store.CreateRefreshToken(model.RefreshToken{ - UserID: user.ID, - TokenHash: refreshHash, - UserAgent: input.UserAgent, - IP: input.IP, - ExpiresAt: time.Now().Add(s.cfg.RefreshTokenTTL), + UserID: user.ID, + TokenHash: refreshHash, + UserAgent: input.UserAgent, + IP: input.IP, + ExpiresAtMS: time.Now().UTC().Add(s.cfg.RefreshTokenTTL).UnixMilli(), }); err != nil { return LoginResult{}, err } _ = s.store.TouchUserLogin(user.ID) s.loginLog(input, &user.ID, "success", "登录成功") - return LoginResult{AccessToken: accessToken, RefreshToken: refreshToken, ExpiresAt: expiresAt, User: *user, Permissions: permissions}, nil + return LoginResult{AccessToken: accessToken, RefreshToken: refreshToken, ExpiresAtMS: expiresAt.UnixMilli(), User: *user, Permissions: permissions}, nil } func (s *AuthFlowService) Logout(refreshToken string) error { @@ -96,7 +96,7 @@ func (s *AuthFlowService) Refresh(refreshToken string) (LoginResult, error) { if err != nil { return LoginResult{}, err } - return LoginResult{AccessToken: accessToken, ExpiresAt: expiresAt, User: *user, Permissions: permissions}, nil + return LoginResult{AccessToken: accessToken, ExpiresAtMS: expiresAt.UnixMilli(), User: *user, Permissions: permissions}, nil } func (s *AuthFlowService) Me(actor shared.Actor) (*model.User, []string, error) { diff --git a/server/admin/internal/modules/notification/response.go b/server/admin/internal/modules/notification/response.go index a48e5f51..b261526e 100644 --- a/server/admin/internal/modules/notification/response.go +++ b/server/admin/internal/modules/notification/response.go @@ -5,7 +5,7 @@ import "hyapp-admin-server/internal/model" func unreadCount(items []model.Notification) int { count := 0 for _, item := range items { - if item.ReadAt == nil { + if item.ReadAtMS == nil { count++ } } diff --git a/server/admin/internal/modules/shared/dto.go b/server/admin/internal/modules/shared/dto.go index d26b8b41..49b4d160 100644 --- a/server/admin/internal/modules/shared/dto.go +++ b/server/admin/internal/modules/shared/dto.go @@ -2,6 +2,7 @@ package shared import ( "strings" + "time" "hyapp-admin-server/internal/model" ) @@ -27,8 +28,8 @@ func UserDTO(user model.User) map[string]interface{} { } lastLogin := "-" - if user.LastLoginAt != nil { - lastLogin = user.LastLoginAt.Format("01-02 15:04") + if user.LastLoginAtMS != nil { + lastLogin = time.UnixMilli(*user.LastLoginAtMS).UTC().Format("01-02 15:04") } return map[string]interface{}{ @@ -41,6 +42,7 @@ func UserDTO(user model.User) map[string]interface{} { "mfa": BoolText(user.MFAEnabled), "mfaEnabled": user.MFAEnabled, "lastLogin": lastLogin, + "lastLoginMs": user.LastLoginAtMS, "roles": user.Roles, "role": role, "roleIds": roleIDs, diff --git a/server/admin/internal/repository/admin_ops.go b/server/admin/internal/repository/admin_ops.go index 0939baaa..124f0398 100644 --- a/server/admin/internal/repository/admin_ops.go +++ b/server/admin/internal/repository/admin_ops.go @@ -128,7 +128,7 @@ func (s *Store) ListJobs(options ListOptions) ([]model.AdminJob, int64, error) { } var jobs []model.AdminJob - err := query.Order("created_at DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&jobs).Error + err := query.Order("created_at_ms DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&jobs).Error return jobs, total, err } @@ -143,13 +143,13 @@ func (s *Store) LeaseNextJob(workerID string, lease time.Duration, maxAttempts i maxAttempts = 3 } - now := time.Now() + nowMS := time.Now().UTC().UnixMilli() var leased model.AdminJob err := s.db.Transaction(func(tx *gorm.DB) error { var job model.AdminJob err := tx.Clauses(clause.Locking{Strength: "UPDATE"}). - Where("(status = ? OR (status = ? AND locked_until IS NOT NULL AND locked_until < ?)) AND attempt < max_attempts", model.JobStatusPending, model.JobStatusRunning, now). - Order("created_at ASC, id ASC"). + Where("(status = ? OR (status = ? AND locked_until_ms IS NOT NULL AND locked_until_ms < ?)) AND attempt < max_attempts", model.JobStatusPending, model.JobStatusRunning, nowMS). + Order("created_at_ms ASC, id ASC"). First(&job).Error if err != nil { return err @@ -158,13 +158,13 @@ func (s *Store) LeaseNextJob(workerID string, lease time.Duration, maxAttempts i job.MaxAttempts = maxAttempts } updates := map[string]interface{}{ - "status": model.JobStatusRunning, - "attempt": job.Attempt + 1, - "max_attempts": job.MaxAttempts, - "locked_by": workerID, - "locked_until": now.Add(lease), - "started_at": firstTime(job.StartedAt, now), - "error": "", + "status": model.JobStatusRunning, + "attempt": job.Attempt + 1, + "max_attempts": job.MaxAttempts, + "locked_by": workerID, + "locked_until_ms": nowMS + lease.Milliseconds(), + "started_at_ms": firstMS(job.StartedAtMS, nowMS), + "error": "", } if err := tx.Model(&model.AdminJob{}).Where("id = ?", job.ID).Updates(updates).Error; err != nil { return err @@ -184,14 +184,14 @@ func (s *Store) LeaseNextJob(workerID string, lease time.Duration, maxAttempts i } func (s *Store) CompleteJobWithArtifact(id uint, resultJSON string, artifactPath string) error { - now := time.Now() + nowMS := time.Now().UTC().UnixMilli() return s.db.Model(&model.AdminJob{}).Where("id = ?", id).Updates(map[string]interface{}{ - "status": model.JobStatusSucceeded, - "result_json": resultJSON, - "artifact_path": artifactPath, - "locked_by": "", - "locked_until": nil, - "finished_at": &now, + "status": model.JobStatusSucceeded, + "result_json": resultJSON, + "artifact_path": artifactPath, + "locked_by": "", + "locked_until_ms": nil, + "finished_at_ms": &nowMS, }).Error } @@ -200,19 +200,19 @@ func (s *Store) FailJobAttempt(id uint, message string) error { if err := s.db.First(&job, id).Error; err != nil { return err } - now := time.Now() + nowMS := time.Now().UTC().UnixMilli() status := model.JobStatusPending finishedAt := interface{}(nil) if job.Attempt >= job.MaxAttempts { status = model.JobStatusFailed - finishedAt = &now + finishedAt = &nowMS } return s.db.Model(&model.AdminJob{}).Where("id = ?", id).Updates(map[string]interface{}{ - "status": status, - "error": message, - "locked_by": "", - "locked_until": nil, - "finished_at": finishedAt, + "status": status, + "error": message, + "locked_by": "", + "locked_until_ms": nil, + "finished_at_ms": finishedAt, }).Error } @@ -220,21 +220,21 @@ func (s *Store) ReleaseJobLease(id uint) error { return s.db.Model(&model.AdminJob{}). Where("id = ? AND status = ?", id, model.JobStatusRunning). Updates(map[string]interface{}{ - "status": model.JobStatusPending, - "locked_by": "", - "locked_until": nil, + "status": model.JobStatusPending, + "locked_by": "", + "locked_until_ms": nil, }).Error } func (s *Store) CancelJob(id uint) error { - now := time.Now() + nowMS := time.Now().UTC().UnixMilli() result := s.db.Model(&model.AdminJob{}). Where("id = ? AND status IN ?", id, []string{model.JobStatusPending, model.JobStatusRunning}). Updates(map[string]interface{}{ - "status": model.JobStatusCanceled, - "locked_by": "", - "locked_until": nil, - "finished_at": &now, + "status": model.JobStatusCanceled, + "locked_by": "", + "locked_until_ms": nil, + "finished_at_ms": &nowMS, }) if result.Error != nil { return result.Error @@ -253,7 +253,7 @@ func (s *Store) FindJobByID(id uint) (*model.AdminJob, error) { return &job, nil } -func firstTime(value *time.Time, fallback time.Time) *time.Time { +func firstMS(value *int64, fallback int64) *int64 { if value != nil { return value } diff --git a/server/admin/internal/repository/app_config_repository.go b/server/admin/internal/repository/app_config_repository.go index c6b89132..1408aec9 100644 --- a/server/admin/internal/repository/app_config_repository.go +++ b/server/admin/internal/repository/app_config_repository.go @@ -20,13 +20,13 @@ func (s *Store) UpsertAppConfigs(items []model.AppConfig) error { return nil } - now := time.Now() + nowMS := time.Now().UTC().UnixMilli() for index := range items { items[index].Group = strings.TrimSpace(items[index].Group) items[index].Key = strings.TrimSpace(items[index].Key) - items[index].UpdatedAt = now - if items[index].CreatedAt.IsZero() { - items[index].CreatedAt = now + items[index].UpdatedAtMS = nowMS + if items[index].CreatedAtMS == 0 { + items[index].CreatedAtMS = nowMS } } @@ -35,6 +35,6 @@ func (s *Store) UpsertAppConfigs(items []model.AppConfig) error { {Name: "group"}, {Name: "key"}, }, - DoUpdates: clause.AssignmentColumns([]string{"value", "description", "updated_at"}), + DoUpdates: clause.AssignmentColumns([]string{"value", "description", "updated_at_ms"}), }).Create(&items).Error } diff --git a/server/admin/internal/repository/audit_repository.go b/server/admin/internal/repository/audit_repository.go index c88150f2..16aaf53d 100644 --- a/server/admin/internal/repository/audit_repository.go +++ b/server/admin/internal/repository/audit_repository.go @@ -27,7 +27,7 @@ func (s *Store) ListLoginLogs(options ListOptions) ([]model.LoginLog, int64, err } var logs []model.LoginLog - err := query.Order("created_at DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&logs).Error + err := query.Order("created_at_ms DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&logs).Error return logs, total, err } @@ -39,7 +39,7 @@ func (s *Store) ExportLoginLogs(options ListOptions) ([]model.LoginLog, error) { } var logs []model.LoginLog - err := query.Order("created_at DESC").Find(&logs).Error + err := query.Order("created_at_ms DESC").Find(&logs).Error return logs, err } @@ -57,7 +57,7 @@ func (s *Store) ListOperationLogs(options ListOptions) ([]model.OperationLog, in } var logs []model.OperationLog - err := query.Order("created_at DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&logs).Error + err := query.Order("created_at_ms DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&logs).Error return logs, total, err } @@ -69,6 +69,6 @@ func (s *Store) ExportOperationLogs(options ListOptions) ([]model.OperationLog, } var logs []model.OperationLog - err := query.Order("created_at DESC").Find(&logs).Error + err := query.Order("created_at_ms DESC").Find(&logs).Error return logs, err } diff --git a/server/admin/internal/repository/auth_repository.go b/server/admin/internal/repository/auth_repository.go index b8b7aee9..9f51a0db 100644 --- a/server/admin/internal/repository/auth_repository.go +++ b/server/admin/internal/repository/auth_repository.go @@ -42,10 +42,10 @@ func PermissionsForUser(user model.User) []string { } func (s *Store) TouchUserLogin(id uint) error { - now := time.Now() + nowMS := time.Now().UTC().UnixMilli() return s.db.Model(&model.User{}).Where("id = ?", id).Updates(map[string]interface{}{ - "last_login_at": &now, - "updated_at": now, + "last_login_at_ms": &nowMS, + "updated_at_ms": nowMS, }).Error } @@ -55,7 +55,7 @@ func (s *Store) CreateRefreshToken(token model.RefreshToken) error { func (s *Store) FindRefreshToken(hash string) (*model.RefreshToken, error) { var token model.RefreshToken - err := s.db.Where("token_hash = ? AND revoked_at IS NULL AND expires_at > ?", hash, time.Now()).First(&token).Error + err := s.db.Where("token_hash = ? AND revoked_at_ms IS NULL AND expires_at_ms > ?", hash, time.Now().UTC().UnixMilli()).First(&token).Error if err != nil { return nil, err } @@ -64,6 +64,6 @@ func (s *Store) FindRefreshToken(hash string) (*model.RefreshToken, error) { } func (s *Store) RevokeRefreshToken(hash string) error { - now := time.Now() - return s.db.Model(&model.RefreshToken{}).Where("token_hash = ? AND revoked_at IS NULL", hash).Update("revoked_at", &now).Error + nowMS := time.Now().UTC().UnixMilli() + return s.db.Model(&model.RefreshToken{}).Where("token_hash = ? AND revoked_at_ms IS NULL", hash).Update("revoked_at_ms", &nowMS).Error } diff --git a/server/admin/internal/repository/dashboard_repository.go b/server/admin/internal/repository/dashboard_repository.go index ad2834d2..1d24c6e1 100644 --- a/server/admin/internal/repository/dashboard_repository.go +++ b/server/admin/internal/repository/dashboard_repository.go @@ -27,17 +27,17 @@ func (s *Store) DashboardOverview() (*DashboardOverview, error) { if err := s.db.Model(&model.Menu{}).Where("visible = ?", true).Count(&menuTotal).Error; err != nil { return nil, err } - now := time.Now() - today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) - if err := s.db.Model(&model.OperationLog{}).Where("created_at >= ?", today).Count(&logsToday).Error; err != nil { + now := time.Now().UTC() + todayMS := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC).UnixMilli() + if err := s.db.Model(&model.OperationLog{}).Where("created_at_ms >= ?", todayMS).Count(&logsToday).Error; err != nil { return nil, err } - if err := s.db.Model(&model.Notification{}).Where("read_at IS NULL").Count(&unreadNotifications).Error; err != nil { + if err := s.db.Model(&model.Notification{}).Where("read_at_ms IS NULL").Count(&unreadNotifications).Error; err != nil { return nil, err } var notifications []model.Notification - if err := s.db.Where("read_at IS NULL").Order("created_at DESC").Limit(3).Find(¬ifications).Error; err != nil { + if err := s.db.Where("read_at_ms IS NULL").Order("created_at_ms DESC").Limit(3).Find(¬ifications).Error; err != nil { return nil, err } alerts := make([]map[string]string, 0, len(notifications)) @@ -46,7 +46,7 @@ func (s *Store) DashboardOverview() (*DashboardOverview, error) { "type": item.Level, "name": item.Title, "desc": item.Content, - "time": item.CreatedAt.Format("15:04"), + "time": time.UnixMilli(item.CreatedAtMS).UTC().Format("15:04"), }) } @@ -64,7 +64,7 @@ func (s *Store) DashboardOverview() (*DashboardOverview, error) { "operations": {int(logsToday)}, "notifications": {int(unreadNotifications)}, }, - Alerts: alerts, - UpdatedAt: now.Format("15:04:05"), + Alerts: alerts, + UpdatedAtMS: now.UnixMilli(), }, nil } diff --git a/server/admin/internal/repository/helpers.go b/server/admin/internal/repository/helpers.go index f7cc7e15..15707968 100644 --- a/server/admin/internal/repository/helpers.go +++ b/server/admin/internal/repository/helpers.go @@ -97,7 +97,7 @@ func userSort(sort string) string { case "username_desc": return "username DESC" case "last_login_desc": - return "last_login_at DESC" + return "last_login_at_ms DESC" default: return "id ASC" } diff --git a/server/admin/internal/repository/notification_repository.go b/server/admin/internal/repository/notification_repository.go index 144b9525..59f002b3 100644 --- a/server/admin/internal/repository/notification_repository.go +++ b/server/admin/internal/repository/notification_repository.go @@ -7,13 +7,13 @@ import ( func (s *Store) ListNotifications() ([]model.Notification, error) { var items []model.Notification - err := s.db.Order("created_at DESC").Find(&items).Error + err := s.db.Order("created_at_ms DESC").Find(&items).Error return items, err } func (s *Store) MarkNotificationRead(id uint) (*model.Notification, error) { - now := time.Now() - if err := s.db.Model(&model.Notification{}).Where("id = ?", id).Update("read_at", &now).Error; err != nil { + nowMS := time.Now().UTC().UnixMilli() + if err := s.db.Model(&model.Notification{}).Where("id = ?", id).Update("read_at_ms", &nowMS).Error; err != nil { return nil, err } var item model.Notification @@ -24,8 +24,8 @@ func (s *Store) MarkNotificationRead(id uint) (*model.Notification, error) { } func (s *Store) MarkAllNotificationsRead() (int64, error) { - now := time.Now() - result := s.db.Model(&model.Notification{}).Where("read_at IS NULL").Update("read_at", &now) + nowMS := time.Now().UTC().UnixMilli() + result := s.db.Model(&model.Notification{}).Where("read_at_ms IS NULL").Update("read_at_ms", &nowMS) return result.RowsAffected, result.Error } diff --git a/server/admin/internal/repository/repository.go b/server/admin/internal/repository/repository.go index 843ccf24..d1ad4fba 100644 --- a/server/admin/internal/repository/repository.go +++ b/server/admin/internal/repository/repository.go @@ -38,7 +38,7 @@ type DashboardOverview struct { UnreadNotifications int `json:"unreadNotifications"` Alerts []map[string]string `json:"alerts"` Series map[string][]int `json:"series"` - UpdatedAt string `json:"updatedAt"` + UpdatedAtMS int64 `json:"updatedAtMs"` } type MenuSortItem struct { diff --git a/server/admin/internal/service/auth.go b/server/admin/internal/service/auth.go index 716d9c2a..f4ebbd6c 100644 --- a/server/admin/internal/service/auth.go +++ b/server/admin/internal/service/auth.go @@ -34,14 +34,15 @@ func CheckPassword(hash string, password string) bool { } func (s *AuthService) GenerateAccessToken(userID uint, username string, permissions []string) (string, time.Time, error) { - expiresAt := time.Now().Add(s.ttl) + now := time.Now().UTC() + expiresAt := now.Add(s.ttl) claims := Claims{ UserID: userID, Username: username, Permissions: permissions, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(expiresAt), - IssuedAt: jwt.NewNumericDate(time.Now()), + IssuedAt: jwt.NewNumericDate(now), Subject: username, }, } diff --git a/server/admin/migrations/001_admin_core.sql b/server/admin/migrations/001_admin_core.sql index 2c199541..e34e673f 100644 --- a/server/admin/migrations/001_admin_core.sql +++ b/server/admin/migrations/001_admin_core.sql @@ -6,9 +6,9 @@ CREATE TABLE IF NOT EXISTS admin_users ( team VARCHAR(80), status VARCHAR(24) NOT NULL DEFAULT 'active', mfa_enabled BOOLEAN NOT NULL DEFAULT FALSE, - last_login_at DATETIME NULL, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + last_login_at_ms BIGINT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_users_status (status) ); @@ -17,8 +17,8 @@ CREATE TABLE IF NOT EXISTS admin_roles ( name VARCHAR(80) NOT NULL UNIQUE, code VARCHAR(80) NOT NULL UNIQUE, description VARCHAR(255), - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL ); CREATE TABLE IF NOT EXISTS admin_permissions ( @@ -27,8 +27,8 @@ CREATE TABLE IF NOT EXISTS admin_permissions ( code VARCHAR(100) NOT NULL UNIQUE, kind VARCHAR(32) NOT NULL, description VARCHAR(255), - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_permissions_kind (kind) ); @@ -54,8 +54,8 @@ CREATE TABLE IF NOT EXISTS admin_menus ( permission_code VARCHAR(100), sort INT NOT NULL DEFAULT 0, visible BOOLEAN NOT NULL DEFAULT TRUE, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_menus_parent_id (parent_id), INDEX idx_admin_menus_permission_code (permission_code) ); @@ -66,12 +66,12 @@ CREATE TABLE IF NOT EXISTS admin_refresh_tokens ( token_hash VARCHAR(128) NOT NULL UNIQUE, user_agent VARCHAR(255), ip VARCHAR(64), - expires_at DATETIME NOT NULL, - revoked_at DATETIME NULL, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + expires_at_ms BIGINT NOT NULL, + revoked_at_ms BIGINT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_refresh_tokens_user_id (user_id), - INDEX idx_admin_refresh_tokens_expires_at (expires_at) + INDEX idx_admin_refresh_tokens_expires_at (expires_at_ms) ); CREATE TABLE IF NOT EXISTS admin_login_logs ( @@ -82,7 +82,7 @@ CREATE TABLE IF NOT EXISTS admin_login_logs ( user_agent VARCHAR(255), status VARCHAR(32) NOT NULL, message VARCHAR(255), - created_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, INDEX idx_admin_login_logs_username (username), INDEX idx_admin_login_logs_status (status) ); @@ -98,7 +98,7 @@ CREATE TABLE IF NOT EXISTS admin_operation_logs ( ip VARCHAR(64), status VARCHAR(32) NOT NULL, detail TEXT, - created_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, INDEX idx_admin_operation_logs_user_id (user_id), INDEX idx_admin_operation_logs_action (action) ); @@ -108,9 +108,9 @@ CREATE TABLE IF NOT EXISTS admin_notifications ( title VARCHAR(120) NOT NULL, content VARCHAR(500), level VARCHAR(24) NOT NULL DEFAULT 'info', - read_at DATETIME NULL, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + read_at_ms BIGINT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_notifications_level (level) ); @@ -129,7 +129,7 @@ CREATE TABLE IF NOT EXISTS admin_service_assets ( memory INT NOT NULL DEFAULT 0, trend_json TEXT, logs_json TEXT, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_service_assets_status (status) ); diff --git a/server/admin/migrations/002_admin_operations.sql b/server/admin/migrations/002_admin_operations.sql index 3258cff3..84123ebd 100644 --- a/server/admin/migrations/002_admin_operations.sql +++ b/server/admin/migrations/002_admin_operations.sql @@ -3,8 +3,8 @@ CREATE TABLE IF NOT EXISTS admin_data_scopes ( role_id BIGINT UNSIGNED NOT NULL, scope_type VARCHAR(40) NOT NULL, scope_value VARCHAR(120) NOT NULL, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, UNIQUE KEY uk_admin_data_scopes_role_scope (role_id, scope_type, scope_value), INDEX idx_admin_data_scopes_role_id (role_id), INDEX idx_admin_data_scopes_scope (scope_type, scope_value) @@ -19,10 +19,10 @@ CREATE TABLE IF NOT EXISTS admin_jobs ( error TEXT, created_by BIGINT UNSIGNED NOT NULL, created_by_name VARCHAR(64) NOT NULL, - started_at DATETIME NULL, - finished_at DATETIME NULL, - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + started_at_ms BIGINT NULL, + finished_at_ms BIGINT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_jobs_type (type), INDEX idx_admin_jobs_status (status), INDEX idx_admin_jobs_created_by (created_by), diff --git a/server/admin/migrations/003_operability_hardening.sql b/server/admin/migrations/003_operability_hardening.sql index 7773f8cb..9d193e78 100644 --- a/server/admin/migrations/003_operability_hardening.sql +++ b/server/admin/migrations/003_operability_hardening.sql @@ -13,7 +13,7 @@ ALTER TABLE admin_jobs ADD COLUMN attempt INT NOT NULL DEFAULT 0 AFTER error, ADD COLUMN max_attempts INT NOT NULL DEFAULT 3 AFTER attempt, ADD COLUMN locked_by VARCHAR(120) NOT NULL DEFAULT '' AFTER max_attempts, - ADD COLUMN locked_until DATETIME(3) NULL AFTER locked_by, - ADD COLUMN artifact_path VARCHAR(255) NOT NULL DEFAULT '' AFTER locked_until, + ADD COLUMN locked_until_ms BIGINT NULL AFTER locked_by, + ADD COLUMN artifact_path VARCHAR(255) NOT NULL DEFAULT '' AFTER locked_until_ms, ADD INDEX idx_admin_jobs_locked_by (locked_by), - ADD INDEX idx_admin_jobs_locked_until (locked_until); + ADD INDEX idx_admin_jobs_locked_until (locked_until_ms); diff --git a/server/admin/migrations/006_admin_app_banners.sql b/server/admin/migrations/006_admin_app_banners.sql index b9fcdce1..8e8ef382 100644 --- a/server/admin/migrations/006_admin_app_banners.sql +++ b/server/admin/migrations/006_admin_app_banners.sql @@ -10,8 +10,8 @@ CREATE TABLE IF NOT EXISTS admin_app_banners ( region_id BIGINT NOT NULL DEFAULT 0, country_code VARCHAR(8) NOT NULL DEFAULT '', description VARCHAR(255) NOT NULL DEFAULT '', - created_at DATETIME NOT NULL, - updated_at DATETIME NOT NULL, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, INDEX idx_admin_app_banners_app_sort (app_code, status, sort_order, id), INDEX idx_admin_app_banners_scope (app_code, platform, region_id, country_code) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/services/activity-service/Dockerfile b/services/activity-service/Dockerfile index ef5b04d3..5fe337b8 100644 --- a/services/activity-service/Dockerfile +++ b/services/activity-service/Dockerfile @@ -13,6 +13,8 @@ RUN GOWORK=off CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/grpc-healt FROM alpine:3.20 +ENV TZ=UTC + WORKDIR /app RUN apk add --no-cache ca-certificates && adduser -D -g '' appuser diff --git a/services/activity-service/configs/config.docker.yaml b/services/activity-service/configs/config.docker.yaml index 03b18726..3f68ae60 100644 --- a/services/activity-service/configs/config.docker.yaml +++ b/services/activity-service/configs/config.docker.yaml @@ -8,11 +8,28 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13006" -mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=UTC" user_service_addr: "user-service:13005" wallet_service_addr: "wallet-service:13004" -task_timezone: "Asia/Shanghai" mysql_auto_migrate: false +tencent_im: + # Docker 本地默认关闭播报 REST,避免未配置密钥时启动后访问外部腾讯云。 + enabled: false + sdk_app_id: 0 + secret_key: "" + admin_identifier: "administrator" + admin_user_sig_ttl: "24h" + endpoint: "console.tim.qq.com" + group_type: "ChatRoom" + request_timeout: "5s" +broadcast: + enabled: false + super_gift_min_value: 100000 + worker_poll_interval: "1s" + worker_batch_size: 100 + worker_lock_ttl: "30s" + worker_max_retry: 8 + ensure_groups_on_startup: true consumer: room_outbox_poll_interval_ms: 1000 batch_size: 100 diff --git a/services/activity-service/configs/config.tencent.example.yaml b/services/activity-service/configs/config.tencent.example.yaml index 53373c62..8ff3c2a4 100644 --- a/services/activity-service/configs/config.tencent.example.yaml +++ b/services/activity-service/configs/config.tencent.example.yaml @@ -8,11 +8,28 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13006" -mysql_dsn: "${TENCENT_MYSQL_ACTIVITY_DSN}" +mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=UTC&tls=false" user_service_addr: "user-service.internal:13005" wallet_service_addr: "wallet-service.internal:13004" -task_timezone: "Asia/Shanghai" mysql_auto_migrate: false +tencent_im: + # 腾讯云 IM 应用配置;必须和 gateway 的 UserSig、room-service 房间群配置属于同一个 SDKAppID。 + enabled: true + sdk_app_id: 1400000000 + secret_key: "TENCENT_IM_SECRET_KEY" + admin_identifier: "TENCENT_IM_ADMIN_IDENTIFIER" + admin_user_sig_ttl: "24h" + endpoint: "adminapisgp.im.qcloud.com" + group_type: "ChatRoom" + request_timeout: "5s" +broadcast: + enabled: true + super_gift_min_value: 100000 + worker_poll_interval: "1s" + worker_batch_size: 100 + worker_lock_ttl: "30s" + worker_max_retry: 8 + ensure_groups_on_startup: true consumer: room_outbox_poll_interval_ms: 1000 batch_size: 100 diff --git a/services/activity-service/configs/config.yaml b/services/activity-service/configs/config.yaml index 20a9ff20..f6bda29a 100644 --- a/services/activity-service/configs/config.yaml +++ b/services/activity-service/configs/config.yaml @@ -8,11 +8,28 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13006" -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=UTC" user_service_addr: "127.0.0.1:13005" wallet_service_addr: "127.0.0.1:13004" -task_timezone: "Asia/Shanghai" mysql_auto_migrate: false +tencent_im: + # activity-service 只负责全局/区域播报群;本地默认关闭,配置完整后才发送腾讯云 IM REST。 + enabled: false + sdk_app_id: 0 + secret_key: "" + admin_identifier: "administrator" + admin_user_sig_ttl: "24h" + endpoint: "console.tim.qq.com" + group_type: "ChatRoom" + request_timeout: "5s" +broadcast: + enabled: false + super_gift_min_value: 100000 + worker_poll_interval: "1s" + worker_batch_size: 100 + worker_lock_ttl: "30s" + worker_max_retry: 8 + ensure_groups_on_startup: true consumer: room_outbox_poll_interval_ms: 1000 batch_size: 100 diff --git a/services/activity-service/deploy/mysql/initdb/001_activity_service.sql b/services/activity-service/deploy/mysql/initdb/001_activity_service.sql index 22ff8e00..43503496 100644 --- a/services/activity-service/deploy/mysql/initdb/001_activity_service.sql +++ b/services/activity-service/deploy/mysql/initdb/001_activity_service.sql @@ -42,6 +42,26 @@ CREATE TABLE IF NOT EXISTS activity_outbox ( KEY idx_activity_outbox_status_retry (app_code, status, next_retry_at_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS im_broadcast_outbox ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu', + event_id VARCHAR(128) NOT NULL, + scope VARCHAR(32) NOT NULL, + group_id VARCHAR(64) NOT NULL, + broadcast_type VARCHAR(64) NOT NULL, + payload_json JSON NOT NULL, + status VARCHAR(32) NOT NULL, + attempt_count INT NOT NULL DEFAULT 0, + next_retry_at_ms BIGINT NOT NULL DEFAULT 0, + last_error VARCHAR(512) NOT NULL DEFAULT '', + locked_by VARCHAR(128) NOT NULL DEFAULT '', + locked_until_ms BIGINT NOT NULL DEFAULT 0, + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, + PRIMARY KEY (app_code, event_id), + KEY idx_im_broadcast_outbox_pending (app_code, status, next_retry_at_ms, created_at_ms), + KEY idx_im_broadcast_outbox_lock (app_code, status, locked_until_ms, created_at_ms) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + CREATE TABLE IF NOT EXISTS task_definitions ( app_code VARCHAR(32) NOT NULL DEFAULT 'lalu', task_id VARCHAR(96) NOT NULL, diff --git a/services/activity-service/internal/app/app.go b/services/activity-service/internal/app/app.go index 82459750..2904e560 100644 --- a/services/activity-service/internal/app/app.go +++ b/services/activity-service/internal/app/app.go @@ -14,9 +14,11 @@ import ( walletv1 "hyapp.local/api/proto/wallet/v1" "hyapp/pkg/grpchealth" "hyapp/pkg/logx" + "hyapp/pkg/tencentim" "hyapp/services/activity-service/internal/client" "hyapp/services/activity-service/internal/config" activityservice "hyapp/services/activity-service/internal/service/activity" + broadcastservice "hyapp/services/activity-service/internal/service/broadcast" messageservice "hyapp/services/activity-service/internal/service/message" taskservice "hyapp/services/activity-service/internal/service/task" mysqlstorage "hyapp/services/activity-service/internal/storage/mysql" @@ -25,13 +27,18 @@ import ( // App 装配 activity-service gRPC 入口和底座依赖。 type App struct { - server *grpc.Server - listener net.Listener - health *grpchealth.ServingChecker - mysqlRepo *mysqlstorage.Repository - userConn *grpc.ClientConn - walletConn *grpc.ClientConn - closeOnce sync.Once + server *grpc.Server + listener net.Listener + health *grpchealth.ServingChecker + mysqlRepo *mysqlstorage.Repository + broadcast *broadcastservice.Service + broadcastWorkerEnabled bool + userConn *grpc.ClientConn + walletConn *grpc.ClientConn + workerCtx context.Context + workerStop context.CancelFunc + workerWG sync.WaitGroup + closeOnce sync.Once } // New 初始化 activity-service 应用。 @@ -67,29 +74,76 @@ func New(cfg config.Config) (*App, error) { server := grpc.NewServer(grpc.UnaryInterceptor(logx.UnaryServerInterceptor("activity-service"))) svc := activityservice.New(activityservice.Config{NodeID: cfg.NodeID}, repository) messageSvc := messageservice.New(messageservice.Config{NodeID: cfg.NodeID}, repository, messageservice.WithTargetSource(client.NewGRPCUserTargetSource(userConn))) - taskSvc := taskservice.New(taskservice.Config{TaskTimezone: cfg.TaskTimezone}, repository, walletv1.NewWalletServiceClient(walletConn)) + taskSvc := taskservice.New(repository, walletv1.NewWalletServiceClient(walletConn)) + var broadcastPublisher broadcastservice.Publisher + if cfg.TencentIM.Enabled { + tencentClient, err := tencentim.NewRESTClient(cfg.TencentIM.RESTConfig()) + if err != nil { + _ = walletConn.Close() + _ = userConn.Close() + _ = listener.Close() + _ = repository.Close() + return nil, err + } + broadcastPublisher = tencentClient + } + if cfg.Broadcast.Enabled && broadcastPublisher == nil { + _ = walletConn.Close() + _ = userConn.Close() + _ = listener.Close() + _ = repository.Close() + return nil, errors.New("broadcast worker requires tencent_im.enabled") + } + broadcastSvc := broadcastservice.New(broadcastservice.Config{ + NodeID: cfg.NodeID, + SuperGiftMinValue: cfg.Broadcast.SuperGiftMinValue, + WorkerBatchSize: cfg.Broadcast.WorkerBatchSize, + WorkerLockTTL: cfg.Broadcast.WorkerLockTTL, + WorkerMaxRetry: cfg.Broadcast.WorkerMaxRetry, + WorkerPollInterval: cfg.Broadcast.WorkerPollInterval, + EnsureGroupsOnStartup: cfg.Broadcast.EnsureGroupsOnStartup, + }, repository, broadcastPublisher, client.NewGRPCRegionSource(userConn)) activityv1.RegisterActivityServiceServer(server, grpcserver.NewServer(svc)) activityv1.RegisterMessageInboxServiceServer(server, grpcserver.NewMessageServer(messageSvc)) activityv1.RegisterActivityCronServiceServer(server, grpcserver.NewCronServer(messageSvc)) activityv1.RegisterTaskServiceServer(server, grpcserver.NewTaskServer(taskSvc)) activityv1.RegisterAdminTaskServiceServer(server, grpcserver.NewAdminTaskServer(taskSvc)) + broadcastServer := grpcserver.NewBroadcastServer(broadcastSvc) + activityv1.RegisterBroadcastServiceServer(server, broadcastServer) + activityv1.RegisterRoomEventConsumerServiceServer(server, broadcastServer) health := grpchealth.NewServingChecker("activity-service") healthgrpc.RegisterHealthServer(server, grpchealth.NewServer(health)) + workerCtx, workerStop := context.WithCancel(context.Background()) return &App{ - server: server, - listener: listener, - health: health, - mysqlRepo: repository, - userConn: userConn, - walletConn: walletConn, + server: server, + listener: listener, + health: health, + mysqlRepo: repository, + broadcast: broadcastSvc, + broadcastWorkerEnabled: cfg.Broadcast.Enabled, + userConn: userConn, + walletConn: walletConn, + workerCtx: workerCtx, + workerStop: workerStop, }, nil } // Run 启动 gRPC 服务。 func (a *App) Run() error { a.health.MarkServing() + if a.broadcastWorkerEnabled && a.broadcast != nil && a.workerCtx != nil { + a.workerWG.Add(1) + go func() { + defer a.workerWG.Done() + a.broadcast.RunWorker(a.workerCtx, broadcastservice.WorkerOptions{}) + }() + } err := a.server.Serve(a.listener) + if a.workerStop != nil { + a.workerStop() + } + a.workerWG.Wait() a.health.MarkStopped() if errors.Is(err, grpc.ErrServerStopped) { return nil @@ -102,6 +156,10 @@ func (a *App) Run() error { func (a *App) Close() { a.closeOnce.Do(func() { a.health.MarkDraining() + if a.workerStop != nil { + a.workerStop() + } + a.workerWG.Wait() a.server.GracefulStop() if a.userConn != nil { _ = a.userConn.Close() diff --git a/services/activity-service/internal/client/region_source.go b/services/activity-service/internal/client/region_source.go new file mode 100644 index 00000000..45c4d83f --- /dev/null +++ b/services/activity-service/internal/client/region_source.go @@ -0,0 +1,41 @@ +package client + +import ( + "context" + + "google.golang.org/grpc" + userv1 "hyapp.local/api/proto/user/v1" + "hyapp/pkg/appcode" +) + +// GRPCRegionSource reads active region IDs from user-service region master data. +type GRPCRegionSource struct { + client userv1.RegionAdminServiceClient +} + +// NewGRPCRegionSource creates a region source backed by user-service gRPC. +func NewGRPCRegionSource(conn *grpc.ClientConn) *GRPCRegionSource { + return &GRPCRegionSource{client: userv1.NewRegionAdminServiceClient(conn)} +} + +// ListActiveRegionIDs returns positive active region IDs; GLOBAL region 0 is not an IM region group. +func (s *GRPCRegionSource) ListActiveRegionIDs(ctx context.Context) ([]int64, error) { + resp, err := s.client.ListRegions(ctx, &userv1.ListRegionsRequest{ + Meta: &userv1.RequestMeta{ + RequestId: "broadcast-region-reconcile", + Caller: "activity-service", + AppCode: appcode.FromContext(ctx), + }, + Status: "active", + }) + if err != nil { + return nil, err + } + regionIDs := make([]int64, 0, len(resp.GetRegions())) + for _, region := range resp.GetRegions() { + if region.GetRegionId() > 0 { + regionIDs = append(regionIDs, region.GetRegionId()) + } + } + return regionIDs, nil +} diff --git a/services/activity-service/internal/config/config.go b/services/activity-service/internal/config/config.go index 205a6ff2..7ae623f0 100644 --- a/services/activity-service/internal/config/config.go +++ b/services/activity-service/internal/config/config.go @@ -1,10 +1,13 @@ package config import ( + "net/http" "strings" + "time" "hyapp/pkg/configx" "hyapp/pkg/logx" + "hyapp/pkg/tencentim" ) // Config 描述 activity-service 启动配置。 @@ -19,8 +22,10 @@ type Config struct { UserServiceAddr string `yaml:"user_service_addr"` // WalletServiceAddr 是任务奖励入账依赖;activity 只发命令,不直接写余额。 WalletServiceAddr string `yaml:"wallet_service_addr"` - // TaskTimezone 是 daily 任务统一周期时区,不能使用客户端手机时区。 - TaskTimezone string `yaml:"task_timezone"` + // TencentIM 是 activity-service 发送全局/区域播报群消息的 REST 配置。 + TencentIM TencentIMConfig `yaml:"tencent_im"` + // Broadcast 控制 IM 播报群 reconciler、outbox worker 和贵重礼物阈值。 + Broadcast BroadcastConfig `yaml:"broadcast"` // MySQLAutoMigrate 保留给显式本地迁移;线上 schema 由发布流程或 initdb 管理。 MySQLAutoMigrate bool `yaml:"mysql_auto_migrate"` Consumer ConsumerConfig `yaml:"consumer"` @@ -39,6 +44,46 @@ type MessageInboxConfig struct { UnreadCacheTTL string `yaml:"unread_cache_ttl"` } +// TencentIMConfig 描述 activity-service 调用腾讯云 IM REST API 的配置。 +type TencentIMConfig struct { + Enabled bool `yaml:"enabled"` + SDKAppID int64 `yaml:"sdk_app_id"` + SecretKey string `yaml:"secret_key"` + AdminIdentifier string `yaml:"admin_identifier"` + AdminUserSigTTL time.Duration `yaml:"admin_user_sig_ttl"` + Endpoint string `yaml:"endpoint"` + GroupType string `yaml:"group_type"` + RequestTimeout time.Duration `yaml:"request_timeout"` +} + +// RESTConfig converts YAML into the shared Tencent IM REST client config. +func (c TencentIMConfig) RESTConfig() tencentim.RESTConfig { + timeout := c.RequestTimeout + if timeout <= 0 { + timeout = 5 * time.Second + } + return tencentim.RESTConfig{ + SDKAppID: c.SDKAppID, + SecretKey: c.SecretKey, + AdminIdentifier: c.AdminIdentifier, + AdminUserSigTTL: c.AdminUserSigTTL, + Endpoint: c.Endpoint, + GroupType: c.GroupType, + HTTPClient: &http.Client{Timeout: timeout}, + } +} + +// BroadcastConfig stores activity-service broadcast worker policy. +type BroadcastConfig struct { + Enabled bool `yaml:"enabled"` + SuperGiftMinValue int64 `yaml:"super_gift_min_value"` + WorkerPollInterval time.Duration `yaml:"worker_poll_interval"` + WorkerBatchSize int `yaml:"worker_batch_size"` + WorkerLockTTL time.Duration `yaml:"worker_lock_ttl"` + WorkerMaxRetry int `yaml:"worker_max_retry"` + EnsureGroupsOnStartup bool `yaml:"ensure_groups_on_startup"` +} + // Default 返回本地默认配置。 func Default() Config { return Config{ @@ -46,11 +91,27 @@ func Default() Config { NodeID: "activity-local", Environment: "local", GRPCAddr: ":13006", - MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=Local", + MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_activity?parseTime=true&charset=utf8mb4&loc=UTC", UserServiceAddr: "127.0.0.1:13005", WalletServiceAddr: "127.0.0.1:13004", - TaskTimezone: "Asia/Shanghai", - MySQLAutoMigrate: false, + TencentIM: TencentIMConfig{ + Enabled: false, + AdminIdentifier: "administrator", + AdminUserSigTTL: 24 * time.Hour, + Endpoint: tencentim.DefaultEndpoint, + GroupType: tencentim.DefaultGroupType, + RequestTimeout: 5 * time.Second, + }, + Broadcast: BroadcastConfig{ + Enabled: false, + SuperGiftMinValue: 100000, + WorkerPollInterval: time.Second, + WorkerBatchSize: 100, + WorkerLockTTL: 30 * time.Second, + WorkerMaxRetry: 8, + EnsureGroupsOnStartup: true, + }, + MySQLAutoMigrate: false, Consumer: ConsumerConfig{ RoomOutboxPollIntervalMs: 1000, BatchSize: 100, @@ -82,9 +143,6 @@ func Load(path string) (Config, error) { if strings.TrimSpace(cfg.WalletServiceAddr) == "" { cfg.WalletServiceAddr = Default().WalletServiceAddr } - if strings.TrimSpace(cfg.TaskTimezone) == "" { - cfg.TaskTimezone = Default().TaskTimezone - } cfg.ServiceName = strings.TrimSpace(cfg.ServiceName) if cfg.ServiceName == "" { cfg.ServiceName = "activity-service" @@ -97,6 +155,39 @@ func Load(path string) (Config, error) { if cfg.Environment == "" { cfg.Environment = "local" } + cfg.TencentIM.AdminIdentifier = strings.TrimSpace(cfg.TencentIM.AdminIdentifier) + if cfg.TencentIM.AdminIdentifier == "" { + cfg.TencentIM.AdminIdentifier = "administrator" + } + cfg.TencentIM.Endpoint = strings.TrimSpace(cfg.TencentIM.Endpoint) + if cfg.TencentIM.Endpoint == "" { + cfg.TencentIM.Endpoint = tencentim.DefaultEndpoint + } + cfg.TencentIM.GroupType = strings.TrimSpace(cfg.TencentIM.GroupType) + if cfg.TencentIM.GroupType == "" { + cfg.TencentIM.GroupType = tencentim.DefaultGroupType + } + if cfg.TencentIM.AdminUserSigTTL <= 0 { + cfg.TencentIM.AdminUserSigTTL = 24 * time.Hour + } + if cfg.TencentIM.RequestTimeout <= 0 { + cfg.TencentIM.RequestTimeout = 5 * time.Second + } + if cfg.Broadcast.SuperGiftMinValue <= 0 { + cfg.Broadcast.SuperGiftMinValue = 100000 + } + if cfg.Broadcast.WorkerPollInterval <= 0 { + cfg.Broadcast.WorkerPollInterval = time.Second + } + if cfg.Broadcast.WorkerBatchSize <= 0 { + cfg.Broadcast.WorkerBatchSize = 100 + } + if cfg.Broadcast.WorkerLockTTL <= 0 { + cfg.Broadcast.WorkerLockTTL = 30 * time.Second + } + if cfg.Broadcast.WorkerMaxRetry <= 0 { + cfg.Broadcast.WorkerMaxRetry = 8 + } return cfg, nil } diff --git a/services/activity-service/internal/domain/broadcast/broadcast.go b/services/activity-service/internal/domain/broadcast/broadcast.go new file mode 100644 index 00000000..e271d516 --- /dev/null +++ b/services/activity-service/internal/domain/broadcast/broadcast.go @@ -0,0 +1,71 @@ +// Package broadcast 定义 activity-service 拥有的 IM 播报领域事实。 +// 这里的对象只描述“需要向哪个腾讯群投递什么消息”,不承载红包金额扣减或房间状态事实。 +package broadcast + +const ( + // ScopeGlobal 表示 App 内全局群;使用频率低,适合全服运营公告或极少数全服事件。 + ScopeGlobal = "global" + // ScopeRegion 表示用户所在区域群;贵重礼物、区域红包、区域运营通知默认走这个范围。 + ScopeRegion = "region" + + // TypeSuperGift 是贵重礼物播报,来源于 room-service 已提交的 RoomGiftSent 事实。 + TypeSuperGift = "super_gift" + // TypeRedPacket 是红包入口播报,资金事实必须由 wallet/red-packet 领域持久化。 + TypeRedPacket = "red_packet" + + // StatusPending 表示消息已持久化,尚未被 worker claim。 + StatusPending = "pending" + // StatusDelivering 表示某个 worker 已抢占该记录,锁过期后允许其他 worker 接管。 + StatusDelivering = "delivering" + // StatusRetryable 表示上次腾讯 REST 失败,但未超过最大重试次数。 + StatusRetryable = "retryable" + // StatusDelivered 表示腾讯 REST 已接受消息,不代表每个客户端都已展示。 + StatusDelivered = "delivered" + // StatusFailed 表示达到最大重试次数,需要人工或后台补偿介入。 + StatusFailed = "failed" + // StatusSkipped 表示消费了上游事件但不满足播报策略,例如礼物价值未达阈值。 + StatusSkipped = "skipped" +) + +// OutboxRecord 是一条持久化播报投递记录。 +// event_id 是幂等键,group_id 是最终腾讯群目标,payload_json 是客户端渲染和点击跳转所需的完整业务负载。 +type OutboxRecord struct { + AppCode string + EventID string + Scope string + GroupID string + BroadcastType string + PayloadJSON string + Status string + AttemptCount int + NextRetryAtMS int64 + LastError string + LockedBy string + LockedUntilMS int64 + CreatedAtMS int64 + UpdatedAtMS int64 +} + +// PublishResult 描述一次幂等入队结果;Created=false 表示重复 event_id 命中已有记录。 +type PublishResult struct { + EventID string + GroupID string + Status string + Created bool +} + +// ProcessResult 汇总一次 worker 批处理结果,用于 cron/日志/监控判断是否需要继续拉下一批。 +type ProcessResult struct { + ClaimedCount int + SuccessCount int + FailureCount int + HasMore bool +} + +// ConsumeRoomEventResult 描述 room outbox 事实是否生成播报;跳过也是一种可观测消费结果。 +type ConsumeRoomEventResult struct { + EventID string + Status string + BroadcastEventID string + BroadcastCreated bool +} diff --git a/services/activity-service/internal/service/broadcast/service.go b/services/activity-service/internal/service/broadcast/service.go new file mode 100644 index 00000000..cf3036ab --- /dev/null +++ b/services/activity-service/internal/service/broadcast/service.go @@ -0,0 +1,432 @@ +// Package broadcast 实现 activity-service 拥有的腾讯云 IM 播报能力。 +// 该包只处理群生命周期、播报入队、outbox 投递和 room 事件消费策略,不拥有房间状态和资金事实。 +package broadcast + +import ( + "context" + "encoding/json" + "fmt" + "strings" + "time" + + "google.golang.org/protobuf/proto" + roomeventsv1 "hyapp.local/api/proto/events/room/v1" + "hyapp/pkg/appcode" + "hyapp/pkg/imgroup" + "hyapp/pkg/tencentim" + "hyapp/pkg/xerr" + broadcastdomain "hyapp/services/activity-service/internal/domain/broadcast" +) + +const ( + defaultBroadcastBatchSize = 100 + defaultBroadcastLockTTL = 30 * time.Second + defaultBroadcastMaxRetry = 8 +) + +// Repository 是播报消息的持久化 outbox 边界。 +// service 只通过这个接口写入/抢占/标记记录,确保腾讯 REST 失败后仍可重试和人工补偿。 +type Repository interface { + SaveBroadcastOutbox(ctx context.Context, record broadcastdomain.OutboxRecord) (bool, broadcastdomain.OutboxRecord, error) + ClaimPendingBroadcastOutbox(ctx context.Context, workerID string, nowMS int64, lockUntilMS int64, limit int, maxRetry int) ([]broadcastdomain.OutboxRecord, error) + MarkBroadcastOutboxDelivered(ctx context.Context, eventID string, nowMS int64) error + MarkBroadcastOutboxFailed(ctx context.Context, eventID string, workerID string, nowMS int64, nextRetryAtMS int64, maxRetry int, lastError string) error +} + +// Publisher 隐藏腾讯云 IM REST 细节,只暴露 activity-service 真正拥有的建群和发群自定义消息能力。 +type Publisher interface { + EnsureGroup(ctx context.Context, spec tencentim.GroupSpec) error + PublishGroupCustomMessage(ctx context.Context, message tencentim.CustomGroupMessage) error + DeleteGroupMember(ctx context.Context, groupID string, userID int64) error +} + +// RegionSource 从 user-service 读取 active 区域。 +// 区域归属是用户主数据,activity-service 不复制区域配置,只在建群 reconciler 中读取。 +type RegionSource interface { + ListActiveRegionIDs(ctx context.Context) ([]int64, error) +} + +// Config 保存播报策略和 worker 参数。 +// SuperGiftMinValue 是产品策略阈值;Worker* 是 outbox 投递吞吐和故障恢复参数。 +type Config struct { + NodeID string + SuperGiftMinValue int64 + WorkerBatchSize int + WorkerLockTTL time.Duration + WorkerMaxRetry int + WorkerPollInterval time.Duration + EnsureGroupsOnStartup bool +} + +// PublishInput 是服务端入队播报请求。 +// 调用方必须提供稳定 EventID;重复请求会命中 outbox 幂等,而不是重复发 IM。 +type PublishInput struct { + EventID string + BroadcastType string + RegionID int64 + PayloadJSON string +} + +// Service 拥有播报群建群补偿、播报入队和 outbox 投递决策。 +// 它不直接向客户端返回 UI 文案,只生产带 action 的结构化 JSON,让客户端自行决定展示形态。 +type Service struct { + cfg Config + repository Repository + publisher Publisher + regionSource RegionSource + now func() time.Time +} + +// New 创建播报服务。 +// publisher 可以为 nil,此时仍允许消费事件并写 outbox,但真正投递会 fail-closed;本地环境默认不误发腾讯云消息。 +func New(cfg Config, repository Repository, publisher Publisher, regionSource RegionSource) *Service { + cfg = normalizeConfig(cfg) + return &Service{cfg: cfg, repository: repository, publisher: publisher, regionSource: regionSource, now: time.Now} +} + +// SetClock 注入确定性时间,测试中用它验证 payload 和 outbox 的 Unix ms 字段。 +func (s *Service) SetClock(now func() time.Time) { + if now != nil { + s.now = now + } +} + +// EnsureBroadcastGroups 幂等创建全局播报群和所有 active 区域播报群。 +// 这个动作放在启动/定时 reconciler,不放在 /im/usersig 路径,避免用户登录被外部腾讯 REST 拖慢。 +func (s *Service) EnsureBroadcastGroups(ctx context.Context) (int, error) { + if s == nil || s.publisher == nil { + return 0, xerr.New(xerr.Unavailable, "broadcast publisher is not configured") + } + app := appcode.FromContext(ctx) + count := 0 + globalID, err := imgroup.GlobalBroadcastGroupID(app) + if err != nil { + return 0, xerr.New(xerr.InvalidArgument, err.Error()) + } + if err := s.publisher.EnsureGroup(ctx, broadcastGroupSpec(globalID)); err != nil { + return count, err + } + count++ + + if s.regionSource == nil { + // 没有区域源时至少保证全局群存在;区域群等待下次有 user-service 依赖的 reconciler 补齐。 + return count, nil + } + regionIDs, err := s.regionSource.ListActiveRegionIDs(ctx) + if err != nil { + return count, err + } + for _, regionID := range regionIDs { + if regionID <= 0 { + // GLOBAL/未知区域不对应 IM 区域群,避免客户端加入一个语义不清的“0 区域群”。 + continue + } + groupID, err := imgroup.RegionBroadcastGroupID(app, regionID) + if err != nil { + return count, xerr.New(xerr.InvalidArgument, err.Error()) + } + if err := s.publisher.EnsureGroup(ctx, broadcastGroupSpec(groupID)); err != nil { + return count, err + } + count++ + } + return count, nil +} + +// PublishRegionBroadcast 把区域播报写入持久化 outbox。 +// 这里不直接调用腾讯 REST,保证调用方提交成功后即使进程崩溃也能由 worker 继续投递。 +func (s *Service) PublishRegionBroadcast(ctx context.Context, input PublishInput) (broadcastdomain.PublishResult, error) { + if input.RegionID <= 0 { + return broadcastdomain.PublishResult{}, xerr.New(xerr.InvalidArgument, "region_id is required") + } + groupID, err := imgroup.RegionBroadcastGroupID(appcode.FromContext(ctx), input.RegionID) + if err != nil { + return broadcastdomain.PublishResult{}, xerr.New(xerr.InvalidArgument, err.Error()) + } + return s.enqueue(ctx, broadcastdomain.ScopeRegion, groupID, input) +} + +// PublishGlobalBroadcast 把全局播报写入持久化 outbox。 +// 全局播报和区域播报共用同一张表,scope/group_id 决定最终投递目标。 +func (s *Service) PublishGlobalBroadcast(ctx context.Context, input PublishInput) (broadcastdomain.PublishResult, error) { + groupID, err := imgroup.GlobalBroadcastGroupID(appcode.FromContext(ctx)) + if err != nil { + return broadcastdomain.PublishResult{}, xerr.New(xerr.InvalidArgument, err.Error()) + } + return s.enqueue(ctx, broadcastdomain.ScopeGlobal, groupID, input) +} + +// RemoveRegionBroadcastMember 把一个用户从旧区域播报群移除。 +// 这是成员关系更新,不是区域群生命周期操作;区域群仍由 reconciler 长期维护,其他用户不受影响。 +func (s *Service) RemoveRegionBroadcastMember(ctx context.Context, userID int64, regionID int64) (string, bool, error) { + if userID <= 0 { + return "", false, xerr.New(xerr.InvalidArgument, "user_id is required") + } + if regionID <= 0 { + // GLOBAL/无区域没有对应区域播报群,调用方跨区域比较时可以安全把 0 传进来。 + return "", false, nil + } + if s == nil || s.publisher == nil { + return "", false, xerr.New(xerr.Unavailable, "broadcast publisher is not configured") + } + groupID, err := imgroup.RegionBroadcastGroupID(appcode.FromContext(ctx), regionID) + if err != nil { + return "", false, xerr.New(xerr.InvalidArgument, err.Error()) + } + if err := s.publisher.DeleteGroupMember(ctx, groupID, userID); err != nil { + return groupID, false, err + } + return groupID, true, nil +} + +func (s *Service) enqueue(ctx context.Context, scope string, groupID string, input PublishInput) (broadcastdomain.PublishResult, error) { + if s == nil || s.repository == nil { + return broadcastdomain.PublishResult{}, xerr.New(xerr.Unavailable, "broadcast repository is not configured") + } + input.EventID = strings.TrimSpace(input.EventID) + input.BroadcastType = strings.TrimSpace(input.BroadcastType) + if input.EventID == "" || input.BroadcastType == "" { + return broadcastdomain.PublishResult{}, xerr.New(xerr.InvalidArgument, "event_id and broadcast_type are required") + } + nowMS := s.now().UTC().UnixMilli() + payloadJSON, err := normalizedPayloadJSON(input.PayloadJSON, map[string]any{ + "event_id": input.EventID, + "broadcast_type": input.BroadcastType, + "scope": scope, + "app_code": appcode.FromContext(ctx), + "region_id": input.RegionID, + "sent_at_ms": nowMS, + }) + if err != nil { + return broadcastdomain.PublishResult{}, err + } + // outbox 记录保存的是完整 JSON,而不是只保存引用 ID;客户端收到 IM 后无需再同步请求才能完成入口跳转。 + record := broadcastdomain.OutboxRecord{ + AppCode: appcode.FromContext(ctx), + EventID: input.EventID, + Scope: scope, + GroupID: groupID, + BroadcastType: input.BroadcastType, + PayloadJSON: payloadJSON, + Status: broadcastdomain.StatusPending, + CreatedAtMS: nowMS, + UpdatedAtMS: nowMS, + } + created, saved, err := s.repository.SaveBroadcastOutbox(ctx, record) + if err != nil { + return broadcastdomain.PublishResult{}, err + } + return broadcastdomain.PublishResult{EventID: saved.EventID, GroupID: saved.GroupID, Status: saved.Status, Created: created}, nil +} + +// ProcessPendingBroadcasts 抢占一批待投递 outbox,发送到腾讯 IM,并更新成功/重试状态。 +// claim 和 mark 分开做:抢占阶段保护多 worker 并发,发送阶段允许单条失败不影响同批其他消息。 +func (s *Service) ProcessPendingBroadcasts(ctx context.Context, options WorkerOptions) (broadcastdomain.ProcessResult, error) { + if s == nil || s.repository == nil { + return broadcastdomain.ProcessResult{}, xerr.New(xerr.Unavailable, "broadcast repository is not configured") + } + if s.publisher == nil { + return broadcastdomain.ProcessResult{}, xerr.New(xerr.Unavailable, "broadcast publisher is not configured") + } + options = normalizeWorkerOptions(options, s.cfg) + nowMS := s.now().UTC().UnixMilli() + records, err := s.repository.ClaimPendingBroadcastOutbox(ctx, options.WorkerID, nowMS, nowMS+options.LockTTL.Milliseconds(), options.BatchSize, options.MaxRetry) + if err != nil { + return broadcastdomain.ProcessResult{}, err + } + result := broadcastdomain.ProcessResult{ClaimedCount: len(records), HasMore: len(records) >= options.BatchSize} + for _, record := range records { + // 腾讯 REST 只接受已序列化 JSON;event_id/desc/ext 让客户端和日志都能快速识别消息类型。 + err := s.publisher.PublishGroupCustomMessage(ctx, tencentim.CustomGroupMessage{ + GroupID: record.GroupID, + EventID: record.EventID, + Desc: record.BroadcastType, + Ext: "im_broadcast", + PayloadJSON: json.RawMessage(record.PayloadJSON), + }) + if err != nil { + result.FailureCount++ + // Mark 失败只记录为 best-effort:当前记录锁会过期,下一轮 worker 仍可重新接管。 + _ = s.repository.MarkBroadcastOutboxFailed(ctx, record.EventID, options.WorkerID, s.now().UTC().UnixMilli(), s.now().UTC().Add(options.PollInterval).UnixMilli(), options.MaxRetry, trimError(err.Error())) + continue + } + if err := s.repository.MarkBroadcastOutboxDelivered(ctx, record.EventID, s.now().UTC().UnixMilli()); err != nil { + return result, err + } + result.SuccessCount++ + } + return result, nil +} + +// HandleRoomEvent 把已提交的 room outbox 事实转换为服务端播报。 +// 只有 RoomGiftSent 且满足区域和礼物价值阈值时才生成区域播报,避免把展示策略侵入 Room Cell 主链路。 +func (s *Service) HandleRoomEvent(ctx context.Context, envelope *roomeventsv1.EventEnvelope) (broadcastdomain.ConsumeRoomEventResult, error) { + if envelope == nil { + return broadcastdomain.ConsumeRoomEventResult{}, xerr.New(xerr.InvalidArgument, "room event envelope is required") + } + eventCtx := appcode.WithContext(ctx, envelope.GetAppCode()) + result := broadcastdomain.ConsumeRoomEventResult{EventID: envelope.GetEventId(), Status: broadcastdomain.StatusSkipped} + if envelope.GetEventType() != "RoomGiftSent" { + // 当前只消费礼物事实;未来红包或运营事件应显式增加事件类型分支和测试。 + return result, nil + } + var gift roomeventsv1.RoomGiftSent + if err := proto.Unmarshal(envelope.GetBody(), &gift); err != nil { + return broadcastdomain.ConsumeRoomEventResult{}, err + } + if gift.GetVisibleRegionId() <= 0 || gift.GetGiftValue() < s.cfg.SuperGiftMinValue { + // visible_region_id 来自房间/主播可见区域,不能用客户端当前 IP 或本地时区推断。 + return result, nil + } + broadcastEventID := superGiftBroadcastEventID(envelope, &gift) + payloadJSON, err := superGiftPayload(envelope, &gift, broadcastEventID, s.now().UTC().UnixMilli()) + if err != nil { + return broadcastdomain.ConsumeRoomEventResult{}, err + } + published, err := s.PublishRegionBroadcast(eventCtx, PublishInput{ + EventID: broadcastEventID, + BroadcastType: broadcastdomain.TypeSuperGift, + RegionID: gift.GetVisibleRegionId(), + PayloadJSON: payloadJSON, + }) + if err != nil { + return broadcastdomain.ConsumeRoomEventResult{}, err + } + // 返回上游 event_id 和下游 broadcast_event_id,方便排查“房间事件已消费但播报是否生成”。 + return broadcastdomain.ConsumeRoomEventResult{ + EventID: envelope.GetEventId(), + Status: published.Status, + BroadcastEventID: published.EventID, + BroadcastCreated: published.Created, + }, nil +} + +// WorkerOptions 描述一次 worker 批处理请求;cron 和常驻 worker 都走同一套参数归一化。 +type WorkerOptions struct { + WorkerID string + BatchSize int + LockTTL time.Duration + MaxRetry int + PollInterval time.Duration +} + +func normalizeConfig(cfg Config) Config { + cfg.NodeID = strings.TrimSpace(cfg.NodeID) + if cfg.NodeID == "" { + cfg.NodeID = "activity-broadcast" + } + if cfg.SuperGiftMinValue <= 0 { + cfg.SuperGiftMinValue = 100000 + } + if cfg.WorkerBatchSize <= 0 { + cfg.WorkerBatchSize = defaultBroadcastBatchSize + } + if cfg.WorkerLockTTL <= 0 { + cfg.WorkerLockTTL = defaultBroadcastLockTTL + } + if cfg.WorkerMaxRetry <= 0 { + cfg.WorkerMaxRetry = defaultBroadcastMaxRetry + } + if cfg.WorkerPollInterval <= 0 { + cfg.WorkerPollInterval = time.Second + } + return cfg +} + +func normalizeWorkerOptions(options WorkerOptions, cfg Config) WorkerOptions { + if strings.TrimSpace(options.WorkerID) == "" { + options.WorkerID = cfg.NodeID + "-broadcast" + } + if options.BatchSize <= 0 { + options.BatchSize = cfg.WorkerBatchSize + } + if options.LockTTL <= 0 { + options.LockTTL = cfg.WorkerLockTTL + } + if options.MaxRetry <= 0 { + options.MaxRetry = cfg.WorkerMaxRetry + } + if options.PollInterval <= 0 { + options.PollInterval = cfg.WorkerPollInterval + } + return options +} + +func broadcastGroupSpec(groupID string) tencentim.GroupSpec { + return tencentim.GroupSpec{ + GroupID: groupID, + Name: groupID, + Type: tencentim.DefaultGroupType, + // 入群表面允许 FreeAccess,真正准入由腾讯回调回查 user-service;这样客户端 SDK 体验简单,权限仍在服务端。 + ApplyJoinOption: "FreeAccess", + } +} + +func normalizedPayloadJSON(input string, forced map[string]any) (string, error) { + input = strings.TrimSpace(input) + if input == "" { + input = "{}" + } + var payload map[string]any + if err := json.Unmarshal([]byte(input), &payload); err != nil { + return "", xerr.New(xerr.InvalidArgument, "payload_json is invalid") + } + if payload == nil { + payload = map[string]any{} + } + for key, value := range forced { + if key == "region_id" && value.(int64) <= 0 { + // 全局播报不写 region_id,避免客户端误把 0 当作一个真实区域。 + continue + } + // forced 字段覆盖调用方 payload,保证 event_id/scope/app_code/sent_at_ms 不被外部请求伪造。 + payload[key] = value + } + encoded, err := json.Marshal(payload) + if err != nil { + return "", err + } + return string(encoded), nil +} + +func superGiftBroadcastEventID(envelope *roomeventsv1.EventEnvelope, gift *roomeventsv1.RoomGiftSent) string { + if strings.TrimSpace(gift.GetCommandId()) != "" { + // command_id 是 SendGift 幂等键,用它生成播报 event_id 可避免同一房间事件重放时重复播报。 + return fmt.Sprintf("gift_broadcast:%s:%s", envelope.GetRoomId(), gift.GetCommandId()) + } + // 兼容没有 command_id 的旧/测试事件;当前开发阶段仍以 envelope event_id 保持幂等。 + return "gift_broadcast:" + envelope.GetEventId() +} + +func superGiftPayload(envelope *roomeventsv1.EventEnvelope, gift *roomeventsv1.RoomGiftSent, eventID string, sentAtMS int64) (string, error) { + payload := map[string]any{ + "event_id": eventID, + "broadcast_type": broadcastdomain.TypeSuperGift, + "scope": broadcastdomain.ScopeRegion, + "app_code": envelope.GetAppCode(), + "region_id": gift.GetVisibleRegionId(), + "room_id": envelope.GetRoomId(), + "sender_user_id": gift.GetSenderUserId(), + "target_user_id": gift.GetTargetUserId(), + "gift_id": gift.GetGiftId(), + "gift_count": gift.GetGiftCount(), + "gift_value": gift.GetGiftValue(), + "sent_at_ms": sentAtMS, + "room_version": envelope.GetRoomVersion(), + "source_event_id": envelope.GetEventId(), + "action": map[string]any{ + "type": "enter_room", + "room_id": envelope.GetRoomId(), + }, + } + encoded, err := json.Marshal(payload) + return string(encoded), err +} + +func trimError(value string) string { + value = strings.TrimSpace(value) + if len(value) > 512 { + return value[:512] + } + return value +} diff --git a/services/activity-service/internal/service/broadcast/service_mysql_test.go b/services/activity-service/internal/service/broadcast/service_mysql_test.go new file mode 100644 index 00000000..952194d4 --- /dev/null +++ b/services/activity-service/internal/service/broadcast/service_mysql_test.go @@ -0,0 +1,105 @@ +package broadcast + +import ( + "context" + "encoding/json" + "testing" + "time" + + roomeventsv1 "hyapp.local/api/proto/events/room/v1" + "hyapp/pkg/appcode" + "hyapp/pkg/tencentim" + broadcastdomain "hyapp/services/activity-service/internal/domain/broadcast" + "hyapp/services/activity-service/internal/testutil/mysqltest" +) + +func TestBroadcastServiceUsesRealMySQLOutbox(t *testing.T) { + // 这个测试使用生产 initdb 创建隔离 MySQL schema,验证真实 JSON 列、主键幂等、claim 锁和 delivered 更新。 + repository := mysqltest.NewRepository(t) + publisher := &fakePublisher{} + service := New(Config{NodeID: "node-real", SuperGiftMinValue: 100}, repository.Repository, publisher, nil) + service.SetClock(func() time.Time { return time.UnixMilli(1_700_000_123_456) }) + ctx := appcode.WithContext(context.Background(), "lalu") + + envelope := mustGiftEnvelope(t, roomeventsv1.RoomGiftSent{ + SenderUserId: 42, + TargetUserId: 43, + GiftId: "super_rocket", + GiftCount: 3, + GiftValue: 300000, + VisibleRegionId: 210, + CommandId: "cmd-real-send-gift-1", + }) + + created, err := service.HandleRoomEvent(ctx, envelope) + if err != nil { + t.Fatalf("HandleRoomEvent with real mysql failed: %v", err) + } + if !created.BroadcastCreated || created.BroadcastEventID != "gift_broadcast:room-1001:cmd-real-send-gift-1" { + t.Fatalf("unexpected first consume result: %+v", created) + } + t.Logf("real mysql enqueue: room_id=%s region_id=%d gift_value=%d broadcast_event_id=%s", envelope.GetRoomId(), int64(210), int64(300000), created.BroadcastEventID) + + // 同一个 room outbox 事实再次消费必须命中 MySQL 主键幂等,不能产生第二条播报。 + again, err := service.HandleRoomEvent(ctx, envelope) + if err != nil { + t.Fatalf("second HandleRoomEvent with real mysql failed: %v", err) + } + if again.BroadcastCreated { + t.Fatalf("duplicate room event should not create another broadcast: %+v", again) + } + + record, exists, err := repository.Repository.GetBroadcastOutbox(ctx, created.BroadcastEventID) + if err != nil { + t.Fatalf("read real mysql outbox failed: %v", err) + } + if !exists || record.Status != broadcastdomain.StatusPending || record.GroupID != "hy_lalu_bc_r_210" { + t.Fatalf("unexpected pending outbox record: exists=%v record=%+v", exists, record) + } + t.Logf("real mysql pending record: event_id=%s group_id=%s status=%s", record.EventID, record.GroupID, record.Status) + assertJSONField(t, record.PayloadJSON, "room_id", "room-1001") + assertJSONField(t, record.PayloadJSON, "gift_id", "super_rocket") + assertJSONField(t, record.PayloadJSON, "scope", broadcastdomain.ScopeRegion) + + result, err := service.ProcessPendingBroadcasts(ctx, WorkerOptions{WorkerID: "worker-real", BatchSize: 1, PollInterval: time.Second}) + if err != nil { + t.Fatalf("ProcessPendingBroadcasts with real mysql failed: %v", err) + } + if result.ClaimedCount != 1 || result.SuccessCount != 1 || result.FailureCount != 0 { + t.Fatalf("unexpected process result: %+v", result) + } + if len(publisher.messages) != 1 { + t.Fatalf("expected one Tencent message, got %d", len(publisher.messages)) + } + assertPublishedMessage(t, publisher.messages[0], "hy_lalu_bc_r_210", created.BroadcastEventID) + + delivered, exists, err := repository.Repository.GetBroadcastOutbox(ctx, created.BroadcastEventID) + if err != nil { + t.Fatalf("read delivered real mysql outbox failed: %v", err) + } + if !exists || delivered.Status != broadcastdomain.StatusDelivered || delivered.LockedBy != "" || delivered.LockedUntilMS != 0 { + t.Fatalf("unexpected delivered outbox record: exists=%v record=%+v", exists, delivered) + } + t.Logf("real mysql delivered record: event_id=%s group_id=%s status=%s", delivered.EventID, delivered.GroupID, delivered.Status) +} + +func assertJSONField(t *testing.T, payloadJSON string, key string, want any) { + t.Helper() + + var payload map[string]any + if err := json.Unmarshal([]byte(payloadJSON), &payload); err != nil { + t.Fatalf("payload is not valid json: %v\npayload=%s", err, payloadJSON) + } + if got := payload[key]; got != want { + t.Fatalf("json field %s mismatch: got=%v want=%v payload=%+v", key, got, want, payload) + } +} + +func assertPublishedMessage(t *testing.T, message tencentim.CustomGroupMessage, groupID string, eventID string) { + t.Helper() + + if message.GroupID != groupID || message.EventID != eventID || message.Desc != broadcastdomain.TypeSuperGift || message.Ext != "im_broadcast" { + t.Fatalf("unexpected Tencent custom message: %+v", message) + } + assertJSONField(t, string(message.PayloadJSON), "event_id", eventID) +} diff --git a/services/activity-service/internal/service/broadcast/service_test.go b/services/activity-service/internal/service/broadcast/service_test.go new file mode 100644 index 00000000..658b4d93 --- /dev/null +++ b/services/activity-service/internal/service/broadcast/service_test.go @@ -0,0 +1,227 @@ +package broadcast + +import ( + "context" + "encoding/json" + "errors" + "testing" + "time" + + "google.golang.org/protobuf/proto" + roomeventsv1 "hyapp.local/api/proto/events/room/v1" + "hyapp/pkg/appcode" + "hyapp/pkg/tencentim" + broadcastdomain "hyapp/services/activity-service/internal/domain/broadcast" +) + +func TestHandleRoomGiftSentCreatesRegionBroadcast(t *testing.T) { + repository := newFakeRepository() + service := New(Config{NodeID: "node-a", SuperGiftMinValue: 100}, repository, nil, nil) + service.SetClock(func() time.Time { return time.UnixMilli(1_700_000_000_000) }) + envelope := mustGiftEnvelope(t, roomeventsv1.RoomGiftSent{ + SenderUserId: 42, + TargetUserId: 43, + GiftId: "rocket", + GiftCount: 2, + GiftValue: 999, + VisibleRegionId: 1001, + CommandId: "cmd-send-gift-1", + }) + + result, err := service.HandleRoomEvent(appcode.WithContext(context.Background(), "lalu"), envelope) + if err != nil { + t.Fatalf("HandleRoomEvent failed: %v", err) + } + if result.Status != broadcastdomain.StatusPending || !result.BroadcastCreated || result.BroadcastEventID != "gift_broadcast:room-1001:cmd-send-gift-1" { + t.Fatalf("unexpected result: %+v", result) + } + record := repository.records[result.BroadcastEventID] + if record.GroupID != "hy_lalu_bc_r_1001" || record.BroadcastType != broadcastdomain.TypeSuperGift { + t.Fatalf("unexpected broadcast record: %+v", record) + } + var payload map[string]any + if err := json.Unmarshal([]byte(record.PayloadJSON), &payload); err != nil { + t.Fatalf("payload is not json: %v", err) + } + if payload["room_id"] != "room-1001" || payload["gift_id"] != "rocket" || payload["scope"] != "region" { + t.Fatalf("payload mismatch: %+v", payload) + } + + again, err := service.HandleRoomEvent(appcode.WithContext(context.Background(), "lalu"), envelope) + if err != nil { + t.Fatalf("second HandleRoomEvent failed: %v", err) + } + if again.BroadcastCreated { + t.Fatalf("second consume must be idempotent: %+v", again) + } +} + +func TestHandleRoomGiftSentSkipsNonBroadcastCases(t *testing.T) { + service := New(Config{SuperGiftMinValue: 1000}, newFakeRepository(), nil, nil) + belowThreshold := mustGiftEnvelope(t, roomeventsv1.RoomGiftSent{GiftValue: 999, VisibleRegionId: 1001}) + result, err := service.HandleRoomEvent(context.Background(), belowThreshold) + if err != nil { + t.Fatalf("below threshold failed: %v", err) + } + if result.Status != broadcastdomain.StatusSkipped || result.BroadcastEventID != "" { + t.Fatalf("below threshold should skip: %+v", result) + } + + globalRegion := mustGiftEnvelope(t, roomeventsv1.RoomGiftSent{GiftValue: 1000, VisibleRegionId: 0}) + result, err = service.HandleRoomEvent(context.Background(), globalRegion) + if err != nil { + t.Fatalf("global region failed: %v", err) + } + if result.Status != broadcastdomain.StatusSkipped || result.BroadcastEventID != "" { + t.Fatalf("global region should skip: %+v", result) + } +} + +func TestProcessPendingBroadcastsPublishesCustomMessage(t *testing.T) { + repository := newFakeRepository() + publisher := &fakePublisher{} + service := New(Config{NodeID: "node-a"}, repository, publisher, nil) + repository.records["evt-1"] = broadcastdomain.OutboxRecord{ + AppCode: "lalu", + EventID: "evt-1", + GroupID: "hy_lalu_bc_g", + BroadcastType: broadcastdomain.TypeRedPacket, + PayloadJSON: `{"event_id":"evt-1","broadcast_type":"red_packet"}`, + Status: broadcastdomain.StatusPending, + } + + result, err := service.ProcessPendingBroadcasts(appcode.WithContext(context.Background(), "lalu"), WorkerOptions{WorkerID: "worker-a", BatchSize: 10}) + if err != nil { + t.Fatalf("ProcessPendingBroadcasts failed: %v", err) + } + if result.SuccessCount != 1 || len(publisher.messages) != 1 { + t.Fatalf("publish result mismatch: result=%+v messages=%d", result, len(publisher.messages)) + } + if repository.records["evt-1"].Status != broadcastdomain.StatusDelivered { + t.Fatalf("record should be delivered: %+v", repository.records["evt-1"]) + } + if publisher.messages[0].GroupID != "hy_lalu_bc_g" || publisher.messages[0].Desc != broadcastdomain.TypeRedPacket { + t.Fatalf("message mismatch: %+v", publisher.messages[0]) + } +} + +func TestRemoveRegionBroadcastMemberDeletesOnlyUserMembership(t *testing.T) { + publisher := &fakePublisher{} + service := New(Config{NodeID: "node-a"}, newFakeRepository(), publisher, nil) + + groupID, removed, err := service.RemoveRegionBroadcastMember(appcode.WithContext(context.Background(), "lalu"), 42, 1001) + if err != nil { + t.Fatalf("RemoveRegionBroadcastMember failed: %v", err) + } + if !removed || groupID != "hy_lalu_bc_r_1001" { + t.Fatalf("unexpected remove result: group_id=%s removed=%t", groupID, removed) + } + if publisher.deletedGroupID != "hy_lalu_bc_r_1001" || publisher.deletedUserID != 42 { + t.Fatalf("unexpected deleted member: group_id=%s user_id=%d", publisher.deletedGroupID, publisher.deletedUserID) + } + + groupID, removed, err = service.RemoveRegionBroadcastMember(appcode.WithContext(context.Background(), "lalu"), 42, 0) + if err != nil { + t.Fatalf("zero region should be a no-op, got: %v", err) + } + if removed || groupID != "" { + t.Fatalf("zero region should not delete any group member: group_id=%s removed=%t", groupID, removed) + } +} + +func mustGiftEnvelope(t *testing.T, gift roomeventsv1.RoomGiftSent) *roomeventsv1.EventEnvelope { + t.Helper() + body, err := proto.Marshal(&gift) + if err != nil { + t.Fatalf("marshal gift failed: %v", err) + } + return &roomeventsv1.EventEnvelope{ + EventId: "evt-room-gift-1", + RoomId: "room-1001", + EventType: "RoomGiftSent", + RoomVersion: 7, + OccurredAtMs: 1_700_000_000_000, + AppCode: "lalu", + Body: body, + } +} + +type fakeRepository struct { + records map[string]broadcastdomain.OutboxRecord +} + +func newFakeRepository() *fakeRepository { + return &fakeRepository{records: map[string]broadcastdomain.OutboxRecord{}} +} + +func (r *fakeRepository) SaveBroadcastOutbox(_ context.Context, record broadcastdomain.OutboxRecord) (bool, broadcastdomain.OutboxRecord, error) { + if existing, ok := r.records[record.EventID]; ok { + return false, existing, nil + } + r.records[record.EventID] = record + return true, record, nil +} + +func (r *fakeRepository) ClaimPendingBroadcastOutbox(_ context.Context, workerID string, _ int64, lockUntilMS int64, limit int, _ int) ([]broadcastdomain.OutboxRecord, error) { + records := make([]broadcastdomain.OutboxRecord, 0, limit) + for eventID, record := range r.records { + if len(records) >= limit { + break + } + if record.Status != broadcastdomain.StatusPending && record.Status != broadcastdomain.StatusRetryable { + continue + } + record.Status = broadcastdomain.StatusDelivering + record.LockedBy = workerID + record.LockedUntilMS = lockUntilMS + r.records[eventID] = record + records = append(records, record) + } + return records, nil +} + +func (r *fakeRepository) MarkBroadcastOutboxDelivered(_ context.Context, eventID string, nowMS int64) error { + record, ok := r.records[eventID] + if !ok { + return errors.New("record not found") + } + record.Status = broadcastdomain.StatusDelivered + record.UpdatedAtMS = nowMS + r.records[eventID] = record + return nil +} + +func (r *fakeRepository) MarkBroadcastOutboxFailed(_ context.Context, eventID string, _ string, nowMS int64, nextRetryAtMS int64, _ int, lastError string) error { + record, ok := r.records[eventID] + if !ok { + return errors.New("record not found") + } + record.Status = broadcastdomain.StatusRetryable + record.AttemptCount++ + record.NextRetryAtMS = nextRetryAtMS + record.LastError = lastError + record.UpdatedAtMS = nowMS + r.records[eventID] = record + return nil +} + +type fakePublisher struct { + messages []tencentim.CustomGroupMessage + deletedGroupID string + deletedUserID int64 +} + +func (p *fakePublisher) EnsureGroup(context.Context, tencentim.GroupSpec) error { + return nil +} + +func (p *fakePublisher) PublishGroupCustomMessage(_ context.Context, message tencentim.CustomGroupMessage) error { + p.messages = append(p.messages, message) + return nil +} + +func (p *fakePublisher) DeleteGroupMember(_ context.Context, groupID string, userID int64) error { + p.deletedGroupID = groupID + p.deletedUserID = userID + return nil +} diff --git a/services/activity-service/internal/service/broadcast/worker.go b/services/activity-service/internal/service/broadcast/worker.go new file mode 100644 index 00000000..e99092a4 --- /dev/null +++ b/services/activity-service/internal/service/broadcast/worker.go @@ -0,0 +1,35 @@ +package broadcast + +import ( + "context" + "log/slog" + "time" + + "hyapp/pkg/logx" +) + +// RunWorker 先按需补齐播报群,再持续拉取持久化 outbox 投递腾讯 IM。 +// 该 worker 只在 broadcast.enabled 且 tencent_im.enabled 时启动,本地默认关闭,防止开发环境误发真实 IM。 +func (s *Service) RunWorker(ctx context.Context, options WorkerOptions) { + options = normalizeWorkerOptions(options, s.cfg) + if s.cfg.EnsureGroupsOnStartup { + // 建群失败不退出进程:下一轮部署/定时任务可继续补偿,已经入队的消息仍保留在 MySQL。 + if _, err := s.EnsureBroadcastGroups(ctx); err != nil && ctx.Err() == nil { + logx.Error(ctx, "broadcast_group_reconcile_failed", err, slog.String("worker_id", options.WorkerID)) + } + } + ticker := time.NewTicker(options.PollInterval) + defer ticker.Stop() + + for { + if _, err := s.ProcessPendingBroadcasts(ctx, options); err != nil && ctx.Err() == nil { + // 批处理失败只影响当前轮询,outbox 记录没有被删除,下一轮会按锁和重试状态重新处理。 + logx.Error(ctx, "broadcast_outbox_batch_failed", err, slog.String("worker_id", options.WorkerID)) + } + select { + case <-ctx.Done(): + return + case <-ticker.C: + } + } +} diff --git a/services/activity-service/internal/service/task/service.go b/services/activity-service/internal/service/task/service.go index d91f1c2e..52c64330 100644 --- a/services/activity-service/internal/service/task/service.go +++ b/services/activity-service/internal/service/task/service.go @@ -14,9 +14,7 @@ import ( ) const ( - defaultTaskTimezone = "Asia/Shanghai" - defaultTaskOffset = 8 * 60 * 60 - taskRewardAsset = "COIN" + taskRewardAsset = "COIN" ) // Repository 是任务系统的唯一持久化边界;进度、领奖和事件幂等都必须落 activity MySQL。 @@ -37,35 +35,16 @@ type WalletClient interface { CreditTaskReward(ctx context.Context, req *walletv1.CreditTaskRewardRequest, opts ...grpc.CallOption) (*walletv1.CreditTaskRewardResponse, error) } -// Config 保存任务系统的全局口径;daily 周期只能使用服务端时区。 -type Config struct { - TaskTimezone string -} - // Service 承载任务查询、事件消费、领奖和后台配置用例。 type Service struct { - cfg Config repository Repository wallet WalletClient now func() time.Time - location *time.Location } -// New 创建任务服务;时区加载失败会退回 Asia/Shanghai,避免启动后使用用户或机器本地时区。 -func New(cfg Config, repository Repository, wallet WalletClient) *Service { - tz := strings.TrimSpace(cfg.TaskTimezone) - if tz == "" { - tz = defaultTaskTimezone - } - location, err := time.LoadLocation(tz) - if err != nil { - location, _ = time.LoadLocation(defaultTaskTimezone) - } - if location == nil { - // Alpine 等精简镜像可能没有 IANA tzdata;任务日边界必须继续按产品口径 UTC+8 计算。 - location = time.FixedZone(defaultTaskTimezone, defaultTaskOffset) - } - return &Service{cfg: Config{TaskTimezone: tz}, repository: repository, wallet: wallet, now: time.Now, location: location} +// New 创建任务服务;daily 周期固定按 UTC 自然日切分,不读取机器或客户端时区。 +func New(repository Repository, wallet WalletClient) *Service { + return &Service{repository: repository, wallet: wallet, now: time.Now} } // SetClock 给测试注入稳定时间;生产路径始终使用 time.Now。 @@ -286,15 +265,8 @@ type dailyCycle struct { } func (s *Service) dailyCycle(t time.Time) dailyCycle { - location := s.location - if location == nil { - location, _ = time.LoadLocation(defaultTaskTimezone) - } - if location == nil { - location = time.FixedZone(defaultTaskTimezone, defaultTaskOffset) - } - local := t.In(location) - start := time.Date(local.Year(), local.Month(), local.Day(), 0, 0, 0, 0, location) + utc := t.UTC() + start := time.Date(utc.Year(), utc.Month(), utc.Day(), 0, 0, 0, 0, time.UTC) next := start.AddDate(0, 0, 1) return dailyCycle{Key: start.Format("2006-01-02"), NextRefreshMS: next.UnixMilli()} } diff --git a/services/activity-service/internal/service/task/service_test.go b/services/activity-service/internal/service/task/service_test.go index 94f6fcdf..51a4dcaf 100644 --- a/services/activity-service/internal/service/task/service_test.go +++ b/services/activity-service/internal/service/task/service_test.go @@ -16,7 +16,7 @@ import ( func TestTaskEventQueryAndClaimFlow(t *testing.T) { repository := mysqltest.NewRepository(t) wallet := &fakeWalletClient{} - svc := taskservice.New(taskservice.Config{TaskTimezone: "Asia/Shanghai"}, repository, wallet) + svc := taskservice.New(repository, wallet) now := time.Date(2026, 5, 9, 10, 0, 0, 0, time.FixedZone("CST", 8*60*60)) svc.SetClock(func() time.Time { return now }) diff --git a/services/activity-service/internal/service/task/service_timezone_test.go b/services/activity-service/internal/service/task/service_timezone_test.go index fe5b45cd..218f0115 100644 --- a/services/activity-service/internal/service/task/service_timezone_test.go +++ b/services/activity-service/internal/service/task/service_timezone_test.go @@ -5,10 +5,13 @@ import ( "time" ) -func TestDailyCycleFallsBackWhenLocationMissing(t *testing.T) { +func TestDailyCycleUsesUTCDay(t *testing.T) { svc := &Service{} - cycle := svc.dailyCycle(time.Date(2026, 5, 8, 16, 30, 0, 0, time.UTC)) - if cycle.Key != "2026-05-09" { - t.Fatalf("daily cycle must use UTC+8 fallback when tzdata is missing: %+v", cycle) + cycle := svc.dailyCycle(time.Date(2026, 5, 8, 23, 30, 0, 0, time.FixedZone("riyadh", 3*60*60))) + if cycle.Key != "2026-05-08" { + t.Fatalf("daily cycle must use UTC day key: %+v", cycle) + } + if want := time.Date(2026, 5, 9, 0, 0, 0, 0, time.UTC).UnixMilli(); cycle.NextRefreshMS != want { + t.Fatalf("next refresh must be next UTC midnight: got=%d want=%d", cycle.NextRefreshMS, want) } } diff --git a/services/activity-service/internal/storage/mysql/broadcast_repository.go b/services/activity-service/internal/storage/mysql/broadcast_repository.go new file mode 100644 index 00000000..003216d3 --- /dev/null +++ b/services/activity-service/internal/storage/mysql/broadcast_repository.go @@ -0,0 +1,233 @@ +package mysql + +import ( + "context" + "database/sql" + "errors" + "strings" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + broadcastdomain "hyapp/services/activity-service/internal/domain/broadcast" +) + +// SaveBroadcastOutbox 插入一条持久化播报 outbox。 +// 主键是 (app_code,event_id),重复写入会返回已有记录,保证 room outbox 重放、gRPC 重试和 cron 重跑不会重复发播报。 +func (r *Repository) SaveBroadcastOutbox(ctx context.Context, record broadcastdomain.OutboxRecord) (bool, broadcastdomain.OutboxRecord, error) { + if r == nil || r.db == nil { + return false, broadcastdomain.OutboxRecord{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + record.AppCode = appcode.FromContext(ctx) + _, err := r.db.ExecContext(ctx, ` + INSERT INTO im_broadcast_outbox ( + app_code, event_id, scope, group_id, broadcast_type, payload_json, status, + attempt_count, next_retry_at_ms, last_error, locked_by, locked_until_ms, + created_at_ms, updated_at_ms + ) VALUES (?, ?, ?, ?, ?, CAST(? AS JSON), ?, ?, ?, ?, '', 0, ?, ?)`, + record.AppCode, + record.EventID, + record.Scope, + record.GroupID, + record.BroadcastType, + record.PayloadJSON, + record.Status, + record.AttemptCount, + record.NextRetryAtMS, + record.LastError, + record.CreatedAtMS, + record.UpdatedAtMS, + ) + if err == nil { + return true, record, nil + } + if !isMySQLDuplicate(err) { + return false, broadcastdomain.OutboxRecord{}, err + } + // duplicate 不能直接当成功丢弃;返回已有记录让上层知道当前状态和目标 group_id。 + existing, exists, findErr := r.GetBroadcastOutbox(ctx, record.EventID) + if findErr != nil { + return false, broadcastdomain.OutboxRecord{}, findErr + } + if !exists { + return false, broadcastdomain.OutboxRecord{}, xerr.New(xerr.Conflict, "broadcast outbox event_id already exists") + } + return false, existing, nil +} + +// GetBroadcastOutbox 按幂等键读取一条播报 outbox,测试和后台排障都会用到。 +func (r *Repository) GetBroadcastOutbox(ctx context.Context, eventID string) (broadcastdomain.OutboxRecord, bool, error) { + row := r.db.QueryRowContext(ctx, ` + SELECT app_code, event_id, scope, group_id, broadcast_type, CAST(payload_json AS CHAR), + status, attempt_count, next_retry_at_ms, last_error, locked_by, locked_until_ms, + created_at_ms, updated_at_ms + FROM im_broadcast_outbox + WHERE app_code = ? AND event_id = ?`, + appcode.FromContext(ctx), eventID, + ) + record, err := scanBroadcastOutbox(row) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return broadcastdomain.OutboxRecord{}, false, nil + } + return broadcastdomain.OutboxRecord{}, false, err + } + return record, true, nil +} + +// ClaimPendingBroadcastOutbox 抢占一页可投递播报消息。 +// FOR UPDATE SKIP LOCKED 让多个 worker 可以并行拉取不同记录;locked_until_ms 处理 worker 崩溃后的接管。 +func (r *Repository) ClaimPendingBroadcastOutbox(ctx context.Context, workerID string, nowMS int64, lockUntilMS int64, limit int, maxRetry int) ([]broadcastdomain.OutboxRecord, error) { + if r == nil || r.db == nil { + return nil, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + if strings.TrimSpace(workerID) == "" { + workerID = "activity-broadcast" + } + if limit <= 0 { + limit = 100 + } + if maxRetry <= 0 { + maxRetry = 8 + } + tx, err := r.db.BeginTx(ctx, nil) + if err != nil { + return nil, err + } + rows, err := tx.QueryContext(ctx, ` + SELECT app_code, event_id, scope, group_id, broadcast_type, CAST(payload_json AS CHAR), + status, attempt_count, next_retry_at_ms, last_error, locked_by, locked_until_ms, + created_at_ms, updated_at_ms + FROM im_broadcast_outbox + WHERE app_code = ? + AND attempt_count < ? + AND ( + (status IN (?, ?) AND next_retry_at_ms <= ?) + OR (status = ? AND locked_until_ms <= ?) + ) + ORDER BY created_at_ms ASC + LIMIT ? + FOR UPDATE SKIP LOCKED`, + appcode.FromContext(ctx), + maxRetry, + broadcastdomain.StatusPending, + broadcastdomain.StatusRetryable, + nowMS, + broadcastdomain.StatusDelivering, + nowMS, + limit, + ) + if err != nil { + _ = tx.Rollback() + return nil, err + } + records := make([]broadcastdomain.OutboxRecord, 0, limit) + for rows.Next() { + record, err := scanBroadcastOutbox(rows) + if err != nil { + _ = rows.Close() + _ = tx.Rollback() + return nil, err + } + records = append(records, record) + } + if err := rows.Close(); err != nil { + _ = tx.Rollback() + return nil, err + } + if err := rows.Err(); err != nil { + _ = tx.Rollback() + return nil, err + } + for _, record := range records { + // 先在同一事务里改成 delivering,再提交给调用方发送,避免两个 worker 同时发送同一 event_id。 + if _, err := tx.ExecContext(ctx, ` + UPDATE im_broadcast_outbox + SET status = ?, locked_by = ?, locked_until_ms = ?, updated_at_ms = ? + WHERE app_code = ? AND event_id = ?`, + broadcastdomain.StatusDelivering, + workerID, + lockUntilMS, + nowMS, + record.AppCode, + record.EventID, + ); err != nil { + _ = tx.Rollback() + return nil, err + } + } + if err := tx.Commit(); err != nil { + return nil, err + } + for i := range records { + records[i].Status = broadcastdomain.StatusDelivering + records[i].LockedBy = workerID + records[i].LockedUntilMS = lockUntilMS + } + return records, nil +} + +// MarkBroadcastOutboxDelivered 在腾讯 REST 接受消息后标记 delivered。 +// delivered 只代表服务端投递成功,不代表所有客户端已在线收到或已展示。 +func (r *Repository) MarkBroadcastOutboxDelivered(ctx context.Context, eventID string, nowMS int64) error { + _, err := r.db.ExecContext(ctx, ` + UPDATE im_broadcast_outbox + SET status = ?, locked_by = '', locked_until_ms = 0, last_error = '', updated_at_ms = ? + WHERE app_code = ? AND event_id = ?`, + broadcastdomain.StatusDelivered, + nowMS, + appcode.FromContext(ctx), + eventID, + ) + return err +} + +// MarkBroadcastOutboxFailed 释放失败记录,未达上限时进入 retryable,达到上限时进入 failed。 +// WHERE locked_by 限定当前 worker,防止锁过期后旧 worker 把新 worker 的处理结果覆盖掉。 +func (r *Repository) MarkBroadcastOutboxFailed(ctx context.Context, eventID string, workerID string, nowMS int64, nextRetryAtMS int64, maxRetry int, lastError string) error { + if maxRetry <= 0 { + maxRetry = 8 + } + _, err := r.db.ExecContext(ctx, ` + UPDATE im_broadcast_outbox + SET status = CASE WHEN attempt_count + 1 >= ? THEN ? ELSE ? END, + attempt_count = attempt_count + 1, + next_retry_at_ms = CASE WHEN attempt_count + 1 >= ? THEN 0 ELSE ? END, + last_error = ?, + locked_by = '', + locked_until_ms = 0, + updated_at_ms = ? + WHERE app_code = ? AND event_id = ? AND locked_by = ?`, + maxRetry, + broadcastdomain.StatusFailed, + broadcastdomain.StatusRetryable, + maxRetry, + nextRetryAtMS, + lastError, + nowMS, + appcode.FromContext(ctx), + eventID, + workerID, + ) + return err +} + +func scanBroadcastOutbox(scanner interface{ Scan(dest ...any) error }) (broadcastdomain.OutboxRecord, error) { + var record broadcastdomain.OutboxRecord + err := scanner.Scan( + &record.AppCode, + &record.EventID, + &record.Scope, + &record.GroupID, + &record.BroadcastType, + &record.PayloadJSON, + &record.Status, + &record.AttemptCount, + &record.NextRetryAtMS, + &record.LastError, + &record.LockedBy, + &record.LockedUntilMS, + &record.CreatedAtMS, + &record.UpdatedAtMS, + ) + return record, err +} diff --git a/services/activity-service/internal/transport/grpc/broadcast_server.go b/services/activity-service/internal/transport/grpc/broadcast_server.go new file mode 100644 index 00000000..bf3ce20d --- /dev/null +++ b/services/activity-service/internal/transport/grpc/broadcast_server.go @@ -0,0 +1,108 @@ +package grpc + +import ( + "context" + "time" + + activityv1 "hyapp.local/api/proto/activity/v1" + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + broadcastservice "hyapp/services/activity-service/internal/service/broadcast" +) + +// BroadcastServer 把 IM 播报能力暴露为内部 gRPC。 +// 外部 HTTP 不直接调用这里;gateway/cron/room-service 只能通过 protobuf 契约进入 activity-service。 +type BroadcastServer struct { + activityv1.UnimplementedBroadcastServiceServer + activityv1.UnimplementedRoomEventConsumerServiceServer + + svc *broadcastservice.Service +} + +// NewBroadcastServer 创建播报和 room event 消费共用的 gRPC adapter。 +func NewBroadcastServer(svc *broadcastservice.Service) *BroadcastServer { + return &BroadcastServer{svc: svc} +} + +func (s *BroadcastServer) EnsureBroadcastGroups(ctx context.Context, req *activityv1.EnsureBroadcastGroupsRequest) (*activityv1.EnsureBroadcastGroupsResponse, error) { + // app_code 只从 RequestMeta 进入 context,底层 repository 才能自动带上租户隔离条件。 + ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) + count, err := s.svc.EnsureBroadcastGroups(ctx) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &activityv1.EnsureBroadcastGroupsResponse{EnsuredCount: int32(count)}, nil +} + +func (s *BroadcastServer) PublishRegionBroadcast(ctx context.Context, req *activityv1.PublishRegionBroadcastRequest) (*activityv1.PublishBroadcastResponse, error) { + // 区域播报是红包、贵重礼物等高频入口,gRPC 层只做字段搬运,策略留给 service。 + ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) + result, err := s.svc.PublishRegionBroadcast(ctx, broadcastservice.PublishInput{ + EventID: req.GetEventId(), + BroadcastType: req.GetBroadcastType(), + RegionID: req.GetRegionId(), + PayloadJSON: req.GetPayloadJson(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &activityv1.PublishBroadcastResponse{EventId: result.EventID, GroupId: result.GroupID, Status: result.Status, Created: result.Created}, nil +} + +func (s *BroadcastServer) PublishGlobalBroadcast(ctx context.Context, req *activityv1.PublishGlobalBroadcastRequest) (*activityv1.PublishBroadcastResponse, error) { + // 全局播报和区域播报共用返回结构,调用方通过 group_id/status/created 判断幂等结果。 + ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) + result, err := s.svc.PublishGlobalBroadcast(ctx, broadcastservice.PublishInput{ + EventID: req.GetEventId(), + BroadcastType: req.GetBroadcastType(), + PayloadJSON: req.GetPayloadJson(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &activityv1.PublishBroadcastResponse{EventId: result.EventID, GroupId: result.GroupID, Status: result.Status, Created: result.Created}, nil +} + +func (s *BroadcastServer) RemoveRegionBroadcastMember(ctx context.Context, req *activityv1.RemoveRegionBroadcastMemberRequest) (*activityv1.RemoveRegionBroadcastMemberResponse, error) { + // 这里只删除 user_id 在旧区域群的成员关系,不删除区域群;群生命周期仍由 reconciler 管理。 + ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) + groupID, removed, err := s.svc.RemoveRegionBroadcastMember(ctx, req.GetUserId(), req.GetRegionId()) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &activityv1.RemoveRegionBroadcastMemberResponse{GroupId: groupID, Removed: removed}, nil +} + +func (s *BroadcastServer) ProcessBroadcastOutboxBatch(ctx context.Context, req *activityv1.CronBatchRequest) (*activityv1.ProcessBroadcastOutboxBatchResponse, error) { + // cron-service 可以显式触发一批投递;常驻 worker 也复用同一个 service 方法。 + ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) + result, err := s.svc.ProcessPendingBroadcasts(ctx, broadcastservice.WorkerOptions{ + WorkerID: req.GetWorkerId(), + BatchSize: int(req.GetBatchSize()), + LockTTL: time.Duration(req.GetLockTtlMs()) * time.Millisecond, + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &activityv1.ProcessBroadcastOutboxBatchResponse{ + ClaimedCount: int32(result.ClaimedCount), + SuccessCount: int32(result.SuccessCount), + FailureCount: int32(result.FailureCount), + HasMore: result.HasMore, + }, nil +} + +func (s *BroadcastServer) ConsumeRoomEvent(ctx context.Context, req *activityv1.ConsumeRoomEventRequest) (*activityv1.ConsumeRoomEventResponse, error) { + // room-service 只推送已提交的 outbox envelope;是否播报、播给哪个群由 activity-service 判定。 + ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) + result, err := s.svc.HandleRoomEvent(ctx, req.GetEnvelope()) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &activityv1.ConsumeRoomEventResponse{ + EventId: result.EventID, + Status: result.Status, + BroadcastEventId: result.BroadcastEventID, + BroadcastCreated: result.BroadcastCreated, + }, nil +} diff --git a/services/cron-service/Dockerfile b/services/cron-service/Dockerfile index 9d54b056..f55d5220 100644 --- a/services/cron-service/Dockerfile +++ b/services/cron-service/Dockerfile @@ -13,6 +13,8 @@ RUN GOWORK=off CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/grpc-healt FROM alpine:3.20 +ENV TZ=UTC + WORKDIR /app RUN apk add --no-cache ca-certificates && adduser -D -g '' appuser @@ -27,4 +29,3 @@ EXPOSE 13007 ENTRYPOINT ["/app/server"] CMD ["-config", "/app/config.yaml"] - diff --git a/services/cron-service/configs/config.docker.yaml b/services/cron-service/configs/config.docker.yaml index abea2ea2..900cebf8 100644 --- a/services/cron-service/configs/config.docker.yaml +++ b/services/cron-service/configs/config.docker.yaml @@ -8,7 +8,7 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13007" -mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=UTC" user_service_addr: "user-service:13005" activity_service_addr: "activity-service:13006" wallet_service_addr: "wallet-service:13004" diff --git a/services/cron-service/configs/config.tencent.example.yaml b/services/cron-service/configs/config.tencent.example.yaml index f732cbdf..9da9f2c2 100644 --- a/services/cron-service/configs/config.tencent.example.yaml +++ b/services/cron-service/configs/config.tencent.example.yaml @@ -8,7 +8,7 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13007" -mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=Local&tls=false" +mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=UTC&tls=false" user_service_addr: "user-service.internal:13005" activity_service_addr: "activity-service.internal:13006" wallet_service_addr: "wallet-service.internal:13004" diff --git a/services/cron-service/configs/config.yaml b/services/cron-service/configs/config.yaml index 5167578e..e7638048 100644 --- a/services/cron-service/configs/config.yaml +++ b/services/cron-service/configs/config.yaml @@ -8,7 +8,7 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13007" -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=UTC" user_service_addr: "127.0.0.1:13005" activity_service_addr: "127.0.0.1:13006" wallet_service_addr: "127.0.0.1:13004" diff --git a/services/cron-service/internal/config/config.go b/services/cron-service/internal/config/config.go index 405945e8..8ff190b4 100644 --- a/services/cron-service/internal/config/config.go +++ b/services/cron-service/internal/config/config.go @@ -62,7 +62,7 @@ func Default() Config { NodeID: "cron-local", Environment: "local", GRPCAddr: ":13007", - MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=Local", + MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_cron?parseTime=true&charset=utf8mb4&loc=UTC", UserServiceAddr: "127.0.0.1:13005", ActivityServiceAddr: "127.0.0.1:13006", WalletServiceAddr: "127.0.0.1:13004", diff --git a/services/cron-service/internal/scheduler/scheduler.go b/services/cron-service/internal/scheduler/scheduler.go index 4fd38ea0..d131b833 100644 --- a/services/cron-service/internal/scheduler/scheduler.go +++ b/services/cron-service/internal/scheduler/scheduler.go @@ -129,7 +129,7 @@ func (s *Scheduler) runOnce(ctx context.Context, taskName string, appCode string logx.Error(ctx, "cron_store_missing", nil, slog.String("task_name", taskName), slog.String("app_code", appCode)) return false } - now := time.Now() + now := time.Now().UTC() lockTTL := parseDuration(task.LockTTL, 30*time.Second) acquired, err := s.store.TryAcquireTaskLease(ctx, taskName, appCode, s.nodeID, now.UnixMilli(), lockTTL) if err != nil { @@ -168,7 +168,7 @@ func (s *Scheduler) runOnce(ctx context.Context, taskName string, appCode string }) cancel() - finished := time.Now() + finished := time.Now().UTC() run.FinishedAtMs = finished.UnixMilli() run.DurationMs = finished.Sub(now).Milliseconds() run.ClaimedCount = result.ClaimedCount diff --git a/services/gateway-service/Dockerfile b/services/gateway-service/Dockerfile index 7aada6ea..7d4adb0f 100644 --- a/services/gateway-service/Dockerfile +++ b/services/gateway-service/Dockerfile @@ -12,6 +12,8 @@ RUN GOWORK=off CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/server ./s FROM alpine:3.20 +ENV TZ=UTC + WORKDIR /app RUN apk add --no-cache ca-certificates && adduser -D -g '' appuser diff --git a/services/gateway-service/configs/config.docker.yaml b/services/gateway-service/configs/config.docker.yaml index c00f17a7..5a41f43f 100644 --- a/services/gateway-service/configs/config.docker.yaml +++ b/services/gateway-service/configs/config.docker.yaml @@ -15,7 +15,7 @@ wallet_service_addr: "wallet-service:13004" activity_service_addr: "activity-service:13006" app_config: # H5 地址由后台 APP配置/H5配置 写入 hyapp_admin.admin_app_configs,gateway 只读下发给 App。 - mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=Local" + mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=UTC" auth_rate_limit: # public auth 固定窗口频控;Redis 不可用时 gateway 启动失败,避免失去入口保护。 enabled: true @@ -45,6 +45,7 @@ tencent_im: # Docker 本地联调腾讯云 IM UserSig;必须与 room-service 使用同一组应用配置。 sdk_app_id: 20036101 secret_key: "dcdf53135f27e7cf8541c4ae9798fb0cb2f0e4d6c5c20022dbaea053f35cbb8c" + admin_identifier: "900100100" user_sig_ttl: "24h" callback_url: "" callback_auth_token: "" diff --git a/services/gateway-service/configs/config.tencent.example.yaml b/services/gateway-service/configs/config.tencent.example.yaml index 8943bbac..1d67ce89 100644 --- a/services/gateway-service/configs/config.tencent.example.yaml +++ b/services/gateway-service/configs/config.tencent.example.yaml @@ -15,7 +15,7 @@ wallet_service_addr: "wallet-service.internal:13004" activity_service_addr: "activity-service.internal:13006" app_config: # H5 地址由后台 APP配置/H5配置 写入 hyapp_admin.admin_app_configs,gateway 只读下发给 App。 - mysql_dsn: "TENCENT_MYSQL_USER:TENCENT_MYSQL_PASSWORD@tcp(TENCENT_MYSQL_HOST:3306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=Local" + mysql_dsn: "TENCENT_MYSQL_USER:TENCENT_MYSQL_PASSWORD@tcp(TENCENT_MYSQL_HOST:3306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=UTC" auth_rate_limit: # public auth 固定窗口频控;Redis 不可用时 gateway 启动失败,避免失去入口保护。 enabled: true @@ -47,6 +47,8 @@ tencent_im: sdk_app_id: 1400000000 # 腾讯云 IM SDKSecretKey,只允许保存在服务端密钥系统或线上配置中。 secret_key: "TENCENT_IM_SECRET_KEY" + # 腾讯云 IM App 管理员账号;必须和 activity/room 服务端 REST 配置一致。 + admin_identifier: "TENCENT_IM_ADMIN_IDENTIFIER" # 客户端 UserSig 有效期;过短会增加刷新频率,过长会放大泄露窗口。 user_sig_ttl: "24h" # 腾讯云 IM 控制台配置的回调地址,用于入群前、发言前等业务守卫。 diff --git a/services/gateway-service/configs/config.yaml b/services/gateway-service/configs/config.yaml index 5d961f33..6bb77869 100644 --- a/services/gateway-service/configs/config.yaml +++ b/services/gateway-service/configs/config.yaml @@ -15,7 +15,7 @@ wallet_service_addr: "127.0.0.1:13004" activity_service_addr: "127.0.0.1:13006" app_config: # H5 地址由后台 APP配置/H5配置 写入 hyapp_admin.admin_app_configs,gateway 只读下发给 App。 - mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=Local" + mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=UTC" auth_rate_limit: # public auth 固定窗口频控;Redis 不可用时 gateway 启动失败,避免失去入口保护。 enabled: true @@ -45,6 +45,7 @@ tencent_im: # 本地联调腾讯云 IM UserSig;SDKAppID 和密钥必须与 room-service 保持一致。 sdk_app_id: 20036101 secret_key: "dcdf53135f27e7cf8541c4ae9798fb0cb2f0e4d6c5c20022dbaea053f35cbb8c" + admin_identifier: "900100100" # 客户端 UserSig 有效期;线上建议 12h-7d,按登录刷新策略决定。 user_sig_ttl: "24h" # 腾讯云 IM 控制台回调 URL。需要公网可访问;本地为空表示暂不启用回调。 diff --git a/services/gateway-service/internal/app/app.go b/services/gateway-service/internal/app/app.go index 45bf8c83..86a2028f 100644 --- a/services/gateway-service/internal/app/app.go +++ b/services/gateway-service/internal/app/app.go @@ -80,6 +80,7 @@ func New(cfg config.Config) (*App, error) { var walletClient client.WalletClient = client.NewGRPCWalletClient(walletConn) var messageClient client.MessageInboxClient = client.NewGRPCMessageInboxClient(activityConn) var taskClient client.TaskClient = client.NewGRPCTaskClient(activityConn) + var broadcastClient client.BroadcastClient = client.NewGRPCBroadcastClient(activityConn) appConfigReader, err := openAppConfigReader(cfg.AppConfig) if err != nil { _ = roomConn.Close() @@ -92,6 +93,7 @@ func New(cfg config.Config) (*App, error) { SDKAppID: cfg.TencentIM.SDKAppID, SecretKey: cfg.TencentIM.SecretKey, UserSigTTL: cfg.TencentIM.UserSigTTL, + AdminIdentifier: cfg.TencentIM.AdminIdentifier, CallbackAuthToken: cfg.TencentIM.CallbackAuthToken, }, userProfileClient) handler.SetRoomQueryClient(roomQueryClient) @@ -102,6 +104,7 @@ func New(cfg config.Config) (*App, error) { handler.SetWalletClient(walletClient) handler.SetMessageInboxClient(messageClient) handler.SetTaskClient(taskClient) + handler.SetBroadcastClient(broadcastClient) if appConfigReader != nil { handler.SetAppConfigReader(appConfigReader) } diff --git a/services/gateway-service/internal/appconfig/mysql.go b/services/gateway-service/internal/appconfig/mysql.go index 187d66d8..f1fc85dd 100644 --- a/services/gateway-service/internal/appconfig/mysql.go +++ b/services/gateway-service/internal/appconfig/mysql.go @@ -12,9 +12,9 @@ import ( const h5LinkGroup = "h5-links" -const listH5LinksSQL = "SELECT `key`, COALESCE(value, ''), updated_at FROM admin_app_configs WHERE `group` = ?" +const listH5LinksSQL = "SELECT `key`, COALESCE(value, ''), updated_at_ms FROM admin_app_configs WHERE `group` = ?" const listAppBannersSQL = ` - SELECT id, app_code, cover_url, banner_type, param, platform, sort_order, region_id, country_code, description, updated_at + SELECT id, app_code, cover_url, banner_type, param, platform, sort_order, region_id, country_code, description, updated_at_ms FROM admin_app_banners WHERE app_code = ? AND status = 'active' AND (? = '' OR platform = ?) @@ -111,8 +111,8 @@ func (r *MySQLReader) ListH5Links(ctx context.Context) ([]H5Link, error) { for rows.Next() { var key string var url string - var updatedAt sql.NullTime - if err := rows.Scan(&key, &url, &updatedAt); err != nil { + var updatedAtMS int64 + if err := rows.Scan(&key, &url, &updatedAtMS); err != nil { return nil, err } @@ -121,9 +121,7 @@ func (r *MySQLReader) ListH5Links(ctx context.Context) ([]H5Link, error) { Key: key, URL: strings.TrimSpace(url), } - if updatedAt.Valid { - link.UpdatedAtMs = updatedAt.Time.UnixMilli() - } + link.UpdatedAtMs = updatedAtMS configs[key] = link } if err := rows.Err(); err != nil { @@ -165,7 +163,7 @@ func (r *MySQLReader) ListBanners(ctx context.Context, query BannerQuery) ([]Ban for rows.Next() { var item Banner var appCode string - var updatedAt sql.NullTime + var updatedAtMS int64 if err := rows.Scan( &item.ID, &appCode, @@ -177,13 +175,11 @@ func (r *MySQLReader) ListBanners(ctx context.Context, query BannerQuery) ([]Ban &item.RegionID, &item.CountryCode, &item.Description, - &updatedAt, + &updatedAtMS, ); err != nil { return nil, err } - if updatedAt.Valid { - item.UpdatedAtMs = updatedAt.Time.UnixMilli() - } + item.UpdatedAtMs = updatedAtMS items = append(items, item) } if err := rows.Err(); err != nil { diff --git a/services/gateway-service/internal/client/broadcast_client.go b/services/gateway-service/internal/client/broadcast_client.go new file mode 100644 index 00000000..f652487e --- /dev/null +++ b/services/gateway-service/internal/client/broadcast_client.go @@ -0,0 +1,27 @@ +package client + +import ( + "context" + + activityv1 "hyapp.local/api/proto/activity/v1" + + "google.golang.org/grpc" +) + +// BroadcastClient abstracts gateway access to activity-service IM broadcast membership operations. +type BroadcastClient interface { + RemoveRegionBroadcastMember(ctx context.Context, req *activityv1.RemoveRegionBroadcastMemberRequest) (*activityv1.RemoveRegionBroadcastMemberResponse, error) +} + +type grpcBroadcastClient struct { + client activityv1.BroadcastServiceClient +} + +// NewGRPCBroadcastClient builds a broadcast client backed by activity-service BroadcastService. +func NewGRPCBroadcastClient(conn *grpc.ClientConn) BroadcastClient { + return &grpcBroadcastClient{client: activityv1.NewBroadcastServiceClient(conn)} +} + +func (c *grpcBroadcastClient) RemoveRegionBroadcastMember(ctx context.Context, req *activityv1.RemoveRegionBroadcastMemberRequest) (*activityv1.RemoveRegionBroadcastMemberResponse, error) { + return c.client.RemoveRegionBroadcastMember(ctx, req) +} diff --git a/services/gateway-service/internal/config/config.go b/services/gateway-service/internal/config/config.go index c3924ba2..f442a8d6 100644 --- a/services/gateway-service/internal/config/config.go +++ b/services/gateway-service/internal/config/config.go @@ -90,6 +90,8 @@ type TencentIMConfig struct { SecretKey string `yaml:"secret_key"` // UserSigTTL 是客户端 IM 登录票据有效期。 UserSigTTL time.Duration `yaml:"user_sig_ttl"` + // AdminIdentifier 是服务端 REST 发播报和系统消息的管理员账号,回调用它识别服务端发送者。 + AdminIdentifier string `yaml:"admin_identifier"` // CallbackURL 是在腾讯云 IM 控制台配置的服务端回调地址。 CallbackURL string `yaml:"callback_url"` // CallbackAuthToken 是腾讯云 IM 回调鉴权 token,只用于校验回调来源。 @@ -144,7 +146,7 @@ func Default() Config { WalletServiceAddr: "127.0.0.1:13004", ActivityServiceAddr: "127.0.0.1:13006", AppConfig: AppConfigConfig{ - MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=Local", + MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_admin?parseTime=true&charset=utf8mb4&loc=UTC", }, AuthRateLimit: AuthRateLimitConfig{ Enabled: true, @@ -164,7 +166,8 @@ func Default() Config { KeyPrefix: "login_risk:ip:", }, TencentIM: TencentIMConfig{ - UserSigTTL: 24 * time.Hour, + UserSigTTL: 24 * time.Hour, + AdminIdentifier: "administrator", }, TencentRTC: TencentRTCConfig{ UserSigTTL: 2 * time.Hour, @@ -269,6 +272,12 @@ func (cfg *Config) Normalize() error { } cfg.TencentRTC.CallbackURL = strings.TrimSpace(cfg.TencentRTC.CallbackURL) cfg.TencentRTC.CallbackSignKey = strings.TrimSpace(cfg.TencentRTC.CallbackSignKey) + cfg.TencentIM.AdminIdentifier = strings.TrimSpace(cfg.TencentIM.AdminIdentifier) + if cfg.TencentIM.AdminIdentifier == "" { + cfg.TencentIM.AdminIdentifier = "administrator" + } + cfg.TencentIM.CallbackURL = strings.TrimSpace(cfg.TencentIM.CallbackURL) + cfg.TencentIM.CallbackAuthToken = strings.TrimSpace(cfg.TencentIM.CallbackAuthToken) return nil } diff --git a/services/gateway-service/internal/transport/http/handler.go b/services/gateway-service/internal/transport/http/handler.go index 7372f4b0..4b1f4bde 100644 --- a/services/gateway-service/internal/transport/http/handler.go +++ b/services/gateway-service/internal/transport/http/handler.go @@ -7,12 +7,15 @@ import ( "strings" "time" - roomv1 "hyapp.local/api/proto/room/v1" "hyapp/pkg/appcode" "hyapp/pkg/idgen" + "hyapp/pkg/imgroup" "hyapp/pkg/tencentim" "hyapp/services/gateway-service/internal/auth" "hyapp/services/gateway-service/internal/client" + + roomv1 "hyapp.local/api/proto/room/v1" + userv1 "hyapp.local/api/proto/user/v1" ) // Handler 是 gateway 的 HTTP transport adapter。 @@ -31,6 +34,7 @@ type Handler struct { walletClient client.WalletClient messageClient client.MessageInboxClient taskClient client.TaskClient + broadcastClient client.BroadcastClient appConfigReader appConfigReader tencentIM TencentIMConfig tencentRTC TencentRTCConfig @@ -46,6 +50,7 @@ type TencentIMConfig struct { SDKAppID int64 SecretKey string UserSigTTL time.Duration + AdminIdentifier string CallbackAuthToken string } @@ -160,6 +165,11 @@ func (h *Handler) SetTaskClient(taskClient client.TaskClient) { h.taskClient = taskClient } +// SetBroadcastClient 注入 activity-service 播报群成员关系 client。 +func (h *Handler) SetBroadcastClient(broadcastClient client.BroadcastClient) { + h.broadcastClient = broadcastClient +} + // SetAppConfigReader 注入后台 App 配置读取依赖。 func (h *Handler) SetAppConfigReader(reader appConfigReader) { h.appConfigReader = reader @@ -220,17 +230,98 @@ func (h *Handler) issueTencentIMUserSig(writer http.ResponseWriter, request *htt writeError(writer, request, http.StatusUnauthorized, codeUnauthorized, "unauthorized") return } + if h.userProfileClient == nil { + // 播报群 join 列表必须来自 user-service 当前资料,不能靠 token 快照猜区域。 + writeError(writer, request, http.StatusInternalServerError, codeInternalError, "internal error") + return + } + + userResp, err := h.userProfileClient.GetUser(request.Context(), &userv1.GetUserRequest{ + Meta: authRequestMeta(request, ""), + UserId: userID, + }) + if err != nil { + writeRPCError(writer, request, err) + return + } + user := userResp.GetUser() + if user == nil { + writeError(writer, request, http.StatusInternalServerError, codeInternalError, "internal error") + return + } + if !user.GetProfileCompleted() { + writeError(writer, request, http.StatusForbidden, codeProfileRequired, "profile required") + return + } + app := appcode.FromContext(request.Context()) + if user.GetAppCode() != "" && appcode.Normalize(user.GetAppCode()) != app { + // UserSig 是 IM 登录凭证,不能给跨 app_code 用户签发,否则会绕过播报群租户隔离。 + writeError(writer, request, http.StatusForbidden, codePermissionDenied, "permission denied") + return + } result, err := tencentim.GenerateUserSig(tencentim.UserSigConfig{ SDKAppID: h.tencentIM.SDKAppID, SecretKey: h.tencentIM.SecretKey, TTL: h.tencentIM.UserSigTTL, - }, tencentim.FormatUserID(userID), time.Now()) + }, tencentim.FormatUserID(userID), time.Now().UTC()) if err != nil { // 缺少 SDKAppID 或 SecretKey 属于服务端配置错误,不能返回假票据给客户端。 writeError(writer, request, http.StatusInternalServerError, codeInternalError, "internal error") return } - writeOK(writer, request, result) + joinGroups, ok := imJoinGroupsForUser(app, user.GetRegionId()) + if !ok { + // 生成 join_groups 失败代表服务端 app_code/region_id 配置异常,不能返回缺失群列表让客户端自行猜。 + writeError(writer, request, http.StatusBadRequest, codeInvalidArgument, "invalid argument") + return + } + + writeOK(writer, request, tencentIMUserSigResponse{ + SDKAppID: result.SDKAppID, + UserID: result.UserID, + UserSig: result.UserSig, + ExpireAtMS: result.ExpireAtMS, + JoinGroups: joinGroups, + }) +} + +type tencentIMUserSigResponse struct { + SDKAppID int64 `json:"sdk_app_id"` + UserID string `json:"user_id"` + UserSig string `json:"user_sig"` + ExpireAtMS int64 `json:"expire_at_ms"` + JoinGroups []tencentIMJoinGroup `json:"join_groups"` +} + +type tencentIMJoinGroup struct { + GroupID string `json:"group_id"` + Type string `json:"type"` + RegionID int64 `json:"region_id,omitempty"` +} + +func imJoinGroupsForUser(app string, regionID int64) ([]tencentIMJoinGroup, bool) { + globalGroupID, err := imgroup.GlobalBroadcastGroupID(app) + if err != nil { + return nil, false + } + // 全局群始终返回;实际消息量应很低,主要用于全服级运营通知或极少数全局事件。 + groups := []tencentIMJoinGroup{{ + GroupID: globalGroupID, + Type: string(imgroup.KindGlobalBroadcast), + }} + if regionID > 0 { + // 区域群来自 user-service 当前 region_id,客户端不能自选区域群;区域变更后下一次 UserSig 返回新群。 + regionGroupID, err := imgroup.RegionBroadcastGroupID(app, regionID) + if err != nil { + return nil, false + } + groups = append(groups, tencentIMJoinGroup{ + GroupID: regionGroupID, + Type: string(imgroup.KindRegionBroadcast), + RegionID: regionID, + }) + } + return groups, true } diff --git a/services/gateway-service/internal/transport/http/response_test.go b/services/gateway-service/internal/transport/http/response_test.go index 4193b9bd..df95fb34 100644 --- a/services/gateway-service/internal/transport/http/response_test.go +++ b/services/gateway-service/internal/transport/http/response_test.go @@ -249,6 +249,11 @@ type fakeTaskClient struct { err error } +type fakeBroadcastClient struct { + lastRemove *activityv1.RemoveRegionBroadcastMemberRequest + err error +} + func (f *fakeUserAuthClient) LoginPassword(_ context.Context, req *userv1.LoginPasswordRequest) (*userv1.AuthResponse, error) { f.lastLoginPassword = req f.loginPasswordCount++ @@ -321,6 +326,7 @@ func (f *fakeUserProfileClient) GetUser(_ context.Context, req *userv1.GetUserRe } return &userv1.GetUserResponse{User: &userv1.User{ UserId: req.GetUserId(), + Status: userv1.UserStatus_USER_STATUS_ACTIVE, DisplayUserId: "100001", Username: "hy", Gender: "female", @@ -411,8 +417,9 @@ func (f *fakeUserProfileClient) ChangeUserCountry(_ context.Context, req *userv1 UserId: req.GetUserId(), DisplayUserId: "100001", Country: req.GetCountry(), + RegionId: 2002, UpdatedAtMs: 3000, - }, NextChangeAllowedAtMs: 3600000}, nil + }, NextChangeAllowedAtMs: 3600000, OldRegionId: 1001, NewRegionId: 2002, RegionChanged: true}, nil } func (f *fakeUserIdentityClient) GetUserIdentity(_ context.Context, req *userv1.GetUserIdentityRequest) (*userv1.GetUserIdentityResponse, error) { @@ -597,6 +604,14 @@ func (f *fakeTaskClient) ClaimTaskReward(_ context.Context, req *activityv1.Clai return &activityv1.ClaimTaskRewardResponse{}, nil } +func (f *fakeBroadcastClient) RemoveRegionBroadcastMember(_ context.Context, req *activityv1.RemoveRegionBroadcastMemberRequest) (*activityv1.RemoveRegionBroadcastMemberResponse, error) { + f.lastRemove = req + if f.err != nil { + return nil, f.err + } + return &activityv1.RemoveRegionBroadcastMemberResponse{GroupId: "hy_lalu_bc_r_1001", Removed: true}, nil +} + func (f *fakeUserHostClient) GetHostProfile(_ context.Context, req *userv1.GetHostProfileRequest) (*userv1.GetHostProfileResponse, error) { f.lastHost = req if f.hostErr != nil { @@ -2151,6 +2166,31 @@ func TestChangeCountryUsesAuthenticatedUserIDAndMapsCooldown(t *testing.T) { assertEnvelope(t, recorder, http.StatusConflict, string(xerr.CountryChangeCooldown), "req-country-cooldown") } +func TestChangeCountryRemovesOldRegionBroadcastMember(t *testing.T) { + profileClient := &fakeUserProfileClient{} + broadcastClient := &fakeBroadcastClient{} + handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, profileClient) + handler.SetBroadcastClient(broadcastClient) + router := handler.Routes(auth.NewVerifier("secret")) + body := []byte(`{"country":"US"}`) + request := httptest.NewRequest(http.MethodPost, "/api/v1/users/me/country/change", bytes.NewReader(body)) + request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42)) + request.Header.Set("X-Request-ID", "req-country-region") + recorder := httptest.NewRecorder() + + router.ServeHTTP(recorder, request) + + if recorder.Code != http.StatusOK { + t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String()) + } + if broadcastClient.lastRemove == nil { + t.Fatalf("expected old region broadcast member removal") + } + if broadcastClient.lastRemove.GetUserId() != 42 || broadcastClient.lastRemove.GetRegionId() != 1001 || broadcastClient.lastRemove.GetMeta().GetAppCode() != "lalu" { + t.Fatalf("remove request mismatch: %+v", broadcastClient.lastRemove) + } +} + func TestCompleteOnboardingAllowsIncompleteProfileAndUsesAuthenticatedUserID(t *testing.T) { profileClient := &fakeUserProfileClient{} router := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, profileClient).Routes(auth.NewVerifier("secret")) @@ -2525,11 +2565,12 @@ func TestJoinRoomClosedWritesRoomClosedEnvelope(t *testing.T) { } func TestTencentIMUserSigUsesAuthenticatedUserIDAndFailsClosed(t *testing.T) { + profileClient := &fakeUserProfileClient{regionID: 1001} router := NewHandlerWithConfig(&fakeRoomClient{}, nil, nil, nil, TencentIMConfig{ SDKAppID: 1400000000, SecretKey: "secret", UserSigTTL: time.Hour, - }).Routes(auth.NewVerifier("secret")) + }, profileClient).Routes(auth.NewVerifier("secret")) request := httptest.NewRequest(http.MethodGet, "/api/v1/im/usersig", nil) request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42)) @@ -2548,11 +2589,19 @@ func TestTencentIMUserSigUsesAuthenticatedUserIDAndFailsClosed(t *testing.T) { if response.Code != codeOK || !ok || data["user_id"] != "42" || data["user_sig"] == "" { t.Fatalf("unexpected usersig response: %+v", response) } + groups, ok := data["join_groups"].([]any) + if !ok || len(groups) != 2 { + t.Fatalf("join_groups mismatch: %+v", data["join_groups"]) + } + regionGroup, ok := groups[1].(map[string]any) + if !ok || regionGroup["group_id"] != "hy_lalu_bc_r_1001" || regionGroup["type"] != "region_broadcast" { + t.Fatalf("region join group mismatch: %+v", groups[1]) + } missingConfigRouter := NewHandlerWithConfig(&fakeRoomClient{}, nil, nil, nil, TencentIMConfig{ SDKAppID: 1400000000, UserSigTTL: time.Hour, - }).Routes(auth.NewVerifier("secret")) + }, profileClient).Routes(auth.NewVerifier("secret")) missingConfigRequest := httptest.NewRequest(http.MethodGet, "/api/v1/im/usersig", nil) missingConfigRequest.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42)) missingConfigRequest.Header.Set("X-Request-ID", "req-usersig-missing") @@ -2829,6 +2878,43 @@ func TestTencentIMSendCallbackUsesSpeakGuard(t *testing.T) { } } +func TestTencentIMBroadcastCallbacksUseRegionGuardAndServerOnlySend(t *testing.T) { + profileClient := &fakeUserProfileClient{regionID: 1001} + guard := &fakeRoomGuardClient{} + router := NewHandlerWithConfig(&fakeRoomClient{}, guard, nil, nil, TencentIMConfig{ + SDKAppID: 1400000000, + AdminIdentifier: "administrator", + }, profileClient).Routes(auth.NewVerifier("secret")) + + joinBody := []byte(`{"CallbackCommand":"Group.CallbackBeforeApplyJoinGroup","GroupId":"hy_lalu_bc_r_1001","Requestor_Account":"42"}`) + joinRequest := httptest.NewRequest(http.MethodPost, "/api/v1/tencent-im/callback?SdkAppid=1400000000&CallbackCommand=Group.CallbackBeforeApplyJoinGroup", bytes.NewReader(joinBody)) + joinRecorder := httptest.NewRecorder() + router.ServeHTTP(joinRecorder, joinRequest) + + assertTencentCallback(t, joinRecorder, http.StatusOK, 0) + if guard.lastPresence != nil { + t.Fatalf("broadcast join must not call room guard: %+v", guard.lastPresence) + } + + mismatchBody := []byte(`{"CallbackCommand":"Group.CallbackBeforeApplyJoinGroup","GroupId":"hy_lalu_bc_r_1002","Requestor_Account":"42"}`) + mismatchRequest := httptest.NewRequest(http.MethodPost, "/api/v1/tencent-im/callback?SdkAppid=1400000000&CallbackCommand=Group.CallbackBeforeApplyJoinGroup", bytes.NewReader(mismatchBody)) + mismatchRecorder := httptest.NewRecorder() + router.ServeHTTP(mismatchRecorder, mismatchRequest) + assertTencentCallback(t, mismatchRecorder, http.StatusOK, 1) + + userSendBody := []byte(`{"CallbackCommand":"Group.CallbackBeforeSendMsg","GroupId":"hy_lalu_bc_r_1001","From_Account":"42"}`) + userSendRequest := httptest.NewRequest(http.MethodPost, "/api/v1/tencent-im/callback?SdkAppid=1400000000&CallbackCommand=Group.CallbackBeforeSendMsg", bytes.NewReader(userSendBody)) + userSendRecorder := httptest.NewRecorder() + router.ServeHTTP(userSendRecorder, userSendRequest) + assertTencentCallback(t, userSendRecorder, http.StatusOK, 1) + + adminSendBody := []byte(`{"CallbackCommand":"Group.CallbackBeforeSendMsg","GroupId":"hy_lalu_bc_r_1001","From_Account":"administrator"}`) + adminSendRequest := httptest.NewRequest(http.MethodPost, "/api/v1/tencent-im/callback?SdkAppid=1400000000&CallbackCommand=Group.CallbackBeforeSendMsg", bytes.NewReader(adminSendBody)) + adminSendRecorder := httptest.NewRecorder() + router.ServeHTTP(adminSendRecorder, adminSendRequest) + assertTencentCallback(t, adminSendRecorder, http.StatusOK, 0) +} + func TestTencentIMCallbackAuthAndUnknownCommand(t *testing.T) { router := NewHandlerWithConfig(&fakeRoomClient{}, &fakeRoomGuardClient{}, nil, nil, TencentIMConfig{ SDKAppID: 1400000000, diff --git a/services/gateway-service/internal/transport/http/rtc_handler.go b/services/gateway-service/internal/transport/http/rtc_handler.go index 03d3aa00..fadb93c9 100644 --- a/services/gateway-service/internal/transport/http/rtc_handler.go +++ b/services/gateway-service/internal/transport/http/rtc_handler.go @@ -114,5 +114,5 @@ func (h *Handler) writeRTCPresenceDenied(writer http.ResponseWriter, request *ht var timeNow = defaultTimeNow func defaultTimeNow() time.Time { - return time.Now() + return time.Now().UTC() } diff --git a/services/gateway-service/internal/transport/http/tencent_im_callback.go b/services/gateway-service/internal/transport/http/tencent_im_callback.go index 0be4f32a..2afa04ea 100644 --- a/services/gateway-service/internal/transport/http/tencent_im_callback.go +++ b/services/gateway-service/internal/transport/http/tencent_im_callback.go @@ -6,9 +6,12 @@ import ( "net/http" "strconv" "strings" + "time" roomv1 "hyapp.local/api/proto/room/v1" + userv1 "hyapp.local/api/proto/user/v1" "hyapp/pkg/appcode" + "hyapp/pkg/imgroup" ) const ( @@ -88,13 +91,33 @@ func (h *Handler) handleTencentIMCallback(writer http.ResponseWriter, request *h } func (h *Handler) handleTencentIMJoinCallback(writer http.ResponseWriter, request *http.Request, body tencentIMCallbackBody) { - roomID := strings.TrimSpace(body.GroupID) + parsed := imgroup.Parse(body.GroupID) userID, ok := parseTencentIMUserID(body.Requestor) - if roomID == "" || !ok || h.roomGuardClient == nil { + if !ok { writeTencentCallback(writer, http.StatusOK, 1, "join guard input invalid") return } + switch parsed.Kind { + case imgroup.KindGlobalBroadcast, imgroup.KindRegionBroadcast: + // 播报群不属于 Room Cell,准入只看 user-service 的用户状态、资料完成度、app_code 和区域归属。 + h.handleTencentIMBroadcastJoinCallback(writer, request, parsed, userID) + return + case imgroup.KindRoom: + // 房间群仍走 room-service guard,保证只有当前房间 presence 用户能加入/留在房间 IM 群。 + h.handleTencentIMRoomJoinCallback(writer, request, parsed.RoomID, userID) + return + default: + writeTencentCallback(writer, http.StatusOK, 1, "group_id is invalid") + return + } +} + +func (h *Handler) handleTencentIMRoomJoinCallback(writer http.ResponseWriter, request *http.Request, roomID string, userID int64) { + if roomID == "" || h.roomGuardClient == nil { + writeTencentCallback(writer, http.StatusOK, 1, "join guard input invalid") + return + } resp, err := h.roomGuardClient.VerifyRoomPresence(request.Context(), &roomv1.VerifyRoomPresenceRequest{ RoomId: roomID, UserId: userID, @@ -109,10 +132,48 @@ func (h *Handler) handleTencentIMJoinCallback(writer http.ResponseWriter, reques writeTencentCallback(writer, http.StatusOK, 0, "") } +func (h *Handler) handleTencentIMBroadcastJoinCallback(writer http.ResponseWriter, request *http.Request, parsed imgroup.ParsedGroup, userID int64) { + user, err := h.tencentIMCallbackUser(request, parsed.AppCode, userID) + if err != nil { + writeTencentCallback(writer, http.StatusOK, 1, err.Error()) + return + } + if parsed.Kind == imgroup.KindRegionBroadcast && user.GetRegionId() != parsed.RegionID { + // 区域群只允许加入当前 user-service 归属区域;客户端缓存、IP 或自报参数都不可信。 + writeTencentCallback(writer, http.StatusOK, 1, "region mismatch") + return + } + + writeTencentCallback(writer, http.StatusOK, 0, "") +} + func (h *Handler) handleTencentIMSendCallback(writer http.ResponseWriter, request *http.Request, body tencentIMCallbackBody) { - roomID := strings.TrimSpace(body.GroupID) - userID, ok := parseTencentIMUserID(body.FromAccount) - if roomID == "" || !ok || h.roomGuardClient == nil { + parsed := imgroup.Parse(body.GroupID) + switch parsed.Kind { + case imgroup.KindGlobalBroadcast, imgroup.KindRegionBroadcast: + if h.tencentIMCallbackSenderIsServer(body) { + // 播报群是服务端只写通道;管理员账号发送的 REST 消息由腾讯回调放行。 + writeTencentCallback(writer, http.StatusOK, 0, "") + return + } + writeTencentCallback(writer, http.StatusOK, 1, "broadcast group is server-only") + return + case imgroup.KindRoom: + userID, ok := parseTencentIMUserID(body.FromAccount) + if !ok { + writeTencentCallback(writer, http.StatusOK, 1, "send guard input invalid") + return + } + h.handleTencentIMRoomSendCallback(writer, request, parsed.RoomID, userID) + return + default: + writeTencentCallback(writer, http.StatusOK, 1, "group_id is invalid") + return + } +} + +func (h *Handler) handleTencentIMRoomSendCallback(writer http.ResponseWriter, request *http.Request, roomID string, userID int64) { + if roomID == "" || h.roomGuardClient == nil { writeTencentCallback(writer, http.StatusOK, 1, "send guard input invalid") return } @@ -130,6 +191,51 @@ func (h *Handler) handleTencentIMSendCallback(writer http.ResponseWriter, reques writeTencentCallback(writer, http.StatusOK, 0, "") } +func (h *Handler) tencentIMCallbackUser(request *http.Request, callbackAppCode string, userID int64) (*userv1.User, error) { + if h.userProfileClient == nil { + return nil, callbackError("user-service unavailable") + } + // 回调路径不信任客户端 join 参数,每次都回查 user-service 当前用户事实。 + resp, err := h.userProfileClient.GetUser(appcode.WithContext(request.Context(), callbackAppCode), &userv1.GetUserRequest{ + Meta: &userv1.RequestMeta{ + RequestId: requestIDFromContext(request.Context()), + Caller: "gateway-service", + SentAtMs: time.Now().UnixMilli(), + AppCode: callbackAppCode, + }, + UserId: userID, + }) + if err != nil || resp.GetUser() == nil { + return nil, callbackError("user-service unavailable") + } + user := resp.GetUser() + if !user.GetProfileCompleted() { + return nil, callbackError("profile required") + } + if user.GetStatus() != userv1.UserStatus_USER_STATUS_ACTIVE { + return nil, callbackError("user is not active") + } + if user.GetAppCode() != "" && appcode.Normalize(user.GetAppCode()) != callbackAppCode { + // callbackAppCode 来自 GroupID 解析结果,用户 app_code 不匹配时拒绝跨租户入群。 + return nil, callbackError("app_code mismatch") + } + return user, nil +} + +func (h *Handler) tencentIMCallbackSenderIsServer(body tencentIMCallbackBody) bool { + admin := strings.TrimSpace(h.tencentIM.AdminIdentifier) + if admin == "" { + return false + } + return subtleStringEqual(body.FromAccount, admin) || subtleStringEqual(body.OperatorAccount, admin) +} + +type callbackError string + +func (e callbackError) Error() string { + return string(e) +} + func (h *Handler) tencentIMCallbackAuthenticated(request *http.Request) bool { token := strings.TrimSpace(h.tencentIM.CallbackAuthToken) if token == "" { diff --git a/services/gateway-service/internal/transport/http/user_handler.go b/services/gateway-service/internal/transport/http/user_handler.go index 1d42fd28..02c29b57 100644 --- a/services/gateway-service/internal/transport/http/user_handler.go +++ b/services/gateway-service/internal/transport/http/user_handler.go @@ -1,11 +1,14 @@ package http import ( + "log/slog" "net/http" "strconv" "strings" + activityv1 "hyapp.local/api/proto/activity/v1" userv1 "hyapp.local/api/proto/user/v1" + "hyapp/pkg/logx" "hyapp/services/gateway-service/internal/auth" ) @@ -254,10 +257,41 @@ func (h *Handler) changeMyCountry(writer http.ResponseWriter, request *http.Requ writeRPCError(writer, request, err) return } + h.removeOldRegionBroadcastMemberBestEffort(request, auth.UserIDFromContext(request.Context()), resp.GetOldRegionId(), resp.GetNewRegionId(), "user_country_changed") writeOK(writer, request, profileData(resp.GetUser(), resp.GetNextChangeAllowedAtMs())) } +func (h *Handler) removeOldRegionBroadcastMemberBestEffort(request *http.Request, userID int64, oldRegionID int64, newRegionID int64, reason string) { + if h == nil || h.broadcastClient == nil || userID <= 0 || oldRegionID <= 0 || oldRegionID == newRegionID { + return + } + resp, err := h.broadcastClient.RemoveRegionBroadcastMember(request.Context(), &activityv1.RemoveRegionBroadcastMemberRequest{ + Meta: activityMeta(request), + UserId: userID, + RegionId: oldRegionID, + Reason: reason, + }) + if err != nil { + // 国家修改已经由 user-service 提交,IM 旧群成员移除是外部副作用;失败记录日志,后续 callback 仍会阻止用户重新加入旧区域群。 + logx.Warn(request.Context(), "im_region_group_member_remove_failed", + slog.Int64("user_id", userID), + slog.Int64("old_region_id", oldRegionID), + slog.Int64("new_region_id", newRegionID), + slog.String("reason", reason), + slog.String("error", err.Error()), + ) + return + } + logx.Info(request.Context(), "im_region_group_member_removed", + slog.Int64("user_id", userID), + slog.Int64("old_region_id", oldRegionID), + slog.Int64("new_region_id", newRegionID), + slog.String("group_id", resp.GetGroupId()), + slog.Bool("removed", resp.GetRemoved()), + ) +} + // changeMyDisplayUserID 修改当前登录用户的默认短号。 func (h *Handler) changeMyDisplayUserID(writer http.ResponseWriter, request *http.Request) { var body struct { diff --git a/services/room-service/Dockerfile b/services/room-service/Dockerfile index ca26dbd0..ee740ca7 100644 --- a/services/room-service/Dockerfile +++ b/services/room-service/Dockerfile @@ -13,6 +13,8 @@ RUN GOWORK=off CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/grpc-healt FROM alpine:3.20 +ENV TZ=UTC + WORKDIR /app RUN apk add --no-cache ca-certificates && adduser -D -g '' appuser diff --git a/services/room-service/configs/config.docker.yaml b/services/room-service/configs/config.docker.yaml index 8caf172b..b215e1f2 100644 --- a/services/room-service/configs/config.docker.yaml +++ b/services/room-service/configs/config.docker.yaml @@ -12,6 +12,7 @@ lease_ttl: "10s" rank_limit: 20 snapshot_every_n: 1 wallet_service_addr: "wallet-service:13004" +activity_service_addr: "activity-service:13006" tencent_im: # Docker 本地联调腾讯云 IM REST 桥接;必须与 gateway-service 使用同一组应用配置。 enabled: true @@ -22,7 +23,7 @@ tencent_im: endpoint: "adminapisgp.im.qcloud.com" group_type: "ChatRoom" request_timeout: "5s" -mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC" mysql_max_open_conns: 20 mysql_max_idle_conns: 10 mysql_auto_migrate: true diff --git a/services/room-service/configs/config.tencent.example.yaml b/services/room-service/configs/config.tencent.example.yaml index b6864c18..4a5fa5c3 100644 --- a/services/room-service/configs/config.tencent.example.yaml +++ b/services/room-service/configs/config.tencent.example.yaml @@ -12,6 +12,7 @@ lease_ttl: "10s" rank_limit: 20 snapshot_every_n: 1 wallet_service_addr: "wallet-service.internal:13004" +activity_service_addr: "activity-service.internal:13006" tencent_im: # 线上开启后,CreateRoom 会先确保腾讯云 IM 群组存在。 enabled: true @@ -29,7 +30,7 @@ tencent_im: group_type: "ChatRoom" # 同步建群/发房间系统消息的单次公网调用超时。 request_timeout: "5s" -mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local&tls=false" +mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC&tls=false" mysql_max_open_conns: 80 mysql_max_idle_conns: 20 mysql_auto_migrate: false diff --git a/services/room-service/configs/config.yaml b/services/room-service/configs/config.yaml index b8b6c923..974a38a0 100644 --- a/services/room-service/configs/config.yaml +++ b/services/room-service/configs/config.yaml @@ -12,6 +12,7 @@ rank_limit: 20 snapshot_every_n: 1 grpc_addr: ":13001" wallet_service_addr: "127.0.0.1:13004" +activity_service_addr: "127.0.0.1:13006" tencent_im: # 本地联调腾讯云 IM REST 桥接;SDKAppID、密钥和管理员账号必须来自同一个应用。 enabled: true @@ -25,7 +26,7 @@ tencent_im: group_type: "ChatRoom" # room-service 同步建群和发送房间系统消息的单次 REST 超时。 request_timeout: "5s" -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC" mysql_max_open_conns: 20 mysql_max_idle_conns: 10 mysql_auto_migrate: true diff --git a/services/room-service/deploy/mysql/initdb/001_room_service.sql b/services/room-service/deploy/mysql/initdb/001_room_service.sql index c6e379bf..96e2c657 100644 --- a/services/room-service/deploy/mysql/initdb/001_room_service.sql +++ b/services/room-service/deploy/mysql/initdb/001_room_service.sql @@ -16,8 +16,8 @@ CREATE TABLE IF NOT EXISTS rooms ( mode VARCHAR(64) NOT NULL, status VARCHAR(32) NOT NULL, visible_region_id BIGINT NOT NULL DEFAULT 0, - created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, PRIMARY KEY (app_code, room_id), UNIQUE KEY uk_rooms_short_id (app_code, room_short_id), UNIQUE KEY uk_rooms_owner_user (app_code, owner_user_id), @@ -70,8 +70,8 @@ CREATE TABLE IF NOT EXISTS room_snapshots ( room_id VARCHAR(64) NOT NULL, room_version BIGINT NOT NULL, payload LONGBLOB NOT NULL, - created_at TIMESTAMP(3) NOT NULL, - updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, PRIMARY KEY (app_code, room_id), INDEX idx_room_snapshots_version (app_code, room_id, room_version) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS room_command_log ( lease_token VARCHAR(128) NOT NULL DEFAULT '', payload LONGBLOB NOT NULL, replayable BOOLEAN NOT NULL, - created_at TIMESTAMP(3) NOT NULL, + created_at_ms BIGINT NOT NULL, UNIQUE KEY uk_room_command (app_code, room_id, command_id), KEY idx_room_command_replay (app_code, room_id, room_version) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -99,13 +99,13 @@ CREATE TABLE IF NOT EXISTS room_outbox ( room_id VARCHAR(64) NOT NULL, status VARCHAR(32) NOT NULL, worker_id VARCHAR(128) NOT NULL DEFAULT '', - lock_until TIMESTAMP(3) NULL, + lock_until_ms BIGINT NULL, envelope LONGBLOB NOT NULL, - created_at TIMESTAMP(3) NOT NULL, + created_at_ms BIGINT NOT NULL, retry_count INT NOT NULL DEFAULT 0, last_error TEXT NULL, - updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + updated_at_ms BIGINT NOT NULL, PRIMARY KEY (app_code, event_id), - KEY idx_room_outbox_pending (app_code, status, created_at), - KEY idx_room_outbox_claim (app_code, status, lock_until, created_at) + KEY idx_room_outbox_pending (app_code, status, created_at_ms), + KEY idx_room_outbox_claim (app_code, status, lock_until_ms, created_at_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/services/room-service/internal/app/app.go b/services/room-service/internal/app/app.go index f74051d5..d057d4c4 100644 --- a/services/room-service/internal/app/app.go +++ b/services/room-service/internal/app/app.go @@ -11,6 +11,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" healthgrpc "google.golang.org/grpc/health/grpc_health_v1" + activityv1 "hyapp.local/api/proto/activity/v1" roomv1 "hyapp.local/api/proto/room/v1" "hyapp/pkg/grpchealth" "hyapp/pkg/logx" @@ -36,6 +37,8 @@ type App struct { listener net.Listener // walletConn 是 SendGift 同步扣费依赖。 walletConn *grpc.ClientConn + // activityConn 是 room outbox 事实投递到 activity-service 的 best-effort 通道。 + activityConn *grpc.ClientConn // repository 是 MySQL 持久化实现,保存 meta、command log、snapshot 和 outbox。 repository *mysqlstorage.Repository // redisClose 关闭 Redis client,Redis directory 本身不拥有额外生命周期。 @@ -65,6 +68,11 @@ func New(cfg config.Config) (*App, error) { if err != nil { return nil, err } + activityConn, err := grpc.Dial(cfg.ActivityServiceAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + _ = walletConn.Close() + return nil, err + } startupCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() @@ -72,6 +80,7 @@ func New(cfg config.Config) (*App, error) { // MySQL 是房间恢复的持久来源,启动阶段必须确认连接池可用。 repository, err := mysqlstorage.Open(startupCtx, cfg.MySQLDSN, cfg.MySQLMaxOpenConns, cfg.MySQLMaxIdleConns) if err != nil { + _ = activityConn.Close() _ = walletConn.Close() return nil, err } @@ -80,6 +89,7 @@ func New(cfg config.Config) (*App, error) { // 本地和测试环境可自动建表,线上应通过显式迁移控制结构变更。 if err := repository.Migrate(startupCtx); err != nil { _ = repository.Close() + _ = activityConn.Close() _ = walletConn.Close() return nil, err } @@ -89,6 +99,7 @@ func New(cfg config.Config) (*App, error) { redisClient, err := router.NewRedisClient(startupCtx, cfg.RedisAddr, cfg.RedisPassword, cfg.RedisDB) if err != nil { _ = repository.Close() + _ = activityConn.Close() _ = walletConn.Close() return nil, err } @@ -101,6 +112,7 @@ func New(cfg config.Config) (*App, error) { tencentClient, err := tencentim.NewRESTClient(cfg.TencentIM.RESTConfig()) if err != nil { _ = repository.Close() + _ = activityConn.Close() _ = walletConn.Close() _ = redisClient.Close() return nil, err @@ -119,6 +131,7 @@ func New(cfg config.Config) (*App, error) { PresenceStaleAfter: cfg.PresenceStaleAfter, MicPublishTimeout: cfg.MicPublishTimeout, }, directory, repository, integration.NewGRPCWalletClient(walletConn), roomPublisher, outboxPublisher) + svc.SetEventPublisher(integration.NewActivityOutboxPublisher(activityv1.NewRoomEventConsumerServiceClient(activityConn), time.Second)) server := grpc.NewServer(grpc.UnaryInterceptor(logx.UnaryServerInterceptor("room-service"))) // 命令服务处理房间状态变更,守卫服务给腾讯云 IM 回调或 gateway 做发言和进群校验。 @@ -131,6 +144,7 @@ func New(cfg config.Config) (*App, error) { // listener 在 New 阶段创建,可以把端口占用作为启动失败暴露。 listener, err := net.Listen("tcp", cfg.GRPCAddr) if err != nil { + _ = activityConn.Close() _ = walletConn.Close() _ = repository.Close() _ = redisClient.Close() @@ -144,6 +158,7 @@ func New(cfg config.Config) (*App, error) { service: svc, listener: listener, walletConn: walletConn, + activityConn: activityConn, repository: repository, redisClose: redisClient.Close, health: healthState, @@ -219,6 +234,9 @@ func (a *App) Close() { if a.walletConn != nil { _ = a.walletConn.Close() } + if a.activityConn != nil { + _ = a.activityConn.Close() + } if a.repository != nil { // MySQL 连接池最后释放,保证 GracefulStop 期间仍可完成持久化。 _ = a.repository.Close() diff --git a/services/room-service/internal/config/config.go b/services/room-service/internal/config/config.go index 915958ce..14cb5c1c 100644 --- a/services/room-service/internal/config/config.go +++ b/services/room-service/internal/config/config.go @@ -30,6 +30,8 @@ type Config struct { SnapshotEveryN int64 `yaml:"snapshot_every_n"` // WalletServiceAddr 是 SendGift 同步扣费 gRPC 地址。 WalletServiceAddr string `yaml:"wallet_service_addr"` + // ActivityServiceAddr 是房间事实事件投给 activity-service 的内部 gRPC 地址。 + ActivityServiceAddr string `yaml:"activity_service_addr"` // TencentIM 是腾讯云 IM 群组和房间系统消息的外部集成配置。 TencentIM TencentIMConfig `yaml:"tencent_im"` // MySQLDSN 是 rooms、snapshot、command log 和 outbox 的持久化连接串。 @@ -117,14 +119,15 @@ func (c TencentIMConfig) RESTConfig() tencentim.RESTConfig { func Default() Config { // 默认端口遵守项目 13xxx 约束,MySQL/Redis 指向本地 Docker 暴露端口。 return Config{ - ServiceName: "room-service", - Environment: "local", - NodeID: "room-node-local", - GRPCAddr: ":13001", - LeaseTTL: 10 * time.Second, - RankLimit: 20, - SnapshotEveryN: 1, - WalletServiceAddr: "127.0.0.1:13004", + ServiceName: "room-service", + Environment: "local", + NodeID: "room-node-local", + GRPCAddr: ":13001", + LeaseTTL: 10 * time.Second, + RankLimit: 20, + SnapshotEveryN: 1, + WalletServiceAddr: "127.0.0.1:13004", + ActivityServiceAddr: "127.0.0.1:13006", TencentIM: TencentIMConfig{ Enabled: false, AdminIdentifier: "administrator", @@ -133,7 +136,7 @@ func Default() Config { GroupType: tencentim.DefaultGroupType, RequestTimeout: 5 * time.Second, }, - MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local", + MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC", MySQLMaxOpenConns: 20, MySQLMaxIdleConns: 10, MySQLAutoMigrate: true, @@ -178,6 +181,14 @@ func Normalize(cfg Config) (Config, error) { if cfg.NodeID == "" { cfg.NodeID = cfg.ServiceName } + cfg.WalletServiceAddr = strings.TrimSpace(cfg.WalletServiceAddr) + if cfg.WalletServiceAddr == "" { + cfg.WalletServiceAddr = "127.0.0.1:13004" + } + cfg.ActivityServiceAddr = strings.TrimSpace(cfg.ActivityServiceAddr) + if cfg.ActivityServiceAddr == "" { + cfg.ActivityServiceAddr = "127.0.0.1:13006" + } outboxWorker, err := normalizeOutboxWorkerConfig(cfg.OutboxWorker) if err != nil { return Config{}, err diff --git a/services/room-service/internal/healthcheck/checker.go b/services/room-service/internal/healthcheck/checker.go index a6faec07..433936dd 100644 --- a/services/room-service/internal/healthcheck/checker.go +++ b/services/room-service/internal/healthcheck/checker.go @@ -172,7 +172,7 @@ func (s *State) redisLeaseCheck(ctx context.Context) grpchealth.Check { checkCtx, cancel := context.WithTimeout(ctx, redisBudget) defer cancel() - if err := s.redis.ProbeLease(checkCtx, s.nodeID, time.Now(), redisLeaseTTL); err != nil { + if err := s.redis.ProbeLease(checkCtx, s.nodeID, time.Now().UTC(), redisLeaseTTL); err != nil { // Eval/cjson/写权限异常会直接破坏 owner 仲裁,ready 必须失败。 return grpchealth.Fail("redis_lease", err.Error()) } diff --git a/services/room-service/internal/integration/activity_outbox.go b/services/room-service/internal/integration/activity_outbox.go new file mode 100644 index 00000000..c2dac931 --- /dev/null +++ b/services/room-service/internal/integration/activity_outbox.go @@ -0,0 +1,47 @@ +package integration + +import ( + "context" + "time" + + activityv1 "hyapp.local/api/proto/activity/v1" + roomeventsv1 "hyapp.local/api/proto/events/room/v1" + "hyapp/pkg/appcode" +) + +// ActivityOutboxPublisher 把已经提交的 room outbox 事实转发给 activity-service。 +// 它是 best-effort 桥接:转发失败不回滚 Room Cell,因为房间状态和 command log 已经是权威事实。 +type ActivityOutboxPublisher struct { + client activityv1.RoomEventConsumerServiceClient + timeout time.Duration +} + +// NewActivityOutboxPublisher 创建 room-service 到 activity-service 的事件消费桥。 +// timeout 较短是有意的,避免活动/播报服务慢调用拖住房间命令返回。 +func NewActivityOutboxPublisher(client activityv1.RoomEventConsumerServiceClient, timeout time.Duration) *ActivityOutboxPublisher { + if timeout <= 0 { + timeout = time.Second + } + return &ActivityOutboxPublisher{client: client, timeout: timeout} +} + +// PublishOutboxEvent 发送一条 protobuf room outbox envelope。 +// RequestMeta 使用 envelope event_id 作为 request_id,排查链路时能直接从房间事件定位到活动消费日志。 +func (p *ActivityOutboxPublisher) PublishOutboxEvent(ctx context.Context, envelope *roomeventsv1.EventEnvelope) error { + if p == nil || p.client == nil || envelope == nil { + // 未配置 activity-service 时保持 no-op,保证房间核心链路可独立运行。 + return nil + } + callCtx, cancel := context.WithTimeout(appcode.WithContext(ctx, envelope.GetAppCode()), p.timeout) + defer cancel() + _, err := p.client.ConsumeRoomEvent(callCtx, &activityv1.ConsumeRoomEventRequest{ + Meta: &activityv1.RequestMeta{ + RequestId: envelope.GetEventId(), + Caller: "room-service", + SentAtMs: time.Now().UTC().UnixMilli(), + AppCode: envelope.GetAppCode(), + }, + Envelope: envelope, + }) + return err +} diff --git a/services/room-service/internal/room/outbox/outbox.go b/services/room-service/internal/room/outbox/outbox.go index b02ffb82..6162ddc8 100644 --- a/services/room-service/internal/room/outbox/outbox.go +++ b/services/room-service/internal/room/outbox/outbox.go @@ -37,8 +37,8 @@ type Record struct { Status string // Envelope 是 protobuf 统一信封,body 内是具体事件消息的序列化结果。 Envelope *roomeventsv1.EventEnvelope - // CreatedAt 是事件入库时间,也是待投递扫描的排序依据。 - CreatedAt time.Time + // CreatedAtMS 是事件入库的 UTC 毫秒时间戳,也是待投递扫描的排序依据。 + CreatedAtMS int64 // RetryCount 记录补偿投递失败次数,便于后续告警和退避策略。 RetryCount int // LastError 保存最近一次投递失败原因。 @@ -75,6 +75,6 @@ func Build(roomID string, eventType string, roomVersion int64, occurredAt time.T OccurredAtMs: occurredAt.UnixMilli(), Body: bodyBytes, }, - CreatedAt: occurredAt, + CreatedAtMS: occurredAt.UnixMilli(), }, nil } diff --git a/services/room-service/internal/room/service/create_room.go b/services/room-service/internal/room/service/create_room.go index f7a424e1..202693c7 100644 --- a/services/room-service/internal/room/service/create_room.go +++ b/services/room-service/internal/room/service/create_room.go @@ -201,7 +201,7 @@ func (s *Service) CreateRoom(ctx context.Context, req *roomv1.CreateRoomRequest) Replayable: true, OwnerNodeID: s.nodeID, LeaseToken: lease.LeaseToken, - CreatedAt: now, + CreatedAtMS: now.UnixMilli(), }, OutboxRecords: []outbox.Record{createdEvent}, }); err != nil { diff --git a/services/room-service/internal/room/service/gift.go b/services/room-service/internal/room/service/gift.go index be6a2713..a9779439 100644 --- a/services/room-service/internal/room/service/gift.go +++ b/services/room-service/internal/room/service/gift.go @@ -93,6 +93,8 @@ func (s *Service) SendGift(ctx context.Context, req *roomv1.SendGiftRequest) (*r GiftCount: cmd.GiftCount, GiftValue: heatValue, BillingReceiptId: billing.GetBillingReceiptId(), + VisibleRegionId: roomMeta.VisibleRegionID, + CommandId: cmd.ID(), }) if err != nil { return mutationResult{}, nil, err diff --git a/services/room-service/internal/room/service/outbox_worker.go b/services/room-service/internal/room/service/outbox_worker.go index f072a66f..e22f5589 100644 --- a/services/room-service/internal/room/service/outbox_worker.go +++ b/services/room-service/internal/room/service/outbox_worker.go @@ -100,7 +100,7 @@ func (s *Service) ProcessPendingOutbox(ctx context.Context, options OutboxWorker } // 补偿 worker 先抢占 pending/retryable 事件,再投递,避免多机同时处理同一批。 - records, err := s.repository.ClaimPendingOutbox(ctx, s.nodeID, options.BatchSize, time.Now().Add(options.PublishTimeout)) + records, err := s.repository.ClaimPendingOutbox(ctx, s.nodeID, options.BatchSize, time.Now().UTC().Add(options.PublishTimeout).UnixMilli()) if err != nil { return err } diff --git a/services/room-service/internal/room/service/pipeline.go b/services/room-service/internal/room/service/pipeline.go index 579f2632..dacef1a4 100644 --- a/services/room-service/internal/room/service/pipeline.go +++ b/services/room-service/internal/room/service/pipeline.go @@ -80,13 +80,15 @@ func (s *Service) mutateRoom(ctx context.Context, cmd command.Command, replayabl Replayable: replayable, OwnerNodeID: s.nodeID, LeaseToken: lease.LeaseToken, - CreatedAt: now, + CreatedAtMS: now.UnixMilli(), }, OutboxRecords: outboxRecords, RoomStatus: result.roomStatus, }); err != nil { return nil, err } + // 保存已提交 outbox 记录,出 Cell 锁后再通知 activity-service;外部服务慢调用不能占住房间串行执行队列。 + result.outboxRecords = outboxRecords // 持久化成功后再替换内存状态,避免内存提交领先于恢复来源。 current.ReplaceWith(nextState) @@ -110,7 +112,7 @@ func (s *Service) mutateRoom(ctx context.Context, cmd command.Command, replayabl Replayable: false, OwnerNodeID: s.nodeID, LeaseToken: lease.LeaseToken, - CreatedAt: now, + CreatedAtMS: now.UnixMilli(), }, }); err != nil { return nil, err @@ -136,6 +138,8 @@ func (s *Service) mutateRoom(ctx context.Context, cmd command.Command, replayabl s.projectRoomListBestEffort(ctx, result.snapshot) // 当前房间恢复读模型同样最终一致;权威校验仍以 Room Cell 快照为准。 s.projectRoomPresenceBestEffort(ctx, result.snapshot) + // activity-service 消费的是已经落库的 room outbox 事实,失败只记日志;outbox 补偿链路仍保留房间 IM 投递能力。 + s.publishRoomEventsBestEffort(ctx, result.outboxRecords) } if result.applied && result.syncEvent != nil { @@ -159,6 +163,27 @@ func (s *Service) mutateRoom(ctx context.Context, cmd command.Command, replayabl return result, nil } +func (s *Service) publishRoomEventsBestEffort(ctx context.Context, records []outbox.Record) { + if s == nil || s.eventPublisher == nil || len(records) == 0 { + return + } + for _, record := range records { + if record.Envelope == nil { + // 只有 protobuf envelope 能跨服务消费;没有 envelope 的历史/本地事件仍只参与原 outbox 投递。 + continue + } + if err := s.eventPublisher.PublishOutboxEvent(ctx, record.Envelope); err != nil { + logx.Warn(ctx, "room_event_consumer_publish_failed", + slog.String("node_id", s.nodeID), + slog.String("event_id", record.EventID), + slog.String("event_type", record.EventType), + slog.String("room_id", record.RoomID), + slog.String("error", err.Error()), + ) + } + } +} + func (s *Service) commandPayloadForIdempotency(ctx context.Context, cmd command.Command) ([]byte, bool, error) { payload, err := command.Serialize(cmd) if err != nil { diff --git a/services/room-service/internal/room/service/repository.go b/services/room-service/internal/room/service/repository.go index 2cfadce1..cd0a0053 100644 --- a/services/room-service/internal/room/service/repository.go +++ b/services/room-service/internal/room/service/repository.go @@ -3,7 +3,6 @@ package service import ( "context" - "time" "hyapp/services/room-service/internal/room/outbox" ) @@ -50,8 +49,8 @@ type CommandRecord struct { OwnerNodeID string // LeaseToken 是提交命令前通过 Redis fencing 校验的 lease token。 LeaseToken string - // CreatedAt 是命令成功落盘时间。 - CreatedAt time.Time + // CreatedAtMS 是命令成功落盘的 UTC 毫秒时间戳,恢复和审计不依赖数据库时区。 + CreatedAtMS int64 } // MutationCommit 表达一次 Room Cell 命令需要一起提交的持久化副作用。 @@ -74,8 +73,8 @@ type SnapshotRecord struct { RoomVersion int64 // Payload 是 roomv1.RoomSnapshot 的 protobuf 序列化结果。 Payload []byte - // CreatedAt 是快照生成时间。 - CreatedAt time.Time + // CreatedAtMS 是快照生成的 UTC 毫秒时间戳。 + CreatedAtMS int64 } // RoomListEntry 是 room_list_entries 的领域投影,只保存列表卡片所需字段。 @@ -188,7 +187,7 @@ type Repository interface { // ListPendingOutbox 扫描待补偿投递事件。 ListPendingOutbox(ctx context.Context, limit int) ([]outbox.Record, error) // ClaimPendingOutbox 抢占一批待投递事件,避免多 worker 同时投递同一批。 - ClaimPendingOutbox(ctx context.Context, workerID string, limit int, lockUntil time.Time) ([]outbox.Record, error) + ClaimPendingOutbox(ctx context.Context, workerID string, limit int, lockUntilMS int64) ([]outbox.Record, error) // MarkOutboxDelivered 标记事件已经投递成功。 MarkOutboxDelivered(ctx context.Context, eventID string) error // MarkOutboxFailed 记录一次投递失败并转为 retryable 状态等待重试。 diff --git a/services/room-service/internal/room/service/service.go b/services/room-service/internal/room/service/service.go index 7845200c..540a4865 100644 --- a/services/room-service/internal/room/service/service.go +++ b/services/room-service/internal/room/service/service.go @@ -12,6 +12,7 @@ import ( "hyapp/pkg/tencentim" "hyapp/services/room-service/internal/integration" "hyapp/services/room-service/internal/room/cell" + "hyapp/services/room-service/internal/room/outbox" "hyapp/services/room-service/internal/router" ) @@ -59,6 +60,8 @@ type Service struct { syncPublisher integration.RoomEventPublisher // outboxPublisher 是补偿 worker 对外部消费者的异步投递抽象。 outboxPublisher integration.OutboxPublisher + // eventPublisher 是命令提交后的房间事实消费者投递通道,不参与 Room Cell 提交回滚。 + eventPublisher integration.OutboxPublisher // draining 表示当前节点正在下线,只允许已经进入执行链路的命令收尾。 draining atomic.Bool @@ -92,6 +95,8 @@ type mutationResult struct { commandPayload []byte // syncEvent 是需要同步推给腾讯云 IM 的低时延房间系统事件。 syncEvent *tencentim.RoomEvent + // outboxRecords 是本次命令已经持久化的房间事实,提交后可投给 activity 等外部消费者。 + outboxRecords []outbox.Record // roomStatus 非空时代表命令提交时需要同步更新 rooms 和列表投影生命周期状态。 roomStatus string } @@ -145,6 +150,13 @@ func New(cfg Config, directory router.Directory, repository Repository, wallet i } } +// SetEventPublisher 注入 room outbox 事实消费者;失败只记录日志,不改变房间主链路。 +func (s *Service) SetEventPublisher(publisher integration.OutboxPublisher) { + if s != nil { + s.eventPublisher = publisher + } +} + // HealthCheck 校验 room-service 核心状态 owner 和持久化依赖已经完成装配。 func (s *Service) HealthCheck() error { if s == nil { diff --git a/services/room-service/internal/room/service/service_test.go b/services/room-service/internal/room/service/service_test.go index 86ac6e55..f75f47e8 100644 --- a/services/room-service/internal/room/service/service_test.go +++ b/services/room-service/internal/room/service/service_test.go @@ -1844,14 +1844,14 @@ func TestOutboxClaimPreventsDuplicateWorkersAndRetriesAfterFailure(t *testing.T) t.Fatalf("SaveOutbox failed: %v", err) } - claimedA, err := repository.ClaimPendingOutbox(ctx, "worker-a", 10, time.Now().Add(time.Minute)) + claimedA, err := repository.ClaimPendingOutbox(ctx, "worker-a", 10, time.Now().Add(time.Minute).UnixMilli()) if err != nil { t.Fatalf("worker-a claim failed: %v", err) } if len(claimedA) != 1 || claimedA[0].Status != outbox.StatusDelivering || claimedA[0].WorkerID != "worker-a" { t.Fatalf("worker-a should claim one delivering record: %+v", claimedA) } - claimedB, err := repository.ClaimPendingOutbox(ctx, "worker-b", 10, time.Now().Add(time.Minute)) + claimedB, err := repository.ClaimPendingOutbox(ctx, "worker-b", 10, time.Now().Add(time.Minute).UnixMilli()) if err != nil { t.Fatalf("worker-b claim failed: %v", err) } @@ -1862,7 +1862,7 @@ func TestOutboxClaimPreventsDuplicateWorkersAndRetriesAfterFailure(t *testing.T) if err := repository.MarkOutboxFailed(ctx, record.EventID, "temporary failure"); err != nil { t.Fatalf("MarkOutboxFailed failed: %v", err) } - claimedRetry, err := repository.ClaimPendingOutbox(ctx, "worker-b", 10, time.Now().Add(time.Minute)) + claimedRetry, err := repository.ClaimPendingOutbox(ctx, "worker-b", 10, time.Now().Add(time.Minute).UnixMilli()) if err != nil { t.Fatalf("retry claim failed: %v", err) } diff --git a/services/room-service/internal/room/service/snapshot.go b/services/room-service/internal/room/service/snapshot.go index fd2967a9..3a746eb1 100644 --- a/services/room-service/internal/room/service/snapshot.go +++ b/services/room-service/internal/room/service/snapshot.go @@ -58,7 +58,7 @@ func (s *Service) persistSnapshot(ctx context.Context, snapshot *roomv1.RoomSnap RoomID: snapshot.GetRoomId(), RoomVersion: snapshot.GetVersion(), Payload: payload, - CreatedAt: s.clock.Now(), + CreatedAtMS: s.clock.Now().UnixMilli(), }) } diff --git a/services/room-service/internal/storage/mysql/repository.go b/services/room-service/internal/storage/mysql/repository.go index e24d1c26..50316df8 100644 --- a/services/room-service/internal/storage/mysql/repository.go +++ b/services/room-service/internal/storage/mysql/repository.go @@ -79,8 +79,8 @@ func (r *Repository) Migrate(ctx context.Context) error { mode VARCHAR(64) NOT NULL, status VARCHAR(32) NOT NULL, visible_region_id BIGINT NOT NULL DEFAULT 0, - created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, PRIMARY KEY (app_code, room_id), UNIQUE KEY uk_rooms_short_id (app_code, room_short_id), UNIQUE KEY uk_rooms_owner_user (app_code, owner_user_id), @@ -130,8 +130,8 @@ func (r *Repository) Migrate(ctx context.Context) error { room_id VARCHAR(64) NOT NULL, room_version BIGINT NOT NULL, payload LONGBLOB NOT NULL, - created_at TIMESTAMP(3) NOT NULL, - updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + created_at_ms BIGINT NOT NULL, + updated_at_ms BIGINT NOT NULL, PRIMARY KEY (app_code, room_id), INDEX idx_room_snapshots_version (app_code, room_id, room_version) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`, @@ -146,7 +146,7 @@ func (r *Repository) Migrate(ctx context.Context) error { lease_token VARCHAR(128) NOT NULL DEFAULT '', payload LONGBLOB NOT NULL, replayable BOOLEAN NOT NULL, - created_at TIMESTAMP(3) NOT NULL, + created_at_ms BIGINT NOT NULL, UNIQUE KEY uk_room_command (app_code, room_id, command_id), KEY idx_room_command_replay (app_code, room_id, room_version) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`, @@ -157,15 +157,15 @@ func (r *Repository) Migrate(ctx context.Context) error { room_id VARCHAR(64) NOT NULL, status VARCHAR(32) NOT NULL, worker_id VARCHAR(128) NOT NULL DEFAULT '', - lock_until TIMESTAMP(3) NULL, + lock_until_ms BIGINT NULL, envelope LONGBLOB NOT NULL, - created_at TIMESTAMP(3) NOT NULL, + created_at_ms BIGINT NOT NULL, retry_count INT NOT NULL DEFAULT 0, last_error TEXT NULL, - updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + updated_at_ms BIGINT NOT NULL, PRIMARY KEY (app_code, event_id), - KEY idx_room_outbox_pending (app_code, status, created_at), - KEY idx_room_outbox_claim (app_code, status, lock_until, created_at) + KEY idx_room_outbox_pending (app_code, status, created_at_ms), + KEY idx_room_outbox_claim (app_code, status, lock_until_ms, created_at_ms) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`, `ALTER TABLE rooms MODIFY COLUMN app_code VARCHAR(32) NOT NULL`, `ALTER TABLE room_list_entries MODIFY COLUMN app_code VARCHAR(32) NOT NULL`, @@ -189,9 +189,10 @@ func (r *Repository) Migrate(ctx context.Context) error { func (r *Repository) SaveRoomMeta(ctx context.Context, meta roomservice.RoomMeta) error { // rooms 表只保存恢复初始状态需要的元数据,实时态以 snapshot/command log 为准。 appCode := normalizedRecordAppCode(ctx, meta.AppCode) + nowMS := time.Now().UTC().UnixMilli() _, err := r.db.ExecContext(ctx, - `INSERT INTO rooms (app_code, room_id, room_short_id, owner_user_id, host_user_id, seat_count, mode, status, visible_region_id) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, + `INSERT INTO rooms (app_code, room_id, room_short_id, owner_user_id, host_user_id, seat_count, mode, status, visible_region_id, created_at_ms, updated_at_ms) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, appCode, meta.RoomID, meta.RoomShortID, @@ -201,6 +202,8 @@ func (r *Repository) SaveRoomMeta(ctx context.Context, meta roomservice.RoomMeta meta.Mode, meta.Status, meta.VisibleRegionID, + nowMS, + nowMS, ) return mapRoomMetaDuplicateError(err) @@ -258,7 +261,7 @@ func (r *Repository) GetRoomMetaByOwner(ctx context.Context, ownerUserID int64) func (r *Repository) GetCommand(ctx context.Context, roomID string, commandID string) (roomservice.CommandRecord, bool, error) { // 幂等检查只看 command log,只有成功提交过的命令才算 seen。 row := r.db.QueryRowContext(ctx, - `SELECT app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at + `SELECT app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at_ms FROM room_command_log WHERE app_code = ? AND room_id = ? AND command_id = ? LIMIT 1`, @@ -268,7 +271,7 @@ func (r *Repository) GetCommand(ctx context.Context, roomID string, commandID st ) var record roomservice.CommandRecord - if err := row.Scan(&record.AppCode, &record.RoomID, &record.RoomVersion, &record.CommandID, &record.CommandType, &record.OwnerNodeID, &record.LeaseToken, &record.Payload, &record.Replayable, &record.CreatedAt); err != nil { + if err := row.Scan(&record.AppCode, &record.RoomID, &record.RoomVersion, &record.CommandID, &record.CommandType, &record.OwnerNodeID, &record.LeaseToken, &record.Payload, &record.Replayable, &record.CreatedAtMS); err != nil { if errors.Is(err, sql.ErrNoRows) { // 没有命令日志表示本命令尚未成功提交。 return roomservice.CommandRecord{}, false, nil @@ -285,7 +288,7 @@ func (r *Repository) SaveCommand(ctx context.Context, record roomservice.Command // ON DUPLICATE KEY 保证重复命令写入不会破坏已提交记录。 appCode := normalizedRecordAppCode(ctx, record.AppCode) _, err := r.db.ExecContext(ctx, - `INSERT INTO room_command_log (app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at) + `INSERT INTO room_command_log (app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE command_id = command_id`, appCode, @@ -297,7 +300,7 @@ func (r *Repository) SaveCommand(ctx context.Context, record roomservice.Command record.LeaseToken, record.Payload, record.Replayable, - record.CreatedAt, + record.CreatedAtMS, ) return err @@ -312,7 +315,7 @@ func (r *Repository) SaveMutation(ctx context.Context, commit roomservice.Mutati } if _, err := tx.ExecContext(ctx, - `INSERT INTO room_command_log (app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at) + `INSERT INTO room_command_log (app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE command_id = command_id`, appCode, @@ -324,7 +327,7 @@ func (r *Repository) SaveMutation(ctx context.Context, commit roomservice.Mutati commit.Command.LeaseToken, commit.Command.Payload, commit.Command.Replayable, - commit.Command.CreatedAt, + commit.Command.CreatedAtMS, ); err != nil { _ = tx.Rollback() return err @@ -341,8 +344,8 @@ func (r *Repository) SaveMutation(ctx context.Context, commit roomservice.Mutati return err } if _, err := tx.ExecContext(ctx, - `INSERT INTO room_outbox (app_code, event_id, event_type, room_id, status, envelope, created_at, retry_count, last_error) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + `INSERT INTO room_outbox (app_code, event_id, event_type, room_id, status, envelope, created_at_ms, retry_count, last_error, updated_at_ms) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE event_id = event_id`, record.AppCode, record.EventID, @@ -350,9 +353,10 @@ func (r *Repository) SaveMutation(ctx context.Context, commit roomservice.Mutati record.RoomID, record.Status, envelopeBytes, - record.CreatedAt, + record.CreatedAtMS, record.RetryCount, nullableString(record.LastError), + record.CreatedAtMS, ); err != nil { _ = tx.Rollback() return err @@ -362,9 +366,10 @@ func (r *Repository) SaveMutation(ctx context.Context, commit roomservice.Mutati if strings.TrimSpace(commit.RoomStatus) != "" { if _, err := tx.ExecContext(ctx, `UPDATE rooms - SET status = ? + SET status = ?, updated_at_ms = ? WHERE app_code = ? AND room_id = ?`, commit.RoomStatus, + commit.Command.CreatedAtMS, appCode, commit.Command.RoomID, ); err != nil { @@ -376,7 +381,7 @@ func (r *Repository) SaveMutation(ctx context.Context, commit roomservice.Mutati SET status = ?, updated_at_ms = ? WHERE app_code = ? AND room_id = ?`, commit.RoomStatus, - commit.Command.CreatedAt.UnixMilli(), + commit.Command.CreatedAtMS, appCode, commit.Command.RoomID, ); err != nil { @@ -392,7 +397,7 @@ func (r *Repository) SaveMutation(ctx context.Context, commit roomservice.Mutati func (r *Repository) ListCommandsAfter(ctx context.Context, roomID string, roomVersion int64) ([]roomservice.CommandRecord, error) { // 恢复必须按 room_version 再按自增 id 排序,确保同版本异常数据也有稳定顺序。 rows, err := r.db.QueryContext(ctx, - `SELECT app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at + `SELECT app_code, room_id, room_version, command_id, command_type, owner_node_id, lease_token, payload, replayable, created_at_ms FROM room_command_log WHERE app_code = ? AND room_id = ? AND room_version > ? ORDER BY room_version ASC, id ASC`, @@ -409,7 +414,7 @@ func (r *Repository) ListCommandsAfter(ctx context.Context, roomID string, roomV for rows.Next() { // payload 保持原始字节,领域层根据 command_type 反序列化。 var record roomservice.CommandRecord - if err := rows.Scan(&record.AppCode, &record.RoomID, &record.RoomVersion, &record.CommandID, &record.CommandType, &record.OwnerNodeID, &record.LeaseToken, &record.Payload, &record.Replayable, &record.CreatedAt); err != nil { + if err := rows.Scan(&record.AppCode, &record.RoomID, &record.RoomVersion, &record.CommandID, &record.CommandType, &record.OwnerNodeID, &record.LeaseToken, &record.Payload, &record.Replayable, &record.CreatedAtMS); err != nil { return nil, err } @@ -429,17 +434,19 @@ func (r *Repository) SaveSnapshot(ctx context.Context, snapshot roomservice.Snap // 快照按 room_id 保留最新一条,版本更旧的写入不会覆盖较新的恢复来源。 appCode := normalizedRecordAppCode(ctx, snapshot.AppCode) _, err := r.db.ExecContext(ctx, - `INSERT INTO room_snapshots (app_code, room_id, room_version, payload, created_at) - VALUES (?, ?, ?, ?, ?) + `INSERT INTO room_snapshots (app_code, room_id, room_version, payload, created_at_ms, updated_at_ms) + VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE room_version = IF(VALUES(room_version) >= room_version, VALUES(room_version), room_version), payload = IF(VALUES(room_version) >= room_version, VALUES(payload), payload), - created_at = IF(VALUES(room_version) >= room_version, VALUES(created_at), created_at)`, + created_at_ms = IF(VALUES(room_version) >= room_version, VALUES(created_at_ms), created_at_ms), + updated_at_ms = IF(VALUES(room_version) >= room_version, VALUES(updated_at_ms), updated_at_ms)`, appCode, snapshot.RoomID, snapshot.RoomVersion, snapshot.Payload, - snapshot.CreatedAt, + snapshot.CreatedAtMS, + snapshot.CreatedAtMS, ) return err @@ -449,7 +456,7 @@ func (r *Repository) SaveSnapshot(ctx context.Context, snapshot roomservice.Snap func (r *Repository) GetLatestSnapshot(ctx context.Context, roomID string) (roomservice.SnapshotRecord, bool, error) { // room_snapshots 主键是 room_id,因此查询结果最多一条。 row := r.db.QueryRowContext(ctx, - `SELECT app_code, room_id, room_version, payload, created_at + `SELECT app_code, room_id, room_version, payload, created_at_ms FROM room_snapshots WHERE app_code = ? AND room_id = ?`, appcode.FromContext(ctx), @@ -457,7 +464,7 @@ func (r *Repository) GetLatestSnapshot(ctx context.Context, roomID string) (room ) var snapshot roomservice.SnapshotRecord - if err := row.Scan(&snapshot.AppCode, &snapshot.RoomID, &snapshot.RoomVersion, &snapshot.Payload, &snapshot.CreatedAt); err != nil { + if err := row.Scan(&snapshot.AppCode, &snapshot.RoomID, &snapshot.RoomVersion, &snapshot.Payload, &snapshot.CreatedAtMS); err != nil { if errors.Is(err, sql.ErrNoRows) { // 没有快照时上层会从 RoomMeta 和 command log 从头恢复。 return roomservice.SnapshotRecord{}, false, nil @@ -495,8 +502,8 @@ func (r *Repository) SaveOutbox(ctx context.Context, records []outbox.Record) er } if _, err := tx.ExecContext(ctx, - `INSERT INTO room_outbox (app_code, event_id, event_type, room_id, status, envelope, created_at, retry_count, last_error) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + `INSERT INTO room_outbox (app_code, event_id, event_type, room_id, status, envelope, created_at_ms, retry_count, last_error, updated_at_ms) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE event_id = event_id`, record.AppCode, record.EventID, @@ -504,9 +511,10 @@ func (r *Repository) SaveOutbox(ctx context.Context, records []outbox.Record) er record.RoomID, record.Status, envelopeBytes, - record.CreatedAt, + record.CreatedAtMS, record.RetryCount, nullableString(record.LastError), + record.CreatedAtMS, ); err != nil { // 任一事件失败就回滚整批,避免 GiftSent/HeatChanged/RankChanged 部分缺失。 _ = tx.Rollback() @@ -527,10 +535,10 @@ func (r *Repository) ListPendingOutbox(ctx context.Context, limit int) ([]outbox // 按创建时间顺序扫描 pending,尽量保持事件投递顺序。 rows, err := r.db.QueryContext(ctx, - `SELECT app_code, event_id, event_type, room_id, status, worker_id, lock_until, envelope, created_at, retry_count, COALESCE(last_error, '') + `SELECT app_code, event_id, event_type, room_id, status, worker_id, lock_until_ms, envelope, created_at_ms, retry_count, COALESCE(last_error, '') FROM room_outbox WHERE app_code = ? AND status IN (?, ?) - ORDER BY created_at ASC + ORDER BY created_at_ms ASC LIMIT ?`, appcode.FromContext(ctx), outbox.StatusPending, @@ -547,12 +555,12 @@ func (r *Repository) ListPendingOutbox(ctx context.Context, limit int) ([]outbox // 每条 outbox 记录恢复 envelope,发布器只消费 protobuf 信封。 var envelopeBytes []byte var record outbox.Record - var lockUntil sql.NullTime - if err := rows.Scan(&record.AppCode, &record.EventID, &record.EventType, &record.RoomID, &record.Status, &record.WorkerID, &lockUntil, &envelopeBytes, &record.CreatedAt, &record.RetryCount, &record.LastError); err != nil { + var lockUntil sql.NullInt64 + if err := rows.Scan(&record.AppCode, &record.EventID, &record.EventType, &record.RoomID, &record.Status, &record.WorkerID, &lockUntil, &envelopeBytes, &record.CreatedAtMS, &record.RetryCount, &record.LastError); err != nil { return nil, err } if lockUntil.Valid { - record.LockUntilMS = lockUntil.Time.UnixMilli() + record.LockUntilMS = lockUntil.Int64 } var envelope roomeventsv1.EventEnvelope @@ -574,7 +582,7 @@ func (r *Repository) ListPendingOutbox(ctx context.Context, limit int) ([]outbox } // ClaimPendingOutbox 抢占一批待投递事件,避免多 worker 同时投递同一批。 -func (r *Repository) ClaimPendingOutbox(ctx context.Context, workerID string, limit int, lockUntil time.Time) ([]outbox.Record, error) { +func (r *Repository) ClaimPendingOutbox(ctx context.Context, workerID string, limit int, lockUntilMS int64) ([]outbox.Record, error) { if limit <= 0 { limit = 100 } @@ -587,23 +595,23 @@ func (r *Repository) ClaimPendingOutbox(ctx context.Context, workerID string, li return nil, err } - now := time.Now().UTC() + nowMS := time.Now().UTC().UnixMilli() rows, err := tx.QueryContext(ctx, - `SELECT app_code, event_id, event_type, room_id, status, worker_id, lock_until, envelope, created_at, retry_count, COALESCE(last_error, '') + `SELECT app_code, event_id, event_type, room_id, status, worker_id, lock_until_ms, envelope, created_at_ms, retry_count, COALESCE(last_error, '') FROM room_outbox WHERE app_code = ? AND ( status IN (?, ?) - OR (status = ? AND lock_until IS NOT NULL AND lock_until <= ?) + OR (status = ? AND lock_until_ms IS NOT NULL AND lock_until_ms <= ?) ) - ORDER BY created_at ASC + ORDER BY created_at_ms ASC LIMIT ? FOR UPDATE SKIP LOCKED`, appcode.FromContext(ctx), outbox.StatusPending, outbox.StatusRetryable, outbox.StatusDelivering, - now, + nowMS, limit, ) if err != nil { @@ -616,14 +624,14 @@ func (r *Repository) ClaimPendingOutbox(ctx context.Context, workerID string, li for rows.Next() { var envelopeBytes []byte var record outbox.Record - var lockUntilValue sql.NullTime - if err := rows.Scan(&record.AppCode, &record.EventID, &record.EventType, &record.RoomID, &record.Status, &record.WorkerID, &lockUntilValue, &envelopeBytes, &record.CreatedAt, &record.RetryCount, &record.LastError); err != nil { + var lockUntilValue sql.NullInt64 + if err := rows.Scan(&record.AppCode, &record.EventID, &record.EventType, &record.RoomID, &record.Status, &record.WorkerID, &lockUntilValue, &envelopeBytes, &record.CreatedAtMS, &record.RetryCount, &record.LastError); err != nil { _ = rows.Close() _ = tx.Rollback() return nil, err } if lockUntilValue.Valid { - record.LockUntilMS = lockUntilValue.Time.UnixMilli() + record.LockUntilMS = lockUntilValue.Int64 } var envelope roomeventsv1.EventEnvelope @@ -650,11 +658,12 @@ func (r *Repository) ClaimPendingOutbox(ctx context.Context, workerID string, li for _, eventID := range eventIDs { if _, err := tx.ExecContext(ctx, `UPDATE room_outbox - SET status = ?, worker_id = ?, lock_until = ? + SET status = ?, worker_id = ?, lock_until_ms = ?, updated_at_ms = ? WHERE app_code = ? AND event_id = ?`, outbox.StatusDelivering, workerID, - lockUntil, + lockUntilMS, + nowMS, appcode.FromContext(ctx), eventID, ); err != nil { @@ -670,7 +679,7 @@ func (r *Repository) ClaimPendingOutbox(ctx context.Context, workerID string, li for index := range records { records[index].Status = outbox.StatusDelivering records[index].WorkerID = workerID - records[index].LockUntilMS = lockUntil.UnixMilli() + records[index].LockUntilMS = lockUntilMS } return records, nil @@ -681,9 +690,10 @@ func (r *Repository) MarkOutboxDelivered(ctx context.Context, eventID string) er // 成功后清空 last_error,后续扫描不再返回该事件。 _, err := r.db.ExecContext(ctx, `UPDATE room_outbox - SET status = ?, worker_id = '', lock_until = NULL, last_error = NULL + SET status = ?, worker_id = '', lock_until_ms = NULL, last_error = NULL, updated_at_ms = ? WHERE app_code = ? AND event_id = ?`, outbox.StatusDelivered, + time.Now().UTC().UnixMilli(), appcode.FromContext(ctx), eventID, ) @@ -696,10 +706,11 @@ func (r *Repository) MarkOutboxFailed(ctx context.Context, eventID string, lastE // 失败转入 retryable,worker 下一轮可重新抢占。 _, err := r.db.ExecContext(ctx, `UPDATE room_outbox - SET status = ?, worker_id = '', lock_until = NULL, retry_count = retry_count + 1, last_error = ? + SET status = ?, worker_id = '', lock_until_ms = NULL, retry_count = retry_count + 1, last_error = ?, updated_at_ms = ? WHERE app_code = ? AND event_id = ?`, outbox.StatusRetryable, lastErr, + time.Now().UTC().UnixMilli(), appcode.FromContext(ctx), eventID, ) diff --git a/services/room-service/internal/testutil/mysqltest/mysqltest.go b/services/room-service/internal/testutil/mysqltest/mysqltest.go index b74f1833..e8794fec 100644 --- a/services/room-service/internal/testutil/mysqltest/mysqltest.go +++ b/services/room-service/internal/testutil/mysqltest/mysqltest.go @@ -68,22 +68,22 @@ func (r *Repository) OutboxRecord(eventID string) (outbox.Record, bool) { r.t.Helper() row := r.schema.DB.QueryRowContext(context.Background(), ` - SELECT app_code, event_id, event_type, room_id, status, worker_id, lock_until, envelope, created_at, retry_count, COALESCE(last_error, '') + SELECT app_code, event_id, event_type, room_id, status, worker_id, lock_until_ms, envelope, created_at_ms, retry_count, COALESCE(last_error, '') FROM room_outbox WHERE app_code = ? AND event_id = ? `, appcode.Default, eventID) var envelopeBytes []byte var record outbox.Record - var lockUntil sql.NullTime - if err := row.Scan(&record.AppCode, &record.EventID, &record.EventType, &record.RoomID, &record.Status, &record.WorkerID, &lockUntil, &envelopeBytes, &record.CreatedAt, &record.RetryCount, &record.LastError); err != nil { + var lockUntil sql.NullInt64 + if err := row.Scan(&record.AppCode, &record.EventID, &record.EventType, &record.RoomID, &record.Status, &record.WorkerID, &lockUntil, &envelopeBytes, &record.CreatedAtMS, &record.RetryCount, &record.LastError); err != nil { if err == sql.ErrNoRows { return outbox.Record{}, false } r.t.Fatalf("query room outbox record failed: %v", err) } if lockUntil.Valid { - record.LockUntilMS = lockUntil.Time.UnixMilli() + record.LockUntilMS = lockUntil.Int64 } var envelope roomeventsv1.EventEnvelope diff --git a/services/user-service/Dockerfile b/services/user-service/Dockerfile index 2ef64b8d..a4a75c15 100644 --- a/services/user-service/Dockerfile +++ b/services/user-service/Dockerfile @@ -13,6 +13,8 @@ RUN GOWORK=off CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/grpc-healt FROM alpine:3.20 +ENV TZ=UTC + WORKDIR /app RUN apk add --no-cache ca-certificates && adduser -D -g '' appuser diff --git a/services/user-service/configs/config.docker.yaml b/services/user-service/configs/config.docker.yaml index 0ce36c27..1583ee7f 100644 --- a/services/user-service/configs/config.docker.yaml +++ b/services/user-service/configs/config.docker.yaml @@ -8,7 +8,7 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13005" -mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=UTC" mysql_auto_migrate: false id_generator: node_id: 1 @@ -24,12 +24,12 @@ third_party: - "google.com" invite_recharge_worker: enabled: true - wallet_mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local" + wallet_mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC" poll_interval_sec: 5 batch_size: 100 mic_time_worker: enabled: true - room_mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local" + room_mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC" poll_interval_sec: 5 batch_size: 100 login_risk: diff --git a/services/user-service/configs/config.tencent.example.yaml b/services/user-service/configs/config.tencent.example.yaml index ca97259c..77335d6e 100644 --- a/services/user-service/configs/config.tencent.example.yaml +++ b/services/user-service/configs/config.tencent.example.yaml @@ -8,7 +8,7 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13005" -mysql_dsn: "${TENCENT_MYSQL_USER_DSN}" +mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=UTC&tls=false" mysql_auto_migrate: false id_generator: node_id: 1 @@ -24,12 +24,12 @@ third_party: - "google.com" invite_recharge_worker: enabled: true - wallet_mysql_dsn: "${TENCENT_MYSQL_WALLET_DSN}" + wallet_mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC&tls=false" poll_interval_sec: 5 batch_size: 100 mic_time_worker: enabled: true - room_mysql_dsn: "${TENCENT_MYSQL_ROOM_DSN}" + room_mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC&tls=false" poll_interval_sec: 5 batch_size: 100 login_risk: diff --git a/services/user-service/configs/config.yaml b/services/user-service/configs/config.yaml index 7f2985d2..b4fbaf96 100644 --- a/services/user-service/configs/config.yaml +++ b/services/user-service/configs/config.yaml @@ -8,7 +8,7 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13005" -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=UTC" mysql_auto_migrate: false id_generator: node_id: 1 @@ -24,12 +24,12 @@ third_party: - "google.com" invite_recharge_worker: enabled: true - wallet_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local" + wallet_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC" poll_interval_sec: 5 batch_size: 100 mic_time_worker: enabled: true - room_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local" + room_mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC" poll_interval_sec: 5 batch_size: 100 login_risk: diff --git a/services/user-service/internal/config/config.go b/services/user-service/internal/config/config.go index a80f3975..cdbffb8a 100644 --- a/services/user-service/internal/config/config.go +++ b/services/user-service/internal/config/config.go @@ -132,7 +132,7 @@ func Default() Config { NodeID: "user-local", Environment: "local", GRPCAddr: ":13005", - MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=Local", + MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=UTC", MySQLAutoMigrate: false, IDGenerator: IDGeneratorConfig{ NodeID: 1, @@ -149,13 +149,13 @@ func Default() Config { }, InviteRechargeWorker: InviteRechargeWorkerConfig{ Enabled: true, - WalletMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local", + WalletMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC", PollIntervalSec: 5, BatchSize: 100, }, MicTimeWorker: MicTimeWorkerConfig{ Enabled: true, - RoomMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local", + RoomMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=UTC", PollIntervalSec: 5, BatchSize: 100, }, diff --git a/services/user-service/internal/storage/mysql/auth/display_sequence.go b/services/user-service/internal/storage/mysql/auth/display_sequence.go index 186eb386..34e74a38 100644 --- a/services/user-service/internal/storage/mysql/auth/display_sequence.go +++ b/services/user-service/internal/storage/mysql/auth/display_sequence.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "time" "hyapp/pkg/appcode" ) @@ -31,14 +32,14 @@ func (r *Repository) AllocateDisplayUserID(ctx context.Context, appCode string) next = firstDisplayUserID _, err = tx.ExecContext(ctx, ` INSERT INTO display_user_id_sequences (app_code, next_value, updated_at_ms) - VALUES (?, ?, 0) - `, normalized, next+1) + VALUES (?, ?, ?) + `, normalized, next+1, time.Now().UTC().UnixMilli()) } else if err == nil { _, err = tx.ExecContext(ctx, ` UPDATE display_user_id_sequences - SET next_value = ?, updated_at_ms = CAST(UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000 AS UNSIGNED) + SET next_value = ?, updated_at_ms = ? WHERE app_code = ? - `, next+1, normalized) + `, next+1, time.Now().UTC().UnixMilli(), normalized) } if err != nil { return "", err diff --git a/services/user-service/internal/storage/mysql/mictime/room_outbox_reader.go b/services/user-service/internal/storage/mysql/mictime/room_outbox_reader.go index a428fd0f..f7e46bc7 100644 --- a/services/user-service/internal/storage/mysql/mictime/room_outbox_reader.go +++ b/services/user-service/internal/storage/mysql/mictime/room_outbox_reader.go @@ -3,7 +3,6 @@ package mictime import ( "context" "database/sql" - "time" "google.golang.org/protobuf/proto" roomeventsv1 "hyapp.local/api/proto/events/room/v1" @@ -30,15 +29,14 @@ func (r *RoomOutboxReader) ListRoomMicEventsAfter(ctx context.Context, cursor mi if batchSize <= 0 { batchSize = 100 } - createdAfter := time.UnixMilli(cursor.CreatedAtMs) rows, err := r.db.QueryContext(ctx, ` - SELECT event_id, envelope, created_at + SELECT event_id, envelope, created_at_ms FROM room_outbox WHERE event_type = ? - AND (created_at > ? OR (created_at = ? AND event_id > ?)) - ORDER BY created_at ASC, event_id ASC + AND (created_at_ms > ? OR (created_at_ms = ? AND event_id > ?)) + ORDER BY created_at_ms ASC, event_id ASC LIMIT ? - `, mictimedomain.RoomMicChangedEventType, createdAfter, createdAfter, cursor.EventID, batchSize) + `, mictimedomain.RoomMicChangedEventType, cursor.CreatedAtMs, cursor.CreatedAtMs, cursor.EventID, batchSize) if err != nil { return nil, err } @@ -48,8 +46,8 @@ func (r *RoomOutboxReader) ListRoomMicEventsAfter(ctx context.Context, cursor mi for rows.Next() { var eventID string var envelopeBytes []byte - var createdAt time.Time - if err := rows.Scan(&eventID, &envelopeBytes, &createdAt); err != nil { + var createdAtMS int64 + if err := rows.Scan(&eventID, &envelopeBytes, &createdAtMS); err != nil { return nil, err } var envelope roomeventsv1.EventEnvelope @@ -70,7 +68,7 @@ func (r *RoomOutboxReader) ListRoomMicEventsAfter(ctx context.Context, cursor mi EventType: envelope.GetEventType(), RoomID: envelope.GetRoomId(), RoomVersion: envelope.GetRoomVersion(), - OutboxCreatedAtMs: createdAt.UnixMilli(), + OutboxCreatedAtMs: createdAtMS, OccurredAtMs: envelope.GetOccurredAtMs(), ActorUserID: body.GetActorUserId(), TargetUserID: body.GetTargetUserId(), diff --git a/services/user-service/internal/storage/mysql/region/rebuild_tasks.go b/services/user-service/internal/storage/mysql/region/rebuild_tasks.go index 3855ead7..dfe71903 100644 --- a/services/user-service/internal/storage/mysql/region/rebuild_tasks.go +++ b/services/user-service/internal/storage/mysql/region/rebuild_tasks.go @@ -20,7 +20,7 @@ func (r *Repository) ProcessNextRegionRebuildTask(ctx context.Context, workerID batchSize = 500 } - // claim 必须独立提交:running/locked_until/attempt_count 要对其他 worker 和运维可见。 + // claim 必须独立提交:running/locked_until_ms/attempt_count 要对其他 worker 和运维可见。 task, ok, err := claimRegionRebuildTask(ctx, r.db, appcode.FromContext(ctx), workerID, nowMs, lockTTL) if err != nil { return userdomain.RegionRebuildProcessResult{}, err diff --git a/services/user-service/internal/transport/grpc/server.go b/services/user-service/internal/transport/grpc/server.go index 9492bfd5..50c1303b 100644 --- a/services/user-service/internal/transport/grpc/server.go +++ b/services/user-service/internal/transport/grpc/server.go @@ -243,12 +243,22 @@ func (s *Server) UpdateUserProfile(ctx context.Context, req *userv1.UpdateUserPr func (s *Server) ChangeUserCountry(ctx context.Context, req *userv1.ChangeUserCountryRequest) (*userv1.ChangeUserCountryResponse, error) { ctx = contextWithApp(ctx, req.GetMeta()) // 国家修改有独立审计和冷却期,不能混进普通资料更新。 + before, err := s.userSvc.GetUser(ctx, req.GetUserId()) + if err != nil { + return nil, xerr.ToGRPCError(err) + } user, nextChangeAllowedAtMs, err := s.userSvc.ChangeUserCountry(ctx, req.GetUserId(), req.GetCountry(), req.GetMeta().GetRequestId()) if err != nil { return nil, xerr.ToGRPCError(err) } - return &userv1.ChangeUserCountryResponse{User: toProtoUser(user), NextChangeAllowedAtMs: nextChangeAllowedAtMs}, nil + return &userv1.ChangeUserCountryResponse{ + User: toProtoUser(user), + NextChangeAllowedAtMs: nextChangeAllowedAtMs, + OldRegionId: before.RegionID, + NewRegionId: user.RegionID, + RegionChanged: before.RegionID != user.RegionID, + }, nil } // CompleteOnboarding 原子完成注册页必填资料。 diff --git a/services/wallet-service/Dockerfile b/services/wallet-service/Dockerfile index 7eb319b8..961c4927 100644 --- a/services/wallet-service/Dockerfile +++ b/services/wallet-service/Dockerfile @@ -13,6 +13,8 @@ RUN GOWORK=off CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/grpc-healt FROM alpine:3.20 +ENV TZ=UTC + WORKDIR /app RUN apk add --no-cache ca-certificates && adduser -D -g '' appuser diff --git a/services/wallet-service/configs/config.docker.yaml b/services/wallet-service/configs/config.docker.yaml index e7991271..63d622c7 100644 --- a/services/wallet-service/configs/config.docker.yaml +++ b/services/wallet-service/configs/config.docker.yaml @@ -8,5 +8,5 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13004" -mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(mysql:3306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC" mysql_auto_migrate: false diff --git a/services/wallet-service/configs/config.tencent.example.yaml b/services/wallet-service/configs/config.tencent.example.yaml index fc9095d1..dcbee2c8 100644 --- a/services/wallet-service/configs/config.tencent.example.yaml +++ b/services/wallet-service/configs/config.tencent.example.yaml @@ -8,5 +8,5 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13004" -mysql_dsn: "${TENCENT_MYSQL_WALLET_DSN}" +mysql_dsn: "USER:PASSWORD@tcp(TENCENT_CDB_HOST:3306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC&tls=false" mysql_auto_migrate: false diff --git a/services/wallet-service/configs/config.yaml b/services/wallet-service/configs/config.yaml index ead3b652..5725e518 100644 --- a/services/wallet-service/configs/config.yaml +++ b/services/wallet-service/configs/config.yaml @@ -8,5 +8,5 @@ log: include_response_body: false max_payload_bytes: 2048 grpc_addr: ":13004" -mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local" +mysql_dsn: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC" mysql_auto_migrate: false diff --git a/services/wallet-service/internal/config/config.go b/services/wallet-service/internal/config/config.go index c4d79cef..1551267c 100644 --- a/services/wallet-service/internal/config/config.go +++ b/services/wallet-service/internal/config/config.go @@ -27,7 +27,7 @@ func Default() Config { NodeID: "wallet-local", Environment: "local", GRPCAddr: ":13004", - MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local", + MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=UTC", MySQLAutoMigrate: false, Log: logx.Config{ Level: "info", diff --git a/services/wallet-service/internal/storage/mysql/recharge_repository.go b/services/wallet-service/internal/storage/mysql/recharge_repository.go index 71c4aa1d..5980aa73 100644 --- a/services/wallet-service/internal/storage/mysql/recharge_repository.go +++ b/services/wallet-service/internal/storage/mysql/recharge_repository.go @@ -126,7 +126,7 @@ func rechargeBillsWhereSQL(query ledger.ListRechargeBillsQuery) (string, []any) args = append(args, query.StartAtMS) } if query.EndAtMS > 0 { - where += ` AND rr.created_at_ms <= ?` + where += ` AND rr.created_at_ms < ?` args = append(args, query.EndAtMS) } if query.Keyword != "" { diff --git a/services/wallet-service/internal/storage/mysql/recharge_repository_test.go b/services/wallet-service/internal/storage/mysql/recharge_repository_test.go new file mode 100644 index 00000000..ece99c18 --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/recharge_repository_test.go @@ -0,0 +1,22 @@ +package mysql + +import ( + "strings" + "testing" + + "hyapp/services/wallet-service/internal/domain/ledger" +) + +func TestRechargeBillsWhereUsesExclusiveEndMs(t *testing.T) { + where, args := rechargeBillsWhereSQL(ledger.ListRechargeBillsQuery{ + AppCode: "lalu", + StartAtMS: 1778284800000, + EndAtMS: 1778371200000, + }) + if !strings.Contains(where, "rr.created_at_ms >= ?") || !strings.Contains(where, "rr.created_at_ms < ?") { + t.Fatalf("recharge bill range must use [start_ms, end_ms): where=%s", where) + } + if len(args) != 3 || args[1] != int64(1778284800000) || args[2] != int64(1778371200000) { + t.Fatalf("range args mismatch: %#v", args) + } +}