diff --git a/api/proto/activity/v1/activity.pb.go b/api/proto/activity/v1/activity.pb.go index 20d7f5d1..4d7ec8b1 100644 --- a/api/proto/activity/v1/activity.pb.go +++ b/api/proto/activity/v1/activity.pb.go @@ -10114,6 +10114,94 @@ func (x *UpsertLuckyGiftConfigResponse) GetConfig() *LuckyGiftConfig { return nil } +type ListLuckyGiftConfigsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListLuckyGiftConfigsRequest) Reset() { + *x = ListLuckyGiftConfigsRequest{} + mi := &file_proto_activity_v1_activity_proto_msgTypes[123] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListLuckyGiftConfigsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListLuckyGiftConfigsRequest) ProtoMessage() {} + +func (x *ListLuckyGiftConfigsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[123] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListLuckyGiftConfigsRequest.ProtoReflect.Descriptor instead. +func (*ListLuckyGiftConfigsRequest) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{123} +} + +func (x *ListLuckyGiftConfigsRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +type ListLuckyGiftConfigsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Configs []*LuckyGiftConfig `protobuf:"bytes,1,rep,name=configs,proto3" json:"configs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListLuckyGiftConfigsResponse) Reset() { + *x = ListLuckyGiftConfigsResponse{} + mi := &file_proto_activity_v1_activity_proto_msgTypes[124] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListLuckyGiftConfigsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListLuckyGiftConfigsResponse) ProtoMessage() {} + +func (x *ListLuckyGiftConfigsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_activity_v1_activity_proto_msgTypes[124] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListLuckyGiftConfigsResponse.ProtoReflect.Descriptor instead. +func (*ListLuckyGiftConfigsResponse) Descriptor() ([]byte, []int) { + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{124} +} + +func (x *ListLuckyGiftConfigsResponse) GetConfigs() []*LuckyGiftConfig { + if x != nil { + return x.Configs + } + return nil +} + type ListLuckyGiftDrawsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` @@ -10130,7 +10218,7 @@ type ListLuckyGiftDrawsRequest struct { func (x *ListLuckyGiftDrawsRequest) Reset() { *x = ListLuckyGiftDrawsRequest{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[123] + mi := &file_proto_activity_v1_activity_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10142,7 +10230,7 @@ func (x *ListLuckyGiftDrawsRequest) String() string { func (*ListLuckyGiftDrawsRequest) ProtoMessage() {} func (x *ListLuckyGiftDrawsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[123] + mi := &file_proto_activity_v1_activity_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10155,7 +10243,7 @@ func (x *ListLuckyGiftDrawsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListLuckyGiftDrawsRequest.ProtoReflect.Descriptor instead. func (*ListLuckyGiftDrawsRequest) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{123} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{125} } func (x *ListLuckyGiftDrawsRequest) GetMeta() *RequestMeta { @@ -10224,7 +10312,7 @@ type ListLuckyGiftDrawsResponse struct { func (x *ListLuckyGiftDrawsResponse) Reset() { *x = ListLuckyGiftDrawsResponse{} - mi := &file_proto_activity_v1_activity_proto_msgTypes[124] + mi := &file_proto_activity_v1_activity_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10236,7 +10324,7 @@ func (x *ListLuckyGiftDrawsResponse) String() string { func (*ListLuckyGiftDrawsResponse) ProtoMessage() {} func (x *ListLuckyGiftDrawsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_activity_v1_activity_proto_msgTypes[124] + mi := &file_proto_activity_v1_activity_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10249,7 +10337,7 @@ func (x *ListLuckyGiftDrawsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListLuckyGiftDrawsResponse.ProtoReflect.Descriptor instead. func (*ListLuckyGiftDrawsResponse) Descriptor() ([]byte, []int) { - return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{124} + return file_proto_activity_v1_activity_proto_rawDescGZIP(), []int{126} } func (x *ListLuckyGiftDrawsResponse) GetDraws() []*LuckyGiftDrawResult { @@ -11208,7 +11296,11 @@ const file_proto_activity_v1_activity_proto_rawDesc = "" + "\x06config\x18\x02 \x01(\v2\".hyapp.activity.v1.LuckyGiftConfigR\x06config\x12*\n" + "\x11operator_admin_id\x18\x03 \x01(\x03R\x0foperatorAdminId\"[\n" + "\x1dUpsertLuckyGiftConfigResponse\x12:\n" + - "\x06config\x18\x01 \x01(\v2\".hyapp.activity.v1.LuckyGiftConfigR\x06config\"\xfc\x01\n" + + "\x06config\x18\x01 \x01(\v2\".hyapp.activity.v1.LuckyGiftConfigR\x06config\"Q\n" + + "\x1bListLuckyGiftConfigsRequest\x122\n" + + "\x04meta\x18\x01 \x01(\v2\x1e.hyapp.activity.v1.RequestMetaR\x04meta\"\\\n" + + "\x1cListLuckyGiftConfigsResponse\x12<\n" + + "\aconfigs\x18\x01 \x03(\v2\".hyapp.activity.v1.LuckyGiftConfigR\aconfigs\"\xfc\x01\n" + "\x19ListLuckyGiftDrawsRequest\x122\n" + "\x04meta\x18\x01 \x01(\v2\x1e.hyapp.activity.v1.RequestMetaR\x04meta\x12\x17\n" + "\agift_id\x18\x02 \x01(\tR\x06giftId\x12\x17\n" + @@ -11286,10 +11378,11 @@ const file_proto_activity_v1_activity_proto_rawDesc = "" + "\x0fUpsertLevelTier\x12).hyapp.activity.v1.UpsertLevelTierRequest\x1a*.hyapp.activity.v1.UpsertLevelTierResponse2\x9f\x02\n" + "\x17AdminAchievementService\x12u\n" + "\x1aListAchievementDefinitions\x12*.hyapp.activity.v1.ListAchievementsRequest\x1a+.hyapp.activity.v1.ListAchievementsResponse\x12\x8c\x01\n" + - "\x1bUpsertAchievementDefinition\x125.hyapp.activity.v1.UpsertAchievementDefinitionRequest\x1a6.hyapp.activity.v1.UpsertAchievementDefinitionResponse2\xf9\x02\n" + + "\x1bUpsertAchievementDefinition\x125.hyapp.activity.v1.UpsertAchievementDefinitionRequest\x1a6.hyapp.activity.v1.UpsertAchievementDefinitionResponse2\xf2\x03\n" + "\x15AdminLuckyGiftService\x12q\n" + "\x12GetLuckyGiftConfig\x12,.hyapp.activity.v1.GetLuckyGiftConfigRequest\x1a-.hyapp.activity.v1.GetLuckyGiftConfigResponse\x12z\n" + - "\x15UpsertLuckyGiftConfig\x12/.hyapp.activity.v1.UpsertLuckyGiftConfigRequest\x1a0.hyapp.activity.v1.UpsertLuckyGiftConfigResponse\x12q\n" + + "\x15UpsertLuckyGiftConfig\x12/.hyapp.activity.v1.UpsertLuckyGiftConfigRequest\x1a0.hyapp.activity.v1.UpsertLuckyGiftConfigResponse\x12w\n" + + "\x14ListLuckyGiftConfigs\x12..hyapp.activity.v1.ListLuckyGiftConfigsRequest\x1a/.hyapp.activity.v1.ListLuckyGiftConfigsResponse\x12q\n" + "\x12ListLuckyGiftDraws\x12,.hyapp.activity.v1.ListLuckyGiftDrawsRequest\x1a-.hyapp.activity.v1.ListLuckyGiftDrawsResponseB.Z,hyapp.local/api/proto/activity/v1;activityv1b\x06proto3" var ( @@ -11304,7 +11397,7 @@ 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, 125) +var file_proto_activity_v1_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 127) var file_proto_activity_v1_activity_proto_goTypes = []any{ (*RequestMeta)(nil), // 0: hyapp.activity.v1.RequestMeta (*PingActivityRequest)(nil), // 1: hyapp.activity.v1.PingActivityRequest @@ -11429,9 +11522,11 @@ var file_proto_activity_v1_activity_proto_goTypes = []any{ (*GetLuckyGiftConfigResponse)(nil), // 120: hyapp.activity.v1.GetLuckyGiftConfigResponse (*UpsertLuckyGiftConfigRequest)(nil), // 121: hyapp.activity.v1.UpsertLuckyGiftConfigRequest (*UpsertLuckyGiftConfigResponse)(nil), // 122: hyapp.activity.v1.UpsertLuckyGiftConfigResponse - (*ListLuckyGiftDrawsRequest)(nil), // 123: hyapp.activity.v1.ListLuckyGiftDrawsRequest - (*ListLuckyGiftDrawsResponse)(nil), // 124: hyapp.activity.v1.ListLuckyGiftDrawsResponse - (*v1.EventEnvelope)(nil), // 125: hyapp.events.room.v1.EventEnvelope + (*ListLuckyGiftConfigsRequest)(nil), // 123: hyapp.activity.v1.ListLuckyGiftConfigsRequest + (*ListLuckyGiftConfigsResponse)(nil), // 124: hyapp.activity.v1.ListLuckyGiftConfigsResponse + (*ListLuckyGiftDrawsRequest)(nil), // 125: hyapp.activity.v1.ListLuckyGiftDrawsRequest + (*ListLuckyGiftDrawsResponse)(nil), // 126: hyapp.activity.v1.ListLuckyGiftDrawsResponse + (*v1.EventEnvelope)(nil), // 127: 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 @@ -11456,7 +11551,7 @@ var file_proto_activity_v1_activity_proto_depIdxs = []int32{ 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 - 125, // 22: hyapp.activity.v1.ConsumeRoomEventRequest.envelope:type_name -> hyapp.events.room.v1.EventEnvelope + 127, // 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 @@ -11529,119 +11624,123 @@ var file_proto_activity_v1_activity_proto_depIdxs = []int32{ 0, // 92: hyapp.activity.v1.UpsertLuckyGiftConfigRequest.meta:type_name -> hyapp.activity.v1.RequestMeta 113, // 93: hyapp.activity.v1.UpsertLuckyGiftConfigRequest.config:type_name -> hyapp.activity.v1.LuckyGiftConfig 113, // 94: hyapp.activity.v1.UpsertLuckyGiftConfigResponse.config:type_name -> hyapp.activity.v1.LuckyGiftConfig - 0, // 95: hyapp.activity.v1.ListLuckyGiftDrawsRequest.meta:type_name -> hyapp.activity.v1.RequestMeta - 116, // 96: hyapp.activity.v1.ListLuckyGiftDrawsResponse.draws:type_name -> hyapp.activity.v1.LuckyGiftDrawResult - 1, // 97: hyapp.activity.v1.ActivityService.PingActivity:input_type -> hyapp.activity.v1.PingActivityRequest - 3, // 98: hyapp.activity.v1.ActivityService.GetActivityStatus:input_type -> hyapp.activity.v1.GetActivityStatusRequest - 6, // 99: hyapp.activity.v1.MessageInboxService.ListMessageTabs:input_type -> hyapp.activity.v1.ListMessageTabsRequest - 9, // 100: hyapp.activity.v1.MessageInboxService.ListInboxMessages:input_type -> hyapp.activity.v1.ListInboxMessagesRequest - 11, // 101: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:input_type -> hyapp.activity.v1.MarkInboxMessageReadRequest - 13, // 102: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:input_type -> hyapp.activity.v1.MarkInboxSectionReadRequest - 15, // 103: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:input_type -> hyapp.activity.v1.DeleteInboxMessageRequest - 17, // 104: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:input_type -> hyapp.activity.v1.CreateInboxMessageRequest - 19, // 105: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:input_type -> hyapp.activity.v1.CreateFanoutJobRequest - 21, // 106: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:input_type -> hyapp.activity.v1.CronBatchRequest - 21, // 107: hyapp.activity.v1.ActivityCronService.ProcessLevelRewardBatch:input_type -> hyapp.activity.v1.CronBatchRequest - 21, // 108: hyapp.activity.v1.ActivityCronService.ProcessAchievementRewardBatch:input_type -> hyapp.activity.v1.CronBatchRequest - 25, // 109: hyapp.activity.v1.TaskService.ListUserTasks:input_type -> hyapp.activity.v1.ListUserTasksRequest - 27, // 110: hyapp.activity.v1.TaskService.ClaimTaskReward:input_type -> hyapp.activity.v1.ClaimTaskRewardRequest - 29, // 111: hyapp.activity.v1.TaskService.ConsumeTaskEvent:input_type -> hyapp.activity.v1.ConsumeTaskEventRequest - 80, // 112: hyapp.activity.v1.GrowthLevelService.GetMyLevelOverview:input_type -> hyapp.activity.v1.GetMyLevelOverviewRequest - 82, // 113: hyapp.activity.v1.GrowthLevelService.GetLevelTrack:input_type -> hyapp.activity.v1.GetLevelTrackRequest - 85, // 114: hyapp.activity.v1.GrowthLevelService.ListLevelRewards:input_type -> hyapp.activity.v1.ListLevelRewardsRequest - 87, // 115: hyapp.activity.v1.GrowthLevelService.ConsumeLevelEvent:input_type -> hyapp.activity.v1.ConsumeLevelEventRequest - 100, // 116: hyapp.activity.v1.AchievementService.ListAchievements:input_type -> hyapp.activity.v1.ListAchievementsRequest - 102, // 117: hyapp.activity.v1.AchievementService.ConsumeAchievementEvent:input_type -> hyapp.activity.v1.ConsumeAchievementEventRequest - 105, // 118: hyapp.activity.v1.AchievementService.ListMyBadges:input_type -> hyapp.activity.v1.ListMyBadgesRequest - 107, // 119: hyapp.activity.v1.AchievementService.SetBadgeDisplay:input_type -> hyapp.activity.v1.SetBadgeDisplayRequest - 114, // 120: hyapp.activity.v1.LuckyGiftService.CheckLuckyGift:input_type -> hyapp.activity.v1.CheckLuckyGiftRequest - 117, // 121: hyapp.activity.v1.LuckyGiftService.ExecuteLuckyGiftDraw:input_type -> hyapp.activity.v1.ExecuteLuckyGiftDrawRequest - 32, // 122: hyapp.activity.v1.BroadcastService.EnsureBroadcastGroups:input_type -> hyapp.activity.v1.EnsureBroadcastGroupsRequest - 34, // 123: hyapp.activity.v1.BroadcastService.PublishRegionBroadcast:input_type -> hyapp.activity.v1.PublishRegionBroadcastRequest - 35, // 124: hyapp.activity.v1.BroadcastService.PublishGlobalBroadcast:input_type -> hyapp.activity.v1.PublishGlobalBroadcastRequest - 37, // 125: hyapp.activity.v1.BroadcastService.RemoveRegionBroadcastMember:input_type -> hyapp.activity.v1.RemoveRegionBroadcastMemberRequest - 21, // 126: hyapp.activity.v1.BroadcastService.ProcessBroadcastOutboxBatch:input_type -> hyapp.activity.v1.CronBatchRequest - 40, // 127: hyapp.activity.v1.RoomEventConsumerService.ConsumeRoomEvent:input_type -> hyapp.activity.v1.ConsumeRoomEventRequest - 43, // 128: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:input_type -> hyapp.activity.v1.ListTaskDefinitionsRequest - 45, // 129: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:input_type -> hyapp.activity.v1.UpsertTaskDefinitionRequest - 47, // 130: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:input_type -> hyapp.activity.v1.SetTaskDefinitionStatusRequest - 52, // 131: hyapp.activity.v1.RegistrationRewardService.GetRegistrationRewardEligibility:input_type -> hyapp.activity.v1.GetRegistrationRewardEligibilityRequest - 54, // 132: hyapp.activity.v1.RegistrationRewardService.IssueRegistrationReward:input_type -> hyapp.activity.v1.IssueRegistrationRewardRequest - 56, // 133: hyapp.activity.v1.AdminRegistrationRewardService.GetRegistrationRewardConfig:input_type -> hyapp.activity.v1.GetRegistrationRewardConfigRequest - 58, // 134: hyapp.activity.v1.AdminRegistrationRewardService.UpdateRegistrationRewardConfig:input_type -> hyapp.activity.v1.UpdateRegistrationRewardConfigRequest - 60, // 135: hyapp.activity.v1.AdminRegistrationRewardService.ListRegistrationRewardClaims:input_type -> hyapp.activity.v1.ListRegistrationRewardClaimsRequest - 65, // 136: hyapp.activity.v1.SevenDayCheckInService.GetSevenDayCheckInStatus:input_type -> hyapp.activity.v1.GetSevenDayCheckInStatusRequest - 67, // 137: hyapp.activity.v1.SevenDayCheckInService.SignSevenDayCheckIn:input_type -> hyapp.activity.v1.SignSevenDayCheckInRequest - 69, // 138: hyapp.activity.v1.AdminSevenDayCheckInService.GetSevenDayCheckInConfig:input_type -> hyapp.activity.v1.GetSevenDayCheckInConfigRequest - 71, // 139: hyapp.activity.v1.AdminSevenDayCheckInService.UpdateSevenDayCheckInConfig:input_type -> hyapp.activity.v1.UpdateSevenDayCheckInConfigRequest - 74, // 140: hyapp.activity.v1.AdminSevenDayCheckInService.ListSevenDayCheckInClaims:input_type -> hyapp.activity.v1.ListSevenDayCheckInClaimsRequest - 95, // 141: hyapp.activity.v1.AdminGrowthLevelService.ListLevelConfig:input_type -> hyapp.activity.v1.ListLevelConfigRequest - 89, // 142: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTrack:input_type -> hyapp.activity.v1.UpsertLevelTrackRequest - 91, // 143: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelRule:input_type -> hyapp.activity.v1.UpsertLevelRuleRequest - 93, // 144: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTier:input_type -> hyapp.activity.v1.UpsertLevelTierRequest - 100, // 145: hyapp.activity.v1.AdminAchievementService.ListAchievementDefinitions:input_type -> hyapp.activity.v1.ListAchievementsRequest - 109, // 146: hyapp.activity.v1.AdminAchievementService.UpsertAchievementDefinition:input_type -> hyapp.activity.v1.UpsertAchievementDefinitionRequest - 119, // 147: hyapp.activity.v1.AdminLuckyGiftService.GetLuckyGiftConfig:input_type -> hyapp.activity.v1.GetLuckyGiftConfigRequest - 121, // 148: hyapp.activity.v1.AdminLuckyGiftService.UpsertLuckyGiftConfig:input_type -> hyapp.activity.v1.UpsertLuckyGiftConfigRequest - 123, // 149: hyapp.activity.v1.AdminLuckyGiftService.ListLuckyGiftDraws:input_type -> hyapp.activity.v1.ListLuckyGiftDrawsRequest - 2, // 150: hyapp.activity.v1.ActivityService.PingActivity:output_type -> hyapp.activity.v1.PingActivityResponse - 4, // 151: hyapp.activity.v1.ActivityService.GetActivityStatus:output_type -> hyapp.activity.v1.GetActivityStatusResponse - 7, // 152: hyapp.activity.v1.MessageInboxService.ListMessageTabs:output_type -> hyapp.activity.v1.ListMessageTabsResponse - 10, // 153: hyapp.activity.v1.MessageInboxService.ListInboxMessages:output_type -> hyapp.activity.v1.ListInboxMessagesResponse - 12, // 154: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:output_type -> hyapp.activity.v1.MarkInboxMessageReadResponse - 14, // 155: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:output_type -> hyapp.activity.v1.MarkInboxSectionReadResponse - 16, // 156: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:output_type -> hyapp.activity.v1.DeleteInboxMessageResponse - 18, // 157: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:output_type -> hyapp.activity.v1.CreateInboxMessageResponse - 20, // 158: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:output_type -> hyapp.activity.v1.CreateFanoutJobResponse - 22, // 159: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:output_type -> hyapp.activity.v1.CronBatchResponse - 22, // 160: hyapp.activity.v1.ActivityCronService.ProcessLevelRewardBatch:output_type -> hyapp.activity.v1.CronBatchResponse - 22, // 161: hyapp.activity.v1.ActivityCronService.ProcessAchievementRewardBatch:output_type -> hyapp.activity.v1.CronBatchResponse - 26, // 162: hyapp.activity.v1.TaskService.ListUserTasks:output_type -> hyapp.activity.v1.ListUserTasksResponse - 28, // 163: hyapp.activity.v1.TaskService.ClaimTaskReward:output_type -> hyapp.activity.v1.ClaimTaskRewardResponse - 30, // 164: hyapp.activity.v1.TaskService.ConsumeTaskEvent:output_type -> hyapp.activity.v1.ConsumeTaskEventResponse - 81, // 165: hyapp.activity.v1.GrowthLevelService.GetMyLevelOverview:output_type -> hyapp.activity.v1.GetMyLevelOverviewResponse - 83, // 166: hyapp.activity.v1.GrowthLevelService.GetLevelTrack:output_type -> hyapp.activity.v1.GetLevelTrackResponse - 86, // 167: hyapp.activity.v1.GrowthLevelService.ListLevelRewards:output_type -> hyapp.activity.v1.ListLevelRewardsResponse - 88, // 168: hyapp.activity.v1.GrowthLevelService.ConsumeLevelEvent:output_type -> hyapp.activity.v1.ConsumeLevelEventResponse - 101, // 169: hyapp.activity.v1.AchievementService.ListAchievements:output_type -> hyapp.activity.v1.ListAchievementsResponse - 103, // 170: hyapp.activity.v1.AchievementService.ConsumeAchievementEvent:output_type -> hyapp.activity.v1.ConsumeAchievementEventResponse - 106, // 171: hyapp.activity.v1.AchievementService.ListMyBadges:output_type -> hyapp.activity.v1.ListMyBadgesResponse - 108, // 172: hyapp.activity.v1.AchievementService.SetBadgeDisplay:output_type -> hyapp.activity.v1.SetBadgeDisplayResponse - 115, // 173: hyapp.activity.v1.LuckyGiftService.CheckLuckyGift:output_type -> hyapp.activity.v1.CheckLuckyGiftResponse - 118, // 174: hyapp.activity.v1.LuckyGiftService.ExecuteLuckyGiftDraw:output_type -> hyapp.activity.v1.ExecuteLuckyGiftDrawResponse - 33, // 175: hyapp.activity.v1.BroadcastService.EnsureBroadcastGroups:output_type -> hyapp.activity.v1.EnsureBroadcastGroupsResponse - 36, // 176: hyapp.activity.v1.BroadcastService.PublishRegionBroadcast:output_type -> hyapp.activity.v1.PublishBroadcastResponse - 36, // 177: hyapp.activity.v1.BroadcastService.PublishGlobalBroadcast:output_type -> hyapp.activity.v1.PublishBroadcastResponse - 38, // 178: hyapp.activity.v1.BroadcastService.RemoveRegionBroadcastMember:output_type -> hyapp.activity.v1.RemoveRegionBroadcastMemberResponse - 39, // 179: hyapp.activity.v1.BroadcastService.ProcessBroadcastOutboxBatch:output_type -> hyapp.activity.v1.ProcessBroadcastOutboxBatchResponse - 41, // 180: hyapp.activity.v1.RoomEventConsumerService.ConsumeRoomEvent:output_type -> hyapp.activity.v1.ConsumeRoomEventResponse - 44, // 181: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:output_type -> hyapp.activity.v1.ListTaskDefinitionsResponse - 46, // 182: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:output_type -> hyapp.activity.v1.UpsertTaskDefinitionResponse - 48, // 183: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:output_type -> hyapp.activity.v1.SetTaskDefinitionStatusResponse - 53, // 184: hyapp.activity.v1.RegistrationRewardService.GetRegistrationRewardEligibility:output_type -> hyapp.activity.v1.GetRegistrationRewardEligibilityResponse - 55, // 185: hyapp.activity.v1.RegistrationRewardService.IssueRegistrationReward:output_type -> hyapp.activity.v1.IssueRegistrationRewardResponse - 57, // 186: hyapp.activity.v1.AdminRegistrationRewardService.GetRegistrationRewardConfig:output_type -> hyapp.activity.v1.GetRegistrationRewardConfigResponse - 59, // 187: hyapp.activity.v1.AdminRegistrationRewardService.UpdateRegistrationRewardConfig:output_type -> hyapp.activity.v1.UpdateRegistrationRewardConfigResponse - 61, // 188: hyapp.activity.v1.AdminRegistrationRewardService.ListRegistrationRewardClaims:output_type -> hyapp.activity.v1.ListRegistrationRewardClaimsResponse - 66, // 189: hyapp.activity.v1.SevenDayCheckInService.GetSevenDayCheckInStatus:output_type -> hyapp.activity.v1.GetSevenDayCheckInStatusResponse - 68, // 190: hyapp.activity.v1.SevenDayCheckInService.SignSevenDayCheckIn:output_type -> hyapp.activity.v1.SignSevenDayCheckInResponse - 70, // 191: hyapp.activity.v1.AdminSevenDayCheckInService.GetSevenDayCheckInConfig:output_type -> hyapp.activity.v1.GetSevenDayCheckInConfigResponse - 72, // 192: hyapp.activity.v1.AdminSevenDayCheckInService.UpdateSevenDayCheckInConfig:output_type -> hyapp.activity.v1.UpdateSevenDayCheckInConfigResponse - 75, // 193: hyapp.activity.v1.AdminSevenDayCheckInService.ListSevenDayCheckInClaims:output_type -> hyapp.activity.v1.ListSevenDayCheckInClaimsResponse - 96, // 194: hyapp.activity.v1.AdminGrowthLevelService.ListLevelConfig:output_type -> hyapp.activity.v1.ListLevelConfigResponse - 90, // 195: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTrack:output_type -> hyapp.activity.v1.UpsertLevelTrackResponse - 92, // 196: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelRule:output_type -> hyapp.activity.v1.UpsertLevelRuleResponse - 94, // 197: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTier:output_type -> hyapp.activity.v1.UpsertLevelTierResponse - 101, // 198: hyapp.activity.v1.AdminAchievementService.ListAchievementDefinitions:output_type -> hyapp.activity.v1.ListAchievementsResponse - 110, // 199: hyapp.activity.v1.AdminAchievementService.UpsertAchievementDefinition:output_type -> hyapp.activity.v1.UpsertAchievementDefinitionResponse - 120, // 200: hyapp.activity.v1.AdminLuckyGiftService.GetLuckyGiftConfig:output_type -> hyapp.activity.v1.GetLuckyGiftConfigResponse - 122, // 201: hyapp.activity.v1.AdminLuckyGiftService.UpsertLuckyGiftConfig:output_type -> hyapp.activity.v1.UpsertLuckyGiftConfigResponse - 124, // 202: hyapp.activity.v1.AdminLuckyGiftService.ListLuckyGiftDraws:output_type -> hyapp.activity.v1.ListLuckyGiftDrawsResponse - 150, // [150:203] is the sub-list for method output_type - 97, // [97:150] is the sub-list for method input_type - 97, // [97:97] is the sub-list for extension type_name - 97, // [97:97] is the sub-list for extension extendee - 0, // [0:97] is the sub-list for field type_name + 0, // 95: hyapp.activity.v1.ListLuckyGiftConfigsRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 113, // 96: hyapp.activity.v1.ListLuckyGiftConfigsResponse.configs:type_name -> hyapp.activity.v1.LuckyGiftConfig + 0, // 97: hyapp.activity.v1.ListLuckyGiftDrawsRequest.meta:type_name -> hyapp.activity.v1.RequestMeta + 116, // 98: hyapp.activity.v1.ListLuckyGiftDrawsResponse.draws:type_name -> hyapp.activity.v1.LuckyGiftDrawResult + 1, // 99: hyapp.activity.v1.ActivityService.PingActivity:input_type -> hyapp.activity.v1.PingActivityRequest + 3, // 100: hyapp.activity.v1.ActivityService.GetActivityStatus:input_type -> hyapp.activity.v1.GetActivityStatusRequest + 6, // 101: hyapp.activity.v1.MessageInboxService.ListMessageTabs:input_type -> hyapp.activity.v1.ListMessageTabsRequest + 9, // 102: hyapp.activity.v1.MessageInboxService.ListInboxMessages:input_type -> hyapp.activity.v1.ListInboxMessagesRequest + 11, // 103: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:input_type -> hyapp.activity.v1.MarkInboxMessageReadRequest + 13, // 104: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:input_type -> hyapp.activity.v1.MarkInboxSectionReadRequest + 15, // 105: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:input_type -> hyapp.activity.v1.DeleteInboxMessageRequest + 17, // 106: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:input_type -> hyapp.activity.v1.CreateInboxMessageRequest + 19, // 107: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:input_type -> hyapp.activity.v1.CreateFanoutJobRequest + 21, // 108: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:input_type -> hyapp.activity.v1.CronBatchRequest + 21, // 109: hyapp.activity.v1.ActivityCronService.ProcessLevelRewardBatch:input_type -> hyapp.activity.v1.CronBatchRequest + 21, // 110: hyapp.activity.v1.ActivityCronService.ProcessAchievementRewardBatch:input_type -> hyapp.activity.v1.CronBatchRequest + 25, // 111: hyapp.activity.v1.TaskService.ListUserTasks:input_type -> hyapp.activity.v1.ListUserTasksRequest + 27, // 112: hyapp.activity.v1.TaskService.ClaimTaskReward:input_type -> hyapp.activity.v1.ClaimTaskRewardRequest + 29, // 113: hyapp.activity.v1.TaskService.ConsumeTaskEvent:input_type -> hyapp.activity.v1.ConsumeTaskEventRequest + 80, // 114: hyapp.activity.v1.GrowthLevelService.GetMyLevelOverview:input_type -> hyapp.activity.v1.GetMyLevelOverviewRequest + 82, // 115: hyapp.activity.v1.GrowthLevelService.GetLevelTrack:input_type -> hyapp.activity.v1.GetLevelTrackRequest + 85, // 116: hyapp.activity.v1.GrowthLevelService.ListLevelRewards:input_type -> hyapp.activity.v1.ListLevelRewardsRequest + 87, // 117: hyapp.activity.v1.GrowthLevelService.ConsumeLevelEvent:input_type -> hyapp.activity.v1.ConsumeLevelEventRequest + 100, // 118: hyapp.activity.v1.AchievementService.ListAchievements:input_type -> hyapp.activity.v1.ListAchievementsRequest + 102, // 119: hyapp.activity.v1.AchievementService.ConsumeAchievementEvent:input_type -> hyapp.activity.v1.ConsumeAchievementEventRequest + 105, // 120: hyapp.activity.v1.AchievementService.ListMyBadges:input_type -> hyapp.activity.v1.ListMyBadgesRequest + 107, // 121: hyapp.activity.v1.AchievementService.SetBadgeDisplay:input_type -> hyapp.activity.v1.SetBadgeDisplayRequest + 114, // 122: hyapp.activity.v1.LuckyGiftService.CheckLuckyGift:input_type -> hyapp.activity.v1.CheckLuckyGiftRequest + 117, // 123: hyapp.activity.v1.LuckyGiftService.ExecuteLuckyGiftDraw:input_type -> hyapp.activity.v1.ExecuteLuckyGiftDrawRequest + 32, // 124: hyapp.activity.v1.BroadcastService.EnsureBroadcastGroups:input_type -> hyapp.activity.v1.EnsureBroadcastGroupsRequest + 34, // 125: hyapp.activity.v1.BroadcastService.PublishRegionBroadcast:input_type -> hyapp.activity.v1.PublishRegionBroadcastRequest + 35, // 126: hyapp.activity.v1.BroadcastService.PublishGlobalBroadcast:input_type -> hyapp.activity.v1.PublishGlobalBroadcastRequest + 37, // 127: hyapp.activity.v1.BroadcastService.RemoveRegionBroadcastMember:input_type -> hyapp.activity.v1.RemoveRegionBroadcastMemberRequest + 21, // 128: hyapp.activity.v1.BroadcastService.ProcessBroadcastOutboxBatch:input_type -> hyapp.activity.v1.CronBatchRequest + 40, // 129: hyapp.activity.v1.RoomEventConsumerService.ConsumeRoomEvent:input_type -> hyapp.activity.v1.ConsumeRoomEventRequest + 43, // 130: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:input_type -> hyapp.activity.v1.ListTaskDefinitionsRequest + 45, // 131: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:input_type -> hyapp.activity.v1.UpsertTaskDefinitionRequest + 47, // 132: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:input_type -> hyapp.activity.v1.SetTaskDefinitionStatusRequest + 52, // 133: hyapp.activity.v1.RegistrationRewardService.GetRegistrationRewardEligibility:input_type -> hyapp.activity.v1.GetRegistrationRewardEligibilityRequest + 54, // 134: hyapp.activity.v1.RegistrationRewardService.IssueRegistrationReward:input_type -> hyapp.activity.v1.IssueRegistrationRewardRequest + 56, // 135: hyapp.activity.v1.AdminRegistrationRewardService.GetRegistrationRewardConfig:input_type -> hyapp.activity.v1.GetRegistrationRewardConfigRequest + 58, // 136: hyapp.activity.v1.AdminRegistrationRewardService.UpdateRegistrationRewardConfig:input_type -> hyapp.activity.v1.UpdateRegistrationRewardConfigRequest + 60, // 137: hyapp.activity.v1.AdminRegistrationRewardService.ListRegistrationRewardClaims:input_type -> hyapp.activity.v1.ListRegistrationRewardClaimsRequest + 65, // 138: hyapp.activity.v1.SevenDayCheckInService.GetSevenDayCheckInStatus:input_type -> hyapp.activity.v1.GetSevenDayCheckInStatusRequest + 67, // 139: hyapp.activity.v1.SevenDayCheckInService.SignSevenDayCheckIn:input_type -> hyapp.activity.v1.SignSevenDayCheckInRequest + 69, // 140: hyapp.activity.v1.AdminSevenDayCheckInService.GetSevenDayCheckInConfig:input_type -> hyapp.activity.v1.GetSevenDayCheckInConfigRequest + 71, // 141: hyapp.activity.v1.AdminSevenDayCheckInService.UpdateSevenDayCheckInConfig:input_type -> hyapp.activity.v1.UpdateSevenDayCheckInConfigRequest + 74, // 142: hyapp.activity.v1.AdminSevenDayCheckInService.ListSevenDayCheckInClaims:input_type -> hyapp.activity.v1.ListSevenDayCheckInClaimsRequest + 95, // 143: hyapp.activity.v1.AdminGrowthLevelService.ListLevelConfig:input_type -> hyapp.activity.v1.ListLevelConfigRequest + 89, // 144: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTrack:input_type -> hyapp.activity.v1.UpsertLevelTrackRequest + 91, // 145: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelRule:input_type -> hyapp.activity.v1.UpsertLevelRuleRequest + 93, // 146: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTier:input_type -> hyapp.activity.v1.UpsertLevelTierRequest + 100, // 147: hyapp.activity.v1.AdminAchievementService.ListAchievementDefinitions:input_type -> hyapp.activity.v1.ListAchievementsRequest + 109, // 148: hyapp.activity.v1.AdminAchievementService.UpsertAchievementDefinition:input_type -> hyapp.activity.v1.UpsertAchievementDefinitionRequest + 119, // 149: hyapp.activity.v1.AdminLuckyGiftService.GetLuckyGiftConfig:input_type -> hyapp.activity.v1.GetLuckyGiftConfigRequest + 121, // 150: hyapp.activity.v1.AdminLuckyGiftService.UpsertLuckyGiftConfig:input_type -> hyapp.activity.v1.UpsertLuckyGiftConfigRequest + 123, // 151: hyapp.activity.v1.AdminLuckyGiftService.ListLuckyGiftConfigs:input_type -> hyapp.activity.v1.ListLuckyGiftConfigsRequest + 125, // 152: hyapp.activity.v1.AdminLuckyGiftService.ListLuckyGiftDraws:input_type -> hyapp.activity.v1.ListLuckyGiftDrawsRequest + 2, // 153: hyapp.activity.v1.ActivityService.PingActivity:output_type -> hyapp.activity.v1.PingActivityResponse + 4, // 154: hyapp.activity.v1.ActivityService.GetActivityStatus:output_type -> hyapp.activity.v1.GetActivityStatusResponse + 7, // 155: hyapp.activity.v1.MessageInboxService.ListMessageTabs:output_type -> hyapp.activity.v1.ListMessageTabsResponse + 10, // 156: hyapp.activity.v1.MessageInboxService.ListInboxMessages:output_type -> hyapp.activity.v1.ListInboxMessagesResponse + 12, // 157: hyapp.activity.v1.MessageInboxService.MarkInboxMessageRead:output_type -> hyapp.activity.v1.MarkInboxMessageReadResponse + 14, // 158: hyapp.activity.v1.MessageInboxService.MarkInboxSectionRead:output_type -> hyapp.activity.v1.MarkInboxSectionReadResponse + 16, // 159: hyapp.activity.v1.MessageInboxService.DeleteInboxMessage:output_type -> hyapp.activity.v1.DeleteInboxMessageResponse + 18, // 160: hyapp.activity.v1.MessageInboxService.CreateInboxMessage:output_type -> hyapp.activity.v1.CreateInboxMessageResponse + 20, // 161: hyapp.activity.v1.MessageInboxService.CreateFanoutJob:output_type -> hyapp.activity.v1.CreateFanoutJobResponse + 22, // 162: hyapp.activity.v1.ActivityCronService.ProcessMessageFanoutBatch:output_type -> hyapp.activity.v1.CronBatchResponse + 22, // 163: hyapp.activity.v1.ActivityCronService.ProcessLevelRewardBatch:output_type -> hyapp.activity.v1.CronBatchResponse + 22, // 164: hyapp.activity.v1.ActivityCronService.ProcessAchievementRewardBatch:output_type -> hyapp.activity.v1.CronBatchResponse + 26, // 165: hyapp.activity.v1.TaskService.ListUserTasks:output_type -> hyapp.activity.v1.ListUserTasksResponse + 28, // 166: hyapp.activity.v1.TaskService.ClaimTaskReward:output_type -> hyapp.activity.v1.ClaimTaskRewardResponse + 30, // 167: hyapp.activity.v1.TaskService.ConsumeTaskEvent:output_type -> hyapp.activity.v1.ConsumeTaskEventResponse + 81, // 168: hyapp.activity.v1.GrowthLevelService.GetMyLevelOverview:output_type -> hyapp.activity.v1.GetMyLevelOverviewResponse + 83, // 169: hyapp.activity.v1.GrowthLevelService.GetLevelTrack:output_type -> hyapp.activity.v1.GetLevelTrackResponse + 86, // 170: hyapp.activity.v1.GrowthLevelService.ListLevelRewards:output_type -> hyapp.activity.v1.ListLevelRewardsResponse + 88, // 171: hyapp.activity.v1.GrowthLevelService.ConsumeLevelEvent:output_type -> hyapp.activity.v1.ConsumeLevelEventResponse + 101, // 172: hyapp.activity.v1.AchievementService.ListAchievements:output_type -> hyapp.activity.v1.ListAchievementsResponse + 103, // 173: hyapp.activity.v1.AchievementService.ConsumeAchievementEvent:output_type -> hyapp.activity.v1.ConsumeAchievementEventResponse + 106, // 174: hyapp.activity.v1.AchievementService.ListMyBadges:output_type -> hyapp.activity.v1.ListMyBadgesResponse + 108, // 175: hyapp.activity.v1.AchievementService.SetBadgeDisplay:output_type -> hyapp.activity.v1.SetBadgeDisplayResponse + 115, // 176: hyapp.activity.v1.LuckyGiftService.CheckLuckyGift:output_type -> hyapp.activity.v1.CheckLuckyGiftResponse + 118, // 177: hyapp.activity.v1.LuckyGiftService.ExecuteLuckyGiftDraw:output_type -> hyapp.activity.v1.ExecuteLuckyGiftDrawResponse + 33, // 178: hyapp.activity.v1.BroadcastService.EnsureBroadcastGroups:output_type -> hyapp.activity.v1.EnsureBroadcastGroupsResponse + 36, // 179: hyapp.activity.v1.BroadcastService.PublishRegionBroadcast:output_type -> hyapp.activity.v1.PublishBroadcastResponse + 36, // 180: hyapp.activity.v1.BroadcastService.PublishGlobalBroadcast:output_type -> hyapp.activity.v1.PublishBroadcastResponse + 38, // 181: hyapp.activity.v1.BroadcastService.RemoveRegionBroadcastMember:output_type -> hyapp.activity.v1.RemoveRegionBroadcastMemberResponse + 39, // 182: hyapp.activity.v1.BroadcastService.ProcessBroadcastOutboxBatch:output_type -> hyapp.activity.v1.ProcessBroadcastOutboxBatchResponse + 41, // 183: hyapp.activity.v1.RoomEventConsumerService.ConsumeRoomEvent:output_type -> hyapp.activity.v1.ConsumeRoomEventResponse + 44, // 184: hyapp.activity.v1.AdminTaskService.ListTaskDefinitions:output_type -> hyapp.activity.v1.ListTaskDefinitionsResponse + 46, // 185: hyapp.activity.v1.AdminTaskService.UpsertTaskDefinition:output_type -> hyapp.activity.v1.UpsertTaskDefinitionResponse + 48, // 186: hyapp.activity.v1.AdminTaskService.SetTaskDefinitionStatus:output_type -> hyapp.activity.v1.SetTaskDefinitionStatusResponse + 53, // 187: hyapp.activity.v1.RegistrationRewardService.GetRegistrationRewardEligibility:output_type -> hyapp.activity.v1.GetRegistrationRewardEligibilityResponse + 55, // 188: hyapp.activity.v1.RegistrationRewardService.IssueRegistrationReward:output_type -> hyapp.activity.v1.IssueRegistrationRewardResponse + 57, // 189: hyapp.activity.v1.AdminRegistrationRewardService.GetRegistrationRewardConfig:output_type -> hyapp.activity.v1.GetRegistrationRewardConfigResponse + 59, // 190: hyapp.activity.v1.AdminRegistrationRewardService.UpdateRegistrationRewardConfig:output_type -> hyapp.activity.v1.UpdateRegistrationRewardConfigResponse + 61, // 191: hyapp.activity.v1.AdminRegistrationRewardService.ListRegistrationRewardClaims:output_type -> hyapp.activity.v1.ListRegistrationRewardClaimsResponse + 66, // 192: hyapp.activity.v1.SevenDayCheckInService.GetSevenDayCheckInStatus:output_type -> hyapp.activity.v1.GetSevenDayCheckInStatusResponse + 68, // 193: hyapp.activity.v1.SevenDayCheckInService.SignSevenDayCheckIn:output_type -> hyapp.activity.v1.SignSevenDayCheckInResponse + 70, // 194: hyapp.activity.v1.AdminSevenDayCheckInService.GetSevenDayCheckInConfig:output_type -> hyapp.activity.v1.GetSevenDayCheckInConfigResponse + 72, // 195: hyapp.activity.v1.AdminSevenDayCheckInService.UpdateSevenDayCheckInConfig:output_type -> hyapp.activity.v1.UpdateSevenDayCheckInConfigResponse + 75, // 196: hyapp.activity.v1.AdminSevenDayCheckInService.ListSevenDayCheckInClaims:output_type -> hyapp.activity.v1.ListSevenDayCheckInClaimsResponse + 96, // 197: hyapp.activity.v1.AdminGrowthLevelService.ListLevelConfig:output_type -> hyapp.activity.v1.ListLevelConfigResponse + 90, // 198: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTrack:output_type -> hyapp.activity.v1.UpsertLevelTrackResponse + 92, // 199: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelRule:output_type -> hyapp.activity.v1.UpsertLevelRuleResponse + 94, // 200: hyapp.activity.v1.AdminGrowthLevelService.UpsertLevelTier:output_type -> hyapp.activity.v1.UpsertLevelTierResponse + 101, // 201: hyapp.activity.v1.AdminAchievementService.ListAchievementDefinitions:output_type -> hyapp.activity.v1.ListAchievementsResponse + 110, // 202: hyapp.activity.v1.AdminAchievementService.UpsertAchievementDefinition:output_type -> hyapp.activity.v1.UpsertAchievementDefinitionResponse + 120, // 203: hyapp.activity.v1.AdminLuckyGiftService.GetLuckyGiftConfig:output_type -> hyapp.activity.v1.GetLuckyGiftConfigResponse + 122, // 204: hyapp.activity.v1.AdminLuckyGiftService.UpsertLuckyGiftConfig:output_type -> hyapp.activity.v1.UpsertLuckyGiftConfigResponse + 124, // 205: hyapp.activity.v1.AdminLuckyGiftService.ListLuckyGiftConfigs:output_type -> hyapp.activity.v1.ListLuckyGiftConfigsResponse + 126, // 206: hyapp.activity.v1.AdminLuckyGiftService.ListLuckyGiftDraws:output_type -> hyapp.activity.v1.ListLuckyGiftDrawsResponse + 153, // [153:207] is the sub-list for method output_type + 99, // [99:153] is the sub-list for method input_type + 99, // [99:99] is the sub-list for extension type_name + 99, // [99:99] is the sub-list for extension extendee + 0, // [0:99] is the sub-list for field type_name } func init() { file_proto_activity_v1_activity_proto_init() } @@ -11655,7 +11754,7 @@ func file_proto_activity_v1_activity_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_activity_v1_activity_proto_rawDesc), len(file_proto_activity_v1_activity_proto_rawDesc)), NumEnums: 0, - NumMessages: 125, + NumMessages: 127, NumExtensions: 0, NumServices: 17, }, diff --git a/api/proto/activity/v1/activity.proto b/api/proto/activity/v1/activity.proto index e5fa6e98..6b18e8cc 100644 --- a/api/proto/activity/v1/activity.proto +++ b/api/proto/activity/v1/activity.proto @@ -1132,6 +1132,14 @@ message UpsertLuckyGiftConfigResponse { LuckyGiftConfig config = 1; } +message ListLuckyGiftConfigsRequest { + RequestMeta meta = 1; +} + +message ListLuckyGiftConfigsResponse { + repeated LuckyGiftConfig configs = 1; +} + message ListLuckyGiftDrawsRequest { RequestMeta meta = 1; string gift_id = 2; @@ -1266,5 +1274,6 @@ service AdminAchievementService { service AdminLuckyGiftService { rpc GetLuckyGiftConfig(GetLuckyGiftConfigRequest) returns (GetLuckyGiftConfigResponse); rpc UpsertLuckyGiftConfig(UpsertLuckyGiftConfigRequest) returns (UpsertLuckyGiftConfigResponse); + rpc ListLuckyGiftConfigs(ListLuckyGiftConfigsRequest) returns (ListLuckyGiftConfigsResponse); rpc ListLuckyGiftDraws(ListLuckyGiftDrawsRequest) returns (ListLuckyGiftDrawsResponse); } diff --git a/api/proto/activity/v1/activity_grpc.pb.go b/api/proto/activity/v1/activity_grpc.pb.go index 9832ce51..3e67207b 100644 --- a/api/proto/activity/v1/activity_grpc.pb.go +++ b/api/proto/activity/v1/activity_grpc.pb.go @@ -3016,6 +3016,7 @@ var AdminAchievementService_ServiceDesc = grpc.ServiceDesc{ const ( AdminLuckyGiftService_GetLuckyGiftConfig_FullMethodName = "/hyapp.activity.v1.AdminLuckyGiftService/GetLuckyGiftConfig" AdminLuckyGiftService_UpsertLuckyGiftConfig_FullMethodName = "/hyapp.activity.v1.AdminLuckyGiftService/UpsertLuckyGiftConfig" + AdminLuckyGiftService_ListLuckyGiftConfigs_FullMethodName = "/hyapp.activity.v1.AdminLuckyGiftService/ListLuckyGiftConfigs" AdminLuckyGiftService_ListLuckyGiftDraws_FullMethodName = "/hyapp.activity.v1.AdminLuckyGiftService/ListLuckyGiftDraws" ) @@ -3027,6 +3028,7 @@ const ( type AdminLuckyGiftServiceClient interface { GetLuckyGiftConfig(ctx context.Context, in *GetLuckyGiftConfigRequest, opts ...grpc.CallOption) (*GetLuckyGiftConfigResponse, error) UpsertLuckyGiftConfig(ctx context.Context, in *UpsertLuckyGiftConfigRequest, opts ...grpc.CallOption) (*UpsertLuckyGiftConfigResponse, error) + ListLuckyGiftConfigs(ctx context.Context, in *ListLuckyGiftConfigsRequest, opts ...grpc.CallOption) (*ListLuckyGiftConfigsResponse, error) ListLuckyGiftDraws(ctx context.Context, in *ListLuckyGiftDrawsRequest, opts ...grpc.CallOption) (*ListLuckyGiftDrawsResponse, error) } @@ -3058,6 +3060,16 @@ func (c *adminLuckyGiftServiceClient) UpsertLuckyGiftConfig(ctx context.Context, return out, nil } +func (c *adminLuckyGiftServiceClient) ListLuckyGiftConfigs(ctx context.Context, in *ListLuckyGiftConfigsRequest, opts ...grpc.CallOption) (*ListLuckyGiftConfigsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListLuckyGiftConfigsResponse) + err := c.cc.Invoke(ctx, AdminLuckyGiftService_ListLuckyGiftConfigs_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *adminLuckyGiftServiceClient) ListLuckyGiftDraws(ctx context.Context, in *ListLuckyGiftDrawsRequest, opts ...grpc.CallOption) (*ListLuckyGiftDrawsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListLuckyGiftDrawsResponse) @@ -3076,6 +3088,7 @@ func (c *adminLuckyGiftServiceClient) ListLuckyGiftDraws(ctx context.Context, in type AdminLuckyGiftServiceServer interface { GetLuckyGiftConfig(context.Context, *GetLuckyGiftConfigRequest) (*GetLuckyGiftConfigResponse, error) UpsertLuckyGiftConfig(context.Context, *UpsertLuckyGiftConfigRequest) (*UpsertLuckyGiftConfigResponse, error) + ListLuckyGiftConfigs(context.Context, *ListLuckyGiftConfigsRequest) (*ListLuckyGiftConfigsResponse, error) ListLuckyGiftDraws(context.Context, *ListLuckyGiftDrawsRequest) (*ListLuckyGiftDrawsResponse, error) mustEmbedUnimplementedAdminLuckyGiftServiceServer() } @@ -3093,6 +3106,9 @@ func (UnimplementedAdminLuckyGiftServiceServer) GetLuckyGiftConfig(context.Conte func (UnimplementedAdminLuckyGiftServiceServer) UpsertLuckyGiftConfig(context.Context, *UpsertLuckyGiftConfigRequest) (*UpsertLuckyGiftConfigResponse, error) { return nil, status.Error(codes.Unimplemented, "method UpsertLuckyGiftConfig not implemented") } +func (UnimplementedAdminLuckyGiftServiceServer) ListLuckyGiftConfigs(context.Context, *ListLuckyGiftConfigsRequest) (*ListLuckyGiftConfigsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListLuckyGiftConfigs not implemented") +} func (UnimplementedAdminLuckyGiftServiceServer) ListLuckyGiftDraws(context.Context, *ListLuckyGiftDrawsRequest) (*ListLuckyGiftDrawsResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListLuckyGiftDraws not implemented") } @@ -3153,6 +3169,24 @@ func _AdminLuckyGiftService_UpsertLuckyGiftConfig_Handler(srv interface{}, ctx c return interceptor(ctx, in, info, handler) } +func _AdminLuckyGiftService_ListLuckyGiftConfigs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListLuckyGiftConfigsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminLuckyGiftServiceServer).ListLuckyGiftConfigs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminLuckyGiftService_ListLuckyGiftConfigs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminLuckyGiftServiceServer).ListLuckyGiftConfigs(ctx, req.(*ListLuckyGiftConfigsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _AdminLuckyGiftService_ListLuckyGiftDraws_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListLuckyGiftDrawsRequest) if err := dec(in); err != nil { @@ -3186,6 +3220,10 @@ var AdminLuckyGiftService_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpsertLuckyGiftConfig", Handler: _AdminLuckyGiftService_UpsertLuckyGiftConfig_Handler, }, + { + MethodName: "ListLuckyGiftConfigs", + Handler: _AdminLuckyGiftService_ListLuckyGiftConfigs_Handler, + }, { MethodName: "ListLuckyGiftDraws", Handler: _AdminLuckyGiftService_ListLuckyGiftDraws_Handler, diff --git a/api/proto/game/v1/game.pb.go b/api/proto/game/v1/game.pb.go index b640821f..eb7072c1 100644 --- a/api/proto/game/v1/game.pb.go +++ b/api/proto/game/v1/game.pb.go @@ -703,6 +703,9 @@ type LaunchGameRequest struct { GameId string `protobuf:"bytes,4,opt,name=game_id,json=gameId,proto3" json:"game_id,omitempty"` Scene string `protobuf:"bytes,5,opt,name=scene,proto3" json:"scene,omitempty"` RoomId string `protobuf:"bytes,6,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + // access_token is the same bearer token used by the App request. + // Provider adapters pass it through as the game token instead of minting a separate game token. + AccessToken string `protobuf:"bytes,7,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -779,6 +782,13 @@ func (x *LaunchGameRequest) GetRoomId() string { return "" } +func (x *LaunchGameRequest) GetAccessToken() string { + if x != nil { + return x.AccessToken + } + return "" +} + type LaunchGameResponse struct { state protoimpl.MessageState `protogen:"open.v1"` SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` @@ -1737,14 +1747,15 @@ const file_proto_game_v1_game_proto_rawDesc = "" + "\x0fclient_platform\x18\a \x01(\tR\x0eclientPlatform\"g\n" + "\x11ListGamesResponse\x12,\n" + "\x05games\x18\x01 \x03(\v2\x16.hyapp.game.v1.AppGameR\x05games\x12$\n" + - "\x0eserver_time_ms\x18\x02 \x01(\x03R\fserverTimeMs\"\xcc\x01\n" + + "\x0eserver_time_ms\x18\x02 \x01(\x03R\fserverTimeMs\"\xef\x01\n" + "\x11LaunchGameRequest\x12.\n" + "\x04meta\x18\x01 \x01(\v2\x1a.hyapp.game.v1.RequestMetaR\x04meta\x12\x17\n" + "\auser_id\x18\x02 \x01(\x03R\x06userId\x12&\n" + "\x0fdisplay_user_id\x18\x03 \x01(\tR\rdisplayUserId\x12\x17\n" + "\agame_id\x18\x04 \x01(\tR\x06gameId\x12\x14\n" + "\x05scene\x18\x05 \x01(\tR\x05scene\x12\x17\n" + - "\aroom_id\x18\x06 \x01(\tR\x06roomId\"\xbe\x01\n" + + "\aroom_id\x18\x06 \x01(\tR\x06roomId\x12!\n" + + "\faccess_token\x18\a \x01(\tR\vaccessToken\"\xbe\x01\n" + "\x12LaunchGameResponse\x12\x1d\n" + "\n" + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x1d\n" + diff --git a/api/proto/game/v1/game.proto b/api/proto/game/v1/game.proto index a358dd68..2e2030b7 100644 --- a/api/proto/game/v1/game.proto +++ b/api/proto/game/v1/game.proto @@ -88,6 +88,9 @@ message LaunchGameRequest { string game_id = 4; string scene = 5; string room_id = 6; + // access_token is the same bearer token used by the App request. + // Provider adapters pass it through as the game token instead of minting a separate game token. + string access_token = 7; } message LaunchGameResponse { diff --git a/api/proto/user/v1/auth.pb.go b/api/proto/user/v1/auth.pb.go index 23371b07..730f271f 100644 --- a/api/proto/user/v1/auth.pb.go +++ b/api/proto/user/v1/auth.pb.go @@ -454,6 +454,248 @@ func (x *SetPasswordResponse) GetPasswordSet() bool { return false } +// QuickCreateAccountRequest 为测试和三方联调快速创建一个可密码登录的完整账号。 +type QuickCreateAccountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + Avatar string `protobuf:"bytes,4,opt,name=avatar,proto3" json:"avatar,omitempty"` + Gender string `protobuf:"bytes,5,opt,name=gender,proto3" json:"gender,omitempty"` + Country string `protobuf:"bytes,6,opt,name=country,proto3" json:"country,omitempty"` + InviteCode string `protobuf:"bytes,7,opt,name=invite_code,json=inviteCode,proto3" json:"invite_code,omitempty"` + DeviceId string `protobuf:"bytes,8,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"` + Device string `protobuf:"bytes,9,opt,name=device,proto3" json:"device,omitempty"` + OsVersion string `protobuf:"bytes,10,opt,name=os_version,json=osVersion,proto3" json:"os_version,omitempty"` + Birth string `protobuf:"bytes,11,opt,name=birth,proto3" json:"birth,omitempty"` + AppVersion string `protobuf:"bytes,12,opt,name=app_version,json=appVersion,proto3" json:"app_version,omitempty"` + BuildNumber string `protobuf:"bytes,13,opt,name=build_number,json=buildNumber,proto3" json:"build_number,omitempty"` + Source string `protobuf:"bytes,14,opt,name=source,proto3" json:"source,omitempty"` + InstallChannel string `protobuf:"bytes,15,opt,name=install_channel,json=installChannel,proto3" json:"install_channel,omitempty"` + Campaign string `protobuf:"bytes,16,opt,name=campaign,proto3" json:"campaign,omitempty"` + Platform string `protobuf:"bytes,17,opt,name=platform,proto3" json:"platform,omitempty"` + Language string `protobuf:"bytes,18,opt,name=language,proto3" json:"language,omitempty"` + Timezone string `protobuf:"bytes,19,opt,name=timezone,proto3" json:"timezone,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QuickCreateAccountRequest) Reset() { + *x = QuickCreateAccountRequest{} + mi := &file_proto_user_v1_auth_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QuickCreateAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuickCreateAccountRequest) ProtoMessage() {} + +func (x *QuickCreateAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_v1_auth_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QuickCreateAccountRequest.ProtoReflect.Descriptor instead. +func (*QuickCreateAccountRequest) Descriptor() ([]byte, []int) { + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{5} +} + +func (x *QuickCreateAccountRequest) GetMeta() *RequestMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *QuickCreateAccountRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *QuickCreateAccountRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *QuickCreateAccountRequest) GetAvatar() string { + if x != nil { + return x.Avatar + } + return "" +} + +func (x *QuickCreateAccountRequest) GetGender() string { + if x != nil { + return x.Gender + } + return "" +} + +func (x *QuickCreateAccountRequest) GetCountry() string { + if x != nil { + return x.Country + } + return "" +} + +func (x *QuickCreateAccountRequest) GetInviteCode() string { + if x != nil { + return x.InviteCode + } + return "" +} + +func (x *QuickCreateAccountRequest) GetDeviceId() string { + if x != nil { + return x.DeviceId + } + return "" +} + +func (x *QuickCreateAccountRequest) GetDevice() string { + if x != nil { + return x.Device + } + return "" +} + +func (x *QuickCreateAccountRequest) GetOsVersion() string { + if x != nil { + return x.OsVersion + } + return "" +} + +func (x *QuickCreateAccountRequest) GetBirth() string { + if x != nil { + return x.Birth + } + return "" +} + +func (x *QuickCreateAccountRequest) GetAppVersion() string { + if x != nil { + return x.AppVersion + } + return "" +} + +func (x *QuickCreateAccountRequest) GetBuildNumber() string { + if x != nil { + return x.BuildNumber + } + return "" +} + +func (x *QuickCreateAccountRequest) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *QuickCreateAccountRequest) GetInstallChannel() string { + if x != nil { + return x.InstallChannel + } + return "" +} + +func (x *QuickCreateAccountRequest) GetCampaign() string { + if x != nil { + return x.Campaign + } + return "" +} + +func (x *QuickCreateAccountRequest) GetPlatform() string { + if x != nil { + return x.Platform + } + return "" +} + +func (x *QuickCreateAccountRequest) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +func (x *QuickCreateAccountRequest) GetTimezone() string { + if x != nil { + return x.Timezone + } + return "" +} + +// QuickCreateAccountResponse 返回新账号登录态;display_user_id 即后续账号密码登录用账号。 +type QuickCreateAccountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Token *AuthToken `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + PasswordSet bool `protobuf:"varint,2,opt,name=password_set,json=passwordSet,proto3" json:"password_set,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QuickCreateAccountResponse) Reset() { + *x = QuickCreateAccountResponse{} + mi := &file_proto_user_v1_auth_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QuickCreateAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuickCreateAccountResponse) ProtoMessage() {} + +func (x *QuickCreateAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_v1_auth_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QuickCreateAccountResponse.ProtoReflect.Descriptor instead. +func (*QuickCreateAccountResponse) Descriptor() ([]byte, []int) { + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{6} +} + +func (x *QuickCreateAccountResponse) GetToken() *AuthToken { + if x != nil { + return x.Token + } + return nil +} + +func (x *QuickCreateAccountResponse) GetPasswordSet() bool { + if x != nil { + return x.PasswordSet + } + return false +} + // RefreshTokenRequest 使用 refresh token 换取新 token。 type RefreshTokenRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -465,7 +707,7 @@ type RefreshTokenRequest struct { func (x *RefreshTokenRequest) Reset() { *x = RefreshTokenRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[5] + mi := &file_proto_user_v1_auth_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -477,7 +719,7 @@ func (x *RefreshTokenRequest) String() string { func (*RefreshTokenRequest) ProtoMessage() {} func (x *RefreshTokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_user_v1_auth_proto_msgTypes[5] + mi := &file_proto_user_v1_auth_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -490,7 +732,7 @@ func (x *RefreshTokenRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshTokenRequest.ProtoReflect.Descriptor instead. func (*RefreshTokenRequest) Descriptor() ([]byte, []int) { - return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{5} + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{7} } func (x *RefreshTokenRequest) GetMeta() *RequestMeta { @@ -517,7 +759,7 @@ type RefreshTokenResponse struct { func (x *RefreshTokenResponse) Reset() { *x = RefreshTokenResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[6] + mi := &file_proto_user_v1_auth_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -529,7 +771,7 @@ func (x *RefreshTokenResponse) String() string { func (*RefreshTokenResponse) ProtoMessage() {} func (x *RefreshTokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_user_v1_auth_proto_msgTypes[6] + mi := &file_proto_user_v1_auth_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -542,7 +784,7 @@ func (x *RefreshTokenResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshTokenResponse.ProtoReflect.Descriptor instead. func (*RefreshTokenResponse) Descriptor() ([]byte, []int) { - return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{6} + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{8} } func (x *RefreshTokenResponse) GetToken() *AuthToken { @@ -564,7 +806,7 @@ type LogoutRequest struct { func (x *LogoutRequest) Reset() { *x = LogoutRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[7] + mi := &file_proto_user_v1_auth_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -576,7 +818,7 @@ func (x *LogoutRequest) String() string { func (*LogoutRequest) ProtoMessage() {} func (x *LogoutRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_user_v1_auth_proto_msgTypes[7] + mi := &file_proto_user_v1_auth_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -589,7 +831,7 @@ func (x *LogoutRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead. func (*LogoutRequest) Descriptor() ([]byte, []int) { - return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{7} + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{9} } func (x *LogoutRequest) GetMeta() *RequestMeta { @@ -623,7 +865,7 @@ type LogoutResponse struct { func (x *LogoutResponse) Reset() { *x = LogoutResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[8] + mi := &file_proto_user_v1_auth_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -635,7 +877,7 @@ func (x *LogoutResponse) String() string { func (*LogoutResponse) ProtoMessage() {} func (x *LogoutResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_user_v1_auth_proto_msgTypes[8] + mi := &file_proto_user_v1_auth_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -648,7 +890,7 @@ func (x *LogoutResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LogoutResponse.ProtoReflect.Descriptor instead. func (*LogoutResponse) Descriptor() ([]byte, []int) { - return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{8} + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{10} } func (x *LogoutResponse) GetRevoked() bool { @@ -673,7 +915,7 @@ type RecordLoginBlockedRequest struct { func (x *RecordLoginBlockedRequest) Reset() { *x = RecordLoginBlockedRequest{} - mi := &file_proto_user_v1_auth_proto_msgTypes[9] + mi := &file_proto_user_v1_auth_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -685,7 +927,7 @@ func (x *RecordLoginBlockedRequest) String() string { func (*RecordLoginBlockedRequest) ProtoMessage() {} func (x *RecordLoginBlockedRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_user_v1_auth_proto_msgTypes[9] + mi := &file_proto_user_v1_auth_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -698,7 +940,7 @@ func (x *RecordLoginBlockedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RecordLoginBlockedRequest.ProtoReflect.Descriptor instead. func (*RecordLoginBlockedRequest) Descriptor() ([]byte, []int) { - return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{9} + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{11} } func (x *RecordLoginBlockedRequest) GetMeta() *RequestMeta { @@ -753,7 +995,7 @@ type RecordLoginBlockedResponse struct { func (x *RecordLoginBlockedResponse) Reset() { *x = RecordLoginBlockedResponse{} - mi := &file_proto_user_v1_auth_proto_msgTypes[10] + mi := &file_proto_user_v1_auth_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -765,7 +1007,7 @@ func (x *RecordLoginBlockedResponse) String() string { func (*RecordLoginBlockedResponse) ProtoMessage() {} func (x *RecordLoginBlockedResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_user_v1_auth_proto_msgTypes[10] + mi := &file_proto_user_v1_auth_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -778,7 +1020,7 @@ func (x *RecordLoginBlockedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RecordLoginBlockedResponse.ProtoReflect.Descriptor instead. func (*RecordLoginBlockedResponse) Descriptor() ([]byte, []int) { - return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{10} + return file_proto_user_v1_auth_proto_rawDescGZIP(), []int{12} } func (x *RecordLoginBlockedResponse) GetRecorded() bool { @@ -834,7 +1076,34 @@ const file_proto_user_v1_auth_proto_rawDesc = "" + "\auser_id\x18\x02 \x01(\x03R\x06userId\x12\x1a\n" + "\bpassword\x18\x03 \x01(\tR\bpassword\"8\n" + "\x13SetPasswordResponse\x12!\n" + - "\fpassword_set\x18\x01 \x01(\bR\vpasswordSet\"j\n" + + "\fpassword_set\x18\x01 \x01(\bR\vpasswordSet\"\xcd\x04\n" + + "\x19QuickCreateAccountRequest\x12.\n" + + "\x04meta\x18\x01 \x01(\v2\x1a.hyapp.user.v1.RequestMetaR\x04meta\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword\x12\x1a\n" + + "\busername\x18\x03 \x01(\tR\busername\x12\x16\n" + + "\x06avatar\x18\x04 \x01(\tR\x06avatar\x12\x16\n" + + "\x06gender\x18\x05 \x01(\tR\x06gender\x12\x18\n" + + "\acountry\x18\x06 \x01(\tR\acountry\x12\x1f\n" + + "\vinvite_code\x18\a \x01(\tR\n" + + "inviteCode\x12\x1b\n" + + "\tdevice_id\x18\b \x01(\tR\bdeviceId\x12\x16\n" + + "\x06device\x18\t \x01(\tR\x06device\x12\x1d\n" + + "\n" + + "os_version\x18\n" + + " \x01(\tR\tosVersion\x12\x14\n" + + "\x05birth\x18\v \x01(\tR\x05birth\x12\x1f\n" + + "\vapp_version\x18\f \x01(\tR\n" + + "appVersion\x12!\n" + + "\fbuild_number\x18\r \x01(\tR\vbuildNumber\x12\x16\n" + + "\x06source\x18\x0e \x01(\tR\x06source\x12'\n" + + "\x0finstall_channel\x18\x0f \x01(\tR\x0einstallChannel\x12\x1a\n" + + "\bcampaign\x18\x10 \x01(\tR\bcampaign\x12\x1a\n" + + "\bplatform\x18\x11 \x01(\tR\bplatform\x12\x1a\n" + + "\blanguage\x18\x12 \x01(\tR\blanguage\x12\x1a\n" + + "\btimezone\x18\x13 \x01(\tR\btimezone\"o\n" + + "\x1aQuickCreateAccountResponse\x12.\n" + + "\x05token\x18\x01 \x01(\v2\x18.hyapp.user.v1.AuthTokenR\x05token\x12!\n" + + "\fpassword_set\x18\x02 \x01(\bR\vpasswordSet\"j\n" + "\x13RefreshTokenRequest\x12.\n" + "\x04meta\x18\x01 \x01(\v2\x1a.hyapp.user.v1.RequestMetaR\x04meta\x12#\n" + "\rrefresh_token\x18\x02 \x01(\tR\frefreshToken\"F\n" + @@ -855,11 +1124,12 @@ const file_proto_user_v1_auth_proto_rawDesc = "" + "\btimezone\x18\x05 \x01(\tR\btimezone\x12!\n" + "\fblock_reason\x18\x06 \x01(\tR\vblockReason\"8\n" + "\x1aRecordLoginBlockedResponse\x12\x1a\n" + - "\brecorded\x18\x01 \x01(\bR\brecorded2\x98\x04\n" + + "\brecorded\x18\x01 \x01(\bR\brecorded2\x83\x05\n" + "\vAuthService\x12Q\n" + "\rLoginPassword\x12#.hyapp.user.v1.LoginPasswordRequest\x1a\x1b.hyapp.user.v1.AuthResponse\x12U\n" + "\x0fLoginThirdParty\x12%.hyapp.user.v1.LoginThirdPartyRequest\x1a\x1b.hyapp.user.v1.AuthResponse\x12T\n" + - "\vSetPassword\x12!.hyapp.user.v1.SetPasswordRequest\x1a\".hyapp.user.v1.SetPasswordResponse\x12W\n" + + "\vSetPassword\x12!.hyapp.user.v1.SetPasswordRequest\x1a\".hyapp.user.v1.SetPasswordResponse\x12i\n" + + "\x12QuickCreateAccount\x12(.hyapp.user.v1.QuickCreateAccountRequest\x1a).hyapp.user.v1.QuickCreateAccountResponse\x12W\n" + "\fRefreshToken\x12\".hyapp.user.v1.RefreshTokenRequest\x1a#.hyapp.user.v1.RefreshTokenResponse\x12E\n" + "\x06Logout\x12\x1c.hyapp.user.v1.LogoutRequest\x1a\x1d.hyapp.user.v1.LogoutResponse\x12i\n" + "\x12RecordLoginBlocked\x12(.hyapp.user.v1.RecordLoginBlockedRequest\x1a).hyapp.user.v1.RecordLoginBlockedResponseB&Z$hyapp.local/api/proto/user/v1;userv1b\x06proto3" @@ -876,48 +1146,54 @@ func file_proto_user_v1_auth_proto_rawDescGZIP() []byte { return file_proto_user_v1_auth_proto_rawDescData } -var file_proto_user_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_proto_user_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_proto_user_v1_auth_proto_goTypes = []any{ (*LoginPasswordRequest)(nil), // 0: hyapp.user.v1.LoginPasswordRequest (*LoginThirdPartyRequest)(nil), // 1: hyapp.user.v1.LoginThirdPartyRequest (*AuthResponse)(nil), // 2: hyapp.user.v1.AuthResponse (*SetPasswordRequest)(nil), // 3: hyapp.user.v1.SetPasswordRequest (*SetPasswordResponse)(nil), // 4: hyapp.user.v1.SetPasswordResponse - (*RefreshTokenRequest)(nil), // 5: hyapp.user.v1.RefreshTokenRequest - (*RefreshTokenResponse)(nil), // 6: hyapp.user.v1.RefreshTokenResponse - (*LogoutRequest)(nil), // 7: hyapp.user.v1.LogoutRequest - (*LogoutResponse)(nil), // 8: hyapp.user.v1.LogoutResponse - (*RecordLoginBlockedRequest)(nil), // 9: hyapp.user.v1.RecordLoginBlockedRequest - (*RecordLoginBlockedResponse)(nil), // 10: hyapp.user.v1.RecordLoginBlockedResponse - (*RequestMeta)(nil), // 11: hyapp.user.v1.RequestMeta - (*AuthToken)(nil), // 12: hyapp.user.v1.AuthToken + (*QuickCreateAccountRequest)(nil), // 5: hyapp.user.v1.QuickCreateAccountRequest + (*QuickCreateAccountResponse)(nil), // 6: hyapp.user.v1.QuickCreateAccountResponse + (*RefreshTokenRequest)(nil), // 7: hyapp.user.v1.RefreshTokenRequest + (*RefreshTokenResponse)(nil), // 8: hyapp.user.v1.RefreshTokenResponse + (*LogoutRequest)(nil), // 9: hyapp.user.v1.LogoutRequest + (*LogoutResponse)(nil), // 10: hyapp.user.v1.LogoutResponse + (*RecordLoginBlockedRequest)(nil), // 11: hyapp.user.v1.RecordLoginBlockedRequest + (*RecordLoginBlockedResponse)(nil), // 12: hyapp.user.v1.RecordLoginBlockedResponse + (*RequestMeta)(nil), // 13: hyapp.user.v1.RequestMeta + (*AuthToken)(nil), // 14: hyapp.user.v1.AuthToken } var file_proto_user_v1_auth_proto_depIdxs = []int32{ - 11, // 0: hyapp.user.v1.LoginPasswordRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 11, // 1: hyapp.user.v1.LoginThirdPartyRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 12, // 2: hyapp.user.v1.AuthResponse.token:type_name -> hyapp.user.v1.AuthToken - 11, // 3: hyapp.user.v1.SetPasswordRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 11, // 4: hyapp.user.v1.RefreshTokenRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 12, // 5: hyapp.user.v1.RefreshTokenResponse.token:type_name -> hyapp.user.v1.AuthToken - 11, // 6: hyapp.user.v1.LogoutRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 11, // 7: hyapp.user.v1.RecordLoginBlockedRequest.meta:type_name -> hyapp.user.v1.RequestMeta - 0, // 8: hyapp.user.v1.AuthService.LoginPassword:input_type -> hyapp.user.v1.LoginPasswordRequest - 1, // 9: hyapp.user.v1.AuthService.LoginThirdParty:input_type -> hyapp.user.v1.LoginThirdPartyRequest - 3, // 10: hyapp.user.v1.AuthService.SetPassword:input_type -> hyapp.user.v1.SetPasswordRequest - 5, // 11: hyapp.user.v1.AuthService.RefreshToken:input_type -> hyapp.user.v1.RefreshTokenRequest - 7, // 12: hyapp.user.v1.AuthService.Logout:input_type -> hyapp.user.v1.LogoutRequest - 9, // 13: hyapp.user.v1.AuthService.RecordLoginBlocked:input_type -> hyapp.user.v1.RecordLoginBlockedRequest - 2, // 14: hyapp.user.v1.AuthService.LoginPassword:output_type -> hyapp.user.v1.AuthResponse - 2, // 15: hyapp.user.v1.AuthService.LoginThirdParty:output_type -> hyapp.user.v1.AuthResponse - 4, // 16: hyapp.user.v1.AuthService.SetPassword:output_type -> hyapp.user.v1.SetPasswordResponse - 6, // 17: hyapp.user.v1.AuthService.RefreshToken:output_type -> hyapp.user.v1.RefreshTokenResponse - 8, // 18: hyapp.user.v1.AuthService.Logout:output_type -> hyapp.user.v1.LogoutResponse - 10, // 19: hyapp.user.v1.AuthService.RecordLoginBlocked:output_type -> hyapp.user.v1.RecordLoginBlockedResponse - 14, // [14:20] is the sub-list for method output_type - 8, // [8:14] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 13, // 0: hyapp.user.v1.LoginPasswordRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 13, // 1: hyapp.user.v1.LoginThirdPartyRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 14, // 2: hyapp.user.v1.AuthResponse.token:type_name -> hyapp.user.v1.AuthToken + 13, // 3: hyapp.user.v1.SetPasswordRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 13, // 4: hyapp.user.v1.QuickCreateAccountRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 14, // 5: hyapp.user.v1.QuickCreateAccountResponse.token:type_name -> hyapp.user.v1.AuthToken + 13, // 6: hyapp.user.v1.RefreshTokenRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 14, // 7: hyapp.user.v1.RefreshTokenResponse.token:type_name -> hyapp.user.v1.AuthToken + 13, // 8: hyapp.user.v1.LogoutRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 13, // 9: hyapp.user.v1.RecordLoginBlockedRequest.meta:type_name -> hyapp.user.v1.RequestMeta + 0, // 10: hyapp.user.v1.AuthService.LoginPassword:input_type -> hyapp.user.v1.LoginPasswordRequest + 1, // 11: hyapp.user.v1.AuthService.LoginThirdParty:input_type -> hyapp.user.v1.LoginThirdPartyRequest + 3, // 12: hyapp.user.v1.AuthService.SetPassword:input_type -> hyapp.user.v1.SetPasswordRequest + 5, // 13: hyapp.user.v1.AuthService.QuickCreateAccount:input_type -> hyapp.user.v1.QuickCreateAccountRequest + 7, // 14: hyapp.user.v1.AuthService.RefreshToken:input_type -> hyapp.user.v1.RefreshTokenRequest + 9, // 15: hyapp.user.v1.AuthService.Logout:input_type -> hyapp.user.v1.LogoutRequest + 11, // 16: hyapp.user.v1.AuthService.RecordLoginBlocked:input_type -> hyapp.user.v1.RecordLoginBlockedRequest + 2, // 17: hyapp.user.v1.AuthService.LoginPassword:output_type -> hyapp.user.v1.AuthResponse + 2, // 18: hyapp.user.v1.AuthService.LoginThirdParty:output_type -> hyapp.user.v1.AuthResponse + 4, // 19: hyapp.user.v1.AuthService.SetPassword:output_type -> hyapp.user.v1.SetPasswordResponse + 6, // 20: hyapp.user.v1.AuthService.QuickCreateAccount:output_type -> hyapp.user.v1.QuickCreateAccountResponse + 8, // 21: hyapp.user.v1.AuthService.RefreshToken:output_type -> hyapp.user.v1.RefreshTokenResponse + 10, // 22: hyapp.user.v1.AuthService.Logout:output_type -> hyapp.user.v1.LogoutResponse + 12, // 23: hyapp.user.v1.AuthService.RecordLoginBlocked:output_type -> hyapp.user.v1.RecordLoginBlockedResponse + 17, // [17:24] is the sub-list for method output_type + 10, // [10:17] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_proto_user_v1_auth_proto_init() } @@ -932,7 +1208,7 @@ func file_proto_user_v1_auth_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_user_v1_auth_proto_rawDesc), len(file_proto_user_v1_auth_proto_rawDesc)), NumEnums: 0, - NumMessages: 11, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/api/proto/user/v1/auth.proto b/api/proto/user/v1/auth.proto index 9540a956..41be332c 100644 --- a/api/proto/user/v1/auth.proto +++ b/api/proto/user/v1/auth.proto @@ -57,6 +57,35 @@ message SetPasswordResponse { bool password_set = 1; } +// QuickCreateAccountRequest 为测试和三方联调快速创建一个可密码登录的完整账号。 +message QuickCreateAccountRequest { + RequestMeta meta = 1; + string password = 2; + string username = 3; + string avatar = 4; + string gender = 5; + string country = 6; + string invite_code = 7; + string device_id = 8; + string device = 9; + string os_version = 10; + string birth = 11; + string app_version = 12; + string build_number = 13; + string source = 14; + string install_channel = 15; + string campaign = 16; + string platform = 17; + string language = 18; + string timezone = 19; +} + +// QuickCreateAccountResponse 返回新账号登录态;display_user_id 即后续账号密码登录用账号。 +message QuickCreateAccountResponse { + AuthToken token = 1; + bool password_set = 2; +} + // RefreshTokenRequest 使用 refresh token 换取新 token。 message RefreshTokenRequest { RequestMeta meta = 1; @@ -100,6 +129,7 @@ service AuthService { rpc LoginPassword(LoginPasswordRequest) returns (AuthResponse); rpc LoginThirdParty(LoginThirdPartyRequest) returns (AuthResponse); rpc SetPassword(SetPasswordRequest) returns (SetPasswordResponse); + rpc QuickCreateAccount(QuickCreateAccountRequest) returns (QuickCreateAccountResponse); rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse); rpc Logout(LogoutRequest) returns (LogoutResponse); rpc RecordLoginBlocked(RecordLoginBlockedRequest) returns (RecordLoginBlockedResponse); diff --git a/api/proto/user/v1/auth_grpc.pb.go b/api/proto/user/v1/auth_grpc.pb.go index b9036787..ca14551d 100644 --- a/api/proto/user/v1/auth_grpc.pb.go +++ b/api/proto/user/v1/auth_grpc.pb.go @@ -22,6 +22,7 @@ const ( AuthService_LoginPassword_FullMethodName = "/hyapp.user.v1.AuthService/LoginPassword" AuthService_LoginThirdParty_FullMethodName = "/hyapp.user.v1.AuthService/LoginThirdParty" AuthService_SetPassword_FullMethodName = "/hyapp.user.v1.AuthService/SetPassword" + AuthService_QuickCreateAccount_FullMethodName = "/hyapp.user.v1.AuthService/QuickCreateAccount" AuthService_RefreshToken_FullMethodName = "/hyapp.user.v1.AuthService/RefreshToken" AuthService_Logout_FullMethodName = "/hyapp.user.v1.AuthService/Logout" AuthService_RecordLoginBlocked_FullMethodName = "/hyapp.user.v1.AuthService/RecordLoginBlocked" @@ -36,6 +37,7 @@ type AuthServiceClient interface { LoginPassword(ctx context.Context, in *LoginPasswordRequest, opts ...grpc.CallOption) (*AuthResponse, error) LoginThirdParty(ctx context.Context, in *LoginThirdPartyRequest, opts ...grpc.CallOption) (*AuthResponse, error) SetPassword(ctx context.Context, in *SetPasswordRequest, opts ...grpc.CallOption) (*SetPasswordResponse, error) + QuickCreateAccount(ctx context.Context, in *QuickCreateAccountRequest, opts ...grpc.CallOption) (*QuickCreateAccountResponse, error) RefreshToken(ctx context.Context, in *RefreshTokenRequest, opts ...grpc.CallOption) (*RefreshTokenResponse, error) Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error) RecordLoginBlocked(ctx context.Context, in *RecordLoginBlockedRequest, opts ...grpc.CallOption) (*RecordLoginBlockedResponse, error) @@ -79,6 +81,16 @@ func (c *authServiceClient) SetPassword(ctx context.Context, in *SetPasswordRequ return out, nil } +func (c *authServiceClient) QuickCreateAccount(ctx context.Context, in *QuickCreateAccountRequest, opts ...grpc.CallOption) (*QuickCreateAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QuickCreateAccountResponse) + err := c.cc.Invoke(ctx, AuthService_QuickCreateAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *authServiceClient) RefreshToken(ctx context.Context, in *RefreshTokenRequest, opts ...grpc.CallOption) (*RefreshTokenResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(RefreshTokenResponse) @@ -118,6 +130,7 @@ type AuthServiceServer interface { LoginPassword(context.Context, *LoginPasswordRequest) (*AuthResponse, error) LoginThirdParty(context.Context, *LoginThirdPartyRequest) (*AuthResponse, error) SetPassword(context.Context, *SetPasswordRequest) (*SetPasswordResponse, error) + QuickCreateAccount(context.Context, *QuickCreateAccountRequest) (*QuickCreateAccountResponse, error) RefreshToken(context.Context, *RefreshTokenRequest) (*RefreshTokenResponse, error) Logout(context.Context, *LogoutRequest) (*LogoutResponse, error) RecordLoginBlocked(context.Context, *RecordLoginBlockedRequest) (*RecordLoginBlockedResponse, error) @@ -140,6 +153,9 @@ func (UnimplementedAuthServiceServer) LoginThirdParty(context.Context, *LoginThi func (UnimplementedAuthServiceServer) SetPassword(context.Context, *SetPasswordRequest) (*SetPasswordResponse, error) { return nil, status.Error(codes.Unimplemented, "method SetPassword not implemented") } +func (UnimplementedAuthServiceServer) QuickCreateAccount(context.Context, *QuickCreateAccountRequest) (*QuickCreateAccountResponse, error) { + return nil, status.Error(codes.Unimplemented, "method QuickCreateAccount not implemented") +} func (UnimplementedAuthServiceServer) RefreshToken(context.Context, *RefreshTokenRequest) (*RefreshTokenResponse, error) { return nil, status.Error(codes.Unimplemented, "method RefreshToken not implemented") } @@ -224,6 +240,24 @@ func _AuthService_SetPassword_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _AuthService_QuickCreateAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuickCreateAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).QuickCreateAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthService_QuickCreateAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).QuickCreateAccount(ctx, req.(*QuickCreateAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _AuthService_RefreshToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RefreshTokenRequest) if err := dec(in); err != nil { @@ -297,6 +331,10 @@ var AuthService_ServiceDesc = grpc.ServiceDesc{ MethodName: "SetPassword", Handler: _AuthService_SetPassword_Handler, }, + { + MethodName: "QuickCreateAccount", + Handler: _AuthService_QuickCreateAccount_Handler, + }, { MethodName: "RefreshToken", Handler: _AuthService_RefreshToken_Handler, diff --git a/server/admin/internal/integration/activityclient/client.go b/server/admin/internal/integration/activityclient/client.go index 738db92a..a3de8b6e 100644 --- a/server/admin/internal/integration/activityclient/client.go +++ b/server/admin/internal/integration/activityclient/client.go @@ -23,6 +23,7 @@ type Client interface { ListSevenDayCheckInClaims(ctx context.Context, req *activityv1.ListSevenDayCheckInClaimsRequest) (*activityv1.ListSevenDayCheckInClaimsResponse, error) GetLuckyGiftConfig(ctx context.Context, req *activityv1.GetLuckyGiftConfigRequest) (*activityv1.GetLuckyGiftConfigResponse, error) UpsertLuckyGiftConfig(ctx context.Context, req *activityv1.UpsertLuckyGiftConfigRequest) (*activityv1.UpsertLuckyGiftConfigResponse, error) + ListLuckyGiftConfigs(ctx context.Context, req *activityv1.ListLuckyGiftConfigsRequest) (*activityv1.ListLuckyGiftConfigsResponse, error) ListLuckyGiftDraws(ctx context.Context, req *activityv1.ListLuckyGiftDrawsRequest) (*activityv1.ListLuckyGiftDrawsResponse, error) RemoveRegionBroadcastMember(ctx context.Context, req *activityv1.RemoveRegionBroadcastMemberRequest) (*activityv1.RemoveRegionBroadcastMemberResponse, error) ListLevelConfig(ctx context.Context, req *activityv1.ListLevelConfigRequest) (*activityv1.ListLevelConfigResponse, error) @@ -105,6 +106,10 @@ func (c *GRPCClient) UpsertLuckyGiftConfig(ctx context.Context, req *activityv1. return c.luckyGiftClient.UpsertLuckyGiftConfig(ctx, req) } +func (c *GRPCClient) ListLuckyGiftConfigs(ctx context.Context, req *activityv1.ListLuckyGiftConfigsRequest) (*activityv1.ListLuckyGiftConfigsResponse, error) { + return c.luckyGiftClient.ListLuckyGiftConfigs(ctx, req) +} + func (c *GRPCClient) ListLuckyGiftDraws(ctx context.Context, req *activityv1.ListLuckyGiftDrawsRequest) (*activityv1.ListLuckyGiftDrawsResponse, error) { return c.luckyGiftClient.ListLuckyGiftDraws(ctx, req) } diff --git a/server/admin/internal/modules/luckygift/handler.go b/server/admin/internal/modules/luckygift/handler.go index 651f13de..80ab1d1f 100644 --- a/server/admin/internal/modules/luckygift/handler.go +++ b/server/admin/internal/modules/luckygift/handler.go @@ -138,6 +138,21 @@ func (h *Handler) UpsertLuckyGiftConfig(c *gin.Context) { response.OK(c, item) } +func (h *Handler) ListLuckyGiftConfigs(c *gin.Context) { + resp, err := h.activity.ListLuckyGiftConfigs(c.Request.Context(), &activityv1.ListLuckyGiftConfigsRequest{ + Meta: h.meta(c), + }) + if err != nil { + response.ServerError(c, "获取幸运礼物奖池列表失败") + return + } + items := make([]configDTO, 0, len(resp.GetConfigs())) + for _, config := range resp.GetConfigs() { + items = append(items, configFromProto(config)) + } + response.OK(c, items) +} + func (h *Handler) ListLuckyGiftDraws(c *gin.Context) { options := shared.ListOptions(c) resp, err := h.activity.ListLuckyGiftDraws(c.Request.Context(), &activityv1.ListLuckyGiftDrawsRequest{ diff --git a/server/admin/internal/modules/luckygift/routes.go b/server/admin/internal/modules/luckygift/routes.go index 6ee1165d..cb00cc35 100644 --- a/server/admin/internal/modules/luckygift/routes.go +++ b/server/admin/internal/modules/luckygift/routes.go @@ -13,5 +13,6 @@ func RegisterRoutes(protected *gin.RouterGroup, h *Handler) { protected.GET("/admin/activity/lucky-gifts/config", middleware.RequirePermission("lucky-gift:view"), h.GetLuckyGiftConfig) protected.PUT("/admin/activity/lucky-gifts/config", middleware.RequirePermission("lucky-gift:update"), h.UpsertLuckyGiftConfig) + protected.GET("/admin/activity/lucky-gifts/configs", middleware.RequirePermission("lucky-gift:view"), h.ListLuckyGiftConfigs) protected.GET("/admin/activity/lucky-gifts/draws", middleware.RequirePermission("lucky-gift:view"), h.ListLuckyGiftDraws) } diff --git a/services/activity-service/internal/service/luckygift/service.go b/services/activity-service/internal/service/luckygift/service.go index beeb82f9..04e76a96 100644 --- a/services/activity-service/internal/service/luckygift/service.go +++ b/services/activity-service/internal/service/luckygift/service.go @@ -14,6 +14,7 @@ import ( type Repository interface { GetLuckyGiftConfig(ctx context.Context, poolID string) (domain.Config, bool, error) UpsertLuckyGiftConfig(ctx context.Context, config domain.Config, nowMS int64) (domain.Config, error) + ListLuckyGiftConfigs(ctx context.Context) ([]domain.Config, error) CheckLuckyGift(ctx context.Context, cmd domain.CheckCommand) (domain.CheckResult, error) ExecuteLuckyGiftDraw(ctx context.Context, cmd domain.DrawCommand, nowMS int64) (domain.DrawResult, error) ListLuckyGiftDraws(ctx context.Context, query domain.DrawQuery) ([]domain.DrawResult, int64, error) @@ -96,6 +97,13 @@ func (s *Service) UpsertConfig(ctx context.Context, config domain.Config) (domai return s.repository.UpsertLuckyGiftConfig(ctx, config, s.now().UTC().UnixMilli()) } +func (s *Service) ListConfigs(ctx context.Context) ([]domain.Config, error) { + if err := s.requireRepository(); err != nil { + return nil, err + } + return s.repository.ListLuckyGiftConfigs(ctx) +} + func (s *Service) ListDraws(ctx context.Context, query domain.DrawQuery) ([]domain.DrawResult, int64, error) { if err := s.requireRepository(); err != nil { return nil, 0, err diff --git a/services/activity-service/internal/service/luckygift/service_test.go b/services/activity-service/internal/service/luckygift/service_test.go index ea819df0..953c0c9b 100644 --- a/services/activity-service/internal/service/luckygift/service_test.go +++ b/services/activity-service/internal/service/luckygift/service_test.go @@ -53,6 +53,10 @@ func (r *fakeLuckyGiftRepository) UpsertLuckyGiftConfig(_ context.Context, confi return config, nil } +func (r *fakeLuckyGiftRepository) ListLuckyGiftConfigs(context.Context) ([]domain.Config, error) { + return nil, nil +} + func (r *fakeLuckyGiftRepository) CheckLuckyGift(context.Context, domain.CheckCommand) (domain.CheckResult, error) { return domain.CheckResult{}, nil } diff --git a/services/activity-service/internal/storage/mysql/lucky_gift_repository.go b/services/activity-service/internal/storage/mysql/lucky_gift_repository.go index 7edaa06f..d1449814 100644 --- a/services/activity-service/internal/storage/mysql/lucky_gift_repository.go +++ b/services/activity-service/internal/storage/mysql/lucky_gift_repository.go @@ -232,6 +232,41 @@ func (r *Repository) UpsertLuckyGiftConfig(ctx context.Context, config domain.Co return config, nil } +func (r *Repository) ListLuckyGiftConfigs(ctx context.Context) ([]domain.Config, error) { + if r == nil || r.db == nil { + return nil, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + appCode := appcode.FromContext(ctx) + rows, err := r.db.QueryContext(ctx, ` + SELECT app_code, gift_id, enabled, rule_version, gift_price, target_rtp_ppm, pool_rate_ppm, + global_window_draws, gift_window_draws, novice_draw_limit, intermediate_draw_limit, + high_multiplier, high_water_pool_multiple, platform_pool_weight_ppm, room_pool_weight_ppm, + gift_pool_weight_ppm, initial_platform_pool, initial_gift_pool, initial_room_pool, + platform_reserve, gift_reserve, room_reserve, max_single_payout, user_hourly_payout_cap, + user_daily_payout_cap, device_daily_payout_cap, room_hourly_payout_cap, anchor_daily_payout_cap, + room_atmosphere_rate_ppm, room_atmosphere_initial, room_atmosphere_reserve, + activity_budget, activity_daily_limit, large_tier_enabled, + COALESCE(CAST(tiers_json AS CHAR), '[]'), updated_by_admin_id, created_at_ms, updated_at_ms + FROM lucky_gift_rules + WHERE app_code = ? + ORDER BY updated_at_ms DESC, gift_id ASC`, + appCode, + ) + if err != nil { + return nil, err + } + defer rows.Close() + configs := make([]domain.Config, 0) + for rows.Next() { + config, err := scanLuckyConfig(rows) + if err != nil { + return nil, err + } + configs = append(configs, config) + } + return configs, rows.Err() +} + func (r *Repository) CheckLuckyGift(ctx context.Context, cmd domain.CheckCommand) (domain.CheckResult, error) { poolID := luckyPoolID(cmd.PoolID) config, exists, err := r.GetLuckyGiftConfig(ctx, poolID) @@ -621,6 +656,10 @@ type luckyQueryer interface { QueryRowContext(context.Context, string, ...any) *sql.Row } +type luckyScanner interface { + Scan(...any) error +} + func (r *Repository) getLuckyGiftConfig(ctx context.Context, q luckyQueryer, appCode string, giftID string, forUpdate bool) (domain.Config, bool, error) { if giftID == "" { return domain.Config{}, false, nil @@ -643,9 +682,20 @@ func (r *Repository) getLuckyGiftConfig(ctx context.Context, q luckyQueryer, app WHERE app_code = ? AND gift_id = ?`+lockSQL, appCode, giftID, ) + config, err := scanLuckyConfig(row) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return domain.Config{}, false, nil + } + return domain.Config{}, false, err + } + return config, true, nil +} + +func scanLuckyConfig(scanner luckyScanner) (domain.Config, error) { var config domain.Config var tiersJSON string - if err := row.Scan(&config.AppCode, &config.GiftID, &config.Enabled, &config.RuleVersion, &config.GiftPrice, &config.TargetRTPPPM, &config.PoolRatePPM, + if err := scanner.Scan(&config.AppCode, &config.GiftID, &config.Enabled, &config.RuleVersion, &config.GiftPrice, &config.TargetRTPPPM, &config.PoolRatePPM, &config.GlobalWindowDraws, &config.GiftWindowDraws, &config.NoviceDrawLimit, &config.IntermediateDrawLimit, &config.HighMultiplier, &config.HighWaterPoolMultiple, &config.PlatformPoolWeightPPM, &config.RoomPoolWeightPPM, &config.GiftPoolWeightPPM, &config.InitialPlatformPool, &config.InitialGiftPool, &config.InitialRoomPool, @@ -654,17 +704,14 @@ func (r *Repository) getLuckyGiftConfig(ctx context.Context, q luckyQueryer, app &config.RoomAtmosphereRatePPM, &config.RoomAtmosphereInitial, &config.RoomAtmosphereReserve, &config.ActivityBudget, &config.ActivityDailyLimit, &config.LargeTierEnabled, &tiersJSON, &config.UpdatedByAdminID, &config.CreatedAtMS, &config.UpdatedAtMS); err != nil { - if errors.Is(err, sql.ErrNoRows) { - return domain.Config{}, false, nil - } - return domain.Config{}, false, err + return domain.Config{}, err } if err := json.Unmarshal([]byte(tiersJSON), &config.Tiers); err != nil { - return domain.Config{}, false, err + return domain.Config{}, err } config.PoolID = config.GiftID config.MultiplierPPMs = luckyMultiplierPPMsFromTiers(config.Tiers, config.GiftPrice) - return config, true, nil + return config, nil } func (r *Repository) getLuckyUserPaidDraws(ctx context.Context, appCode string, userID int64, giftID string) (int64, error) { diff --git a/services/activity-service/internal/transport/grpc/lucky_gift_server.go b/services/activity-service/internal/transport/grpc/lucky_gift_server.go index 3c912887..34648ae4 100644 --- a/services/activity-service/internal/transport/grpc/lucky_gift_server.go +++ b/services/activity-service/internal/transport/grpc/lucky_gift_server.go @@ -95,6 +95,19 @@ func (s *AdminLuckyGiftServer) UpsertLuckyGiftConfig(ctx context.Context, req *a return &activityv1.UpsertLuckyGiftConfigResponse{Config: luckyConfigToProto(updated)}, nil } +func (s *AdminLuckyGiftServer) ListLuckyGiftConfigs(ctx context.Context, req *activityv1.ListLuckyGiftConfigsRequest) (*activityv1.ListLuckyGiftConfigsResponse, error) { + ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) + configs, err := s.svc.ListConfigs(ctx) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + resp := &activityv1.ListLuckyGiftConfigsResponse{Configs: make([]*activityv1.LuckyGiftConfig, 0, len(configs))} + for _, config := range configs { + resp.Configs = append(resp.Configs, luckyConfigToProto(config)) + } + return resp, nil +} + func (s *AdminLuckyGiftServer) ListLuckyGiftDraws(ctx context.Context, req *activityv1.ListLuckyGiftDrawsRequest) (*activityv1.ListLuckyGiftDrawsResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) draws, total, err := s.svc.ListDraws(ctx, domain.DrawQuery{ diff --git a/services/game-service/internal/service/game/leadercc_adapter.go b/services/game-service/internal/service/game/leadercc_adapter.go index b1c072b8..50bbac7c 100644 --- a/services/game-service/internal/service/game/leadercc_adapter.go +++ b/services/game-service/internal/service/game/leadercc_adapter.go @@ -62,11 +62,7 @@ func (c leaderccAdapterConfig) TokenTTL() time.Duration { } func (s *Service) handleLeaderCCOperation(ctx context.Context, app string, platform gamedomain.Platform, req *gamev1.CallbackRequest, operation string, requestHash string) ([]byte, string, string, bool, string, error) { - // 灵仙是明文 JSON + MD5 签名,所以先做 IP 白名单,再进入具体接口校验签名。 - if !callbackIPAllowed(req, platform.CallbackIPWhitelist) { - raw, contentType := leaderccJSON(leaderccCodeRiskRejected, "ip forbidden", map[string]any{}) - return raw, contentType, strconv.Itoa(leaderccCodeRiskRejected), false, "", nil - } + // 灵仙不做 IP 白名单过滤,来源校验只依赖每个接口的 MD5 签名和 token/session 绑定。 switch operation { // operation 由统一 callback 路由传入,兼容不同命名可以减少网关层特殊分支。 case "userinfo", "user_info", "get_user_info": diff --git a/services/game-service/internal/service/game/service.go b/services/game-service/internal/service/game/service.go index d3cc5b3f..200789c8 100644 --- a/services/game-service/internal/service/game/service.go +++ b/services/game-service/internal/service/game/service.go @@ -102,6 +102,7 @@ type LaunchCommand struct { GameID string Scene string RoomID string + AccessToken string } type LaunchResult struct { @@ -183,7 +184,13 @@ func (s *Service) LaunchGame(ctx context.Context, command LaunchCommand) (Launch now := s.now() sessionID := "game_sess_" + strconv.FormatInt(now.UnixMilli(), 10) + "_" + randomHex(6) - token := "gt_" + randomHex(24) + token := strings.TrimSpace(command.AccessToken) + if token == "" { + if strings.EqualFold(game.AdapterType, gamedomain.AdapterYomiV4) || strings.EqualFold(game.AdapterType, gamedomain.AdapterLeaderCCV1) { + return LaunchResult{}, xerr.New(xerr.InvalidArgument, "access token is required for provider game launch") + } + token = "gt_" + randomHex(24) + } sessionTTL := s.config.LaunchSessionTTL // 三方游戏会在 H5 运行期间持续回调 token;厂商适配器可以把默认 15 分钟启动 TTL 拉长。 if strings.EqualFold(game.AdapterType, gamedomain.AdapterYomiV4) { @@ -542,6 +549,10 @@ func normalizeScene(scene string) string { func buildLaunchURL(game gamedomain.LaunchableGame, session gamedomain.LaunchSession, token string) (string, error) { base := strings.TrimSpace(game.APIBaseURL) + if strings.EqualFold(game.AdapterType, gamedomain.AdapterLeaderCCV1) && base == "" { + // 灵仙当前只需要我们提供回调域名和接口,不要求服务端拼 H5/Auth URL。 + return "", nil + } if base == "" { // demo 平台可以没有真实厂商域名,保留本地默认地址用于开发自测。 base = "https://game.example.local/h5" diff --git a/services/game-service/internal/service/game/service_test.go b/services/game-service/internal/service/game/service_test.go index 9808a38e..cd3f98bb 100644 --- a/services/game-service/internal/service/game/service_test.go +++ b/services/game-service/internal/service/game/service_test.go @@ -91,6 +91,7 @@ func TestLaunchGameBuildsYomiAuthURL(t *testing.T) { DisplayUserID: "420001", GameID: "yomi_fish_001", RoomID: "room_1", + AccessToken: "app_access_token_yomi", }) if err != nil { t.Fatalf("LaunchGame failed: %v", err) @@ -98,7 +99,7 @@ func TestLaunchGameBuildsYomiAuthURL(t *testing.T) { if result.ExpiresAtMS != 1700086400000 { t.Fatalf("yomi launch must use adapter token ttl, got %+v", result) } - for _, part := range []string{"gameUid=33", "platUserId=42", "lang=en", "gameLevelUid=0", "platRoomId=room_1", "platAuthCode=gt_"} { + for _, part := range []string{"gameUid=33", "platUserId=42", "lang=en", "gameLevelUid=0", "platRoomId=room_1", "platAuthCode=app_access_token_yomi"} { if !strings.Contains(result.LaunchURL, part) { t.Fatalf("yomi launch url missing %s: %s", part, result.LaunchURL) } @@ -132,6 +133,7 @@ func TestLaunchGameBuildsLeaderCCURL(t *testing.T) { DisplayUserID: "420001", GameID: "lingxian_rocket_001", RoomID: "room_1", + AccessToken: "app_access_token_lingxian", }) if err != nil { t.Fatalf("LaunchGame failed: %v", err) @@ -139,13 +141,47 @@ func TestLaunchGameBuildsLeaderCCURL(t *testing.T) { if result.ExpiresAtMS != 1700086400000 { t.Fatalf("leadercc launch must use adapter token ttl, got %+v", result) } - for _, part := range []string{"uid=420001", "token=gt_", "lang=zh-CN", "roomid=room_1"} { + for _, part := range []string{"uid=420001", "token=app_access_token_lingxian", "lang=zh-CN", "roomid=room_1"} { if !strings.Contains(result.LaunchURL, part) { t.Fatalf("leadercc launch url missing %s: %s", part, result.LaunchURL) } } } +func TestLaunchGameAllowsLeaderCCWithoutLaunchURL(t *testing.T) { + repo := &fakeRepository{ + launchable: gamedomain.LaunchableGame{ + CatalogItem: gamedomain.CatalogItem{ + AppCode: "lalu", + GameID: "lingxian_rocket_001", + PlatformCode: "lingxian", + ProviderGameID: "101", + GameName: "Rocket", + Status: gamedomain.StatusActive, + }, + PlatformStatus: gamedomain.StatusActive, + AdapterType: gamedomain.AdapterLeaderCCV1, + AdapterConfigJSON: `{"token_ttl_seconds":86400}`, + }, + } + svc := New(Config{LaunchSessionTTL: 15 * time.Minute}, repo, &fakeWallet{}, &fakeUser{}) + svc.now = func() time.Time { return time.UnixMilli(1700000000000) } + + result, err := svc.LaunchGame(context.Background(), LaunchCommand{ + AppCode: "lalu", + UserID: 42, + DisplayUserID: "420001", + GameID: "lingxian_rocket_001", + AccessToken: "app_access_token_lingxian", + }) + if err != nil { + t.Fatalf("LaunchGame failed: %v", err) + } + if result.LaunchURL != "" || repo.session.LaunchTokenHash != stableHash("app_access_token_lingxian") { + t.Fatalf("leadercc without launch url should only create session: result=%+v session=%+v", result, repo.session) + } +} + func TestHandleLeaderCCUserInfoValidatesSignAndToken(t *testing.T) { key := "leadercc-test-key" token := "gt_lingxian_token" @@ -181,7 +217,7 @@ func TestHandleLeaderCCUserInfoValidatesSignAndToken(t *testing.T) { PlatformCode: "lingxian", Operation: "userinfo", RawBody: []byte(`{"gameId":"101","uid":"420001","token":"` + token + `","roomId":"room_1","sign":"` + sign + `"}`), - RemoteAddr: "3.1.174.194:443", + RemoteAddr: "203.0.113.10:443", }) if err != nil { t.Fatalf("HandleCallback failed: %v", err) diff --git a/services/game-service/internal/transport/grpc/server.go b/services/game-service/internal/transport/grpc/server.go index a2e0f696..9feabe0b 100644 --- a/services/game-service/internal/transport/grpc/server.go +++ b/services/game-service/internal/transport/grpc/server.go @@ -57,6 +57,7 @@ func (s *Server) LaunchGame(ctx context.Context, req *gamev1.LaunchGameRequest) GameID: req.GetGameId(), Scene: req.GetScene(), RoomID: req.GetRoomId(), + AccessToken: req.GetAccessToken(), }) if err != nil { return nil, xerr.ToGRPCError(err) diff --git a/services/gateway-service/internal/client/user_client.go b/services/gateway-service/internal/client/user_client.go index 6577debe..f3cf1645 100644 --- a/services/gateway-service/internal/client/user_client.go +++ b/services/gateway-service/internal/client/user_client.go @@ -13,6 +13,7 @@ type UserAuthClient interface { LoginPassword(ctx context.Context, req *userv1.LoginPasswordRequest) (*userv1.AuthResponse, error) LoginThirdParty(ctx context.Context, req *userv1.LoginThirdPartyRequest) (*userv1.AuthResponse, error) SetPassword(ctx context.Context, req *userv1.SetPasswordRequest) (*userv1.SetPasswordResponse, error) + QuickCreateAccount(ctx context.Context, req *userv1.QuickCreateAccountRequest) (*userv1.QuickCreateAccountResponse, error) RefreshToken(ctx context.Context, req *userv1.RefreshTokenRequest) (*userv1.RefreshTokenResponse, error) Logout(ctx context.Context, req *userv1.LogoutRequest) (*userv1.LogoutResponse, error) RecordLoginBlocked(ctx context.Context, req *userv1.RecordLoginBlockedRequest) (*userv1.RecordLoginBlockedResponse, error) @@ -177,6 +178,10 @@ func (c *grpcUserAuthClient) SetPassword(ctx context.Context, req *userv1.SetPas return c.client.SetPassword(ctx, req) } +func (c *grpcUserAuthClient) QuickCreateAccount(ctx context.Context, req *userv1.QuickCreateAccountRequest) (*userv1.QuickCreateAccountResponse, error) { + return c.client.QuickCreateAccount(ctx, req) +} + func (c *grpcUserAuthClient) RefreshToken(ctx context.Context, req *userv1.RefreshTokenRequest) (*userv1.RefreshTokenResponse, error) { return c.client.RefreshToken(ctx, req) } diff --git a/services/gateway-service/internal/transport/http/auth_handler.go b/services/gateway-service/internal/transport/http/auth_handler.go index 3ab2d62d..e4afadf4 100644 --- a/services/gateway-service/internal/transport/http/auth_handler.go +++ b/services/gateway-service/internal/transport/http/auth_handler.go @@ -5,11 +5,13 @@ import ( "net" "net/http" "net/netip" + "strconv" "strings" "time" userv1 "hyapp.local/api/proto/user/v1" "hyapp/pkg/appcode" + "hyapp/pkg/idgen" "hyapp/services/gateway-service/internal/auth" ) @@ -31,6 +33,16 @@ type authTokenData struct { OnboardingStatus string `json:"onboarding_status"` } +// quickCreateAccountData 直接把联调最关心的 uid/token 放到顶层,token 内仍保留标准登录响应。 +type quickCreateAccountData struct { + UID string `json:"uid"` + Account string `json:"account"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token,omitempty"` + PasswordSet bool `json:"password_set"` + Token authTokenData `json:"token"` +} + // loginPassword 处理账号密码登录;账号就是当前有效短号。 func (h *Handler) loginPassword(writer http.ResponseWriter, request *http.Request) { var body struct { @@ -78,6 +90,126 @@ func (h *Handler) loginPassword(writer http.ResponseWriter, request *http.Reques httpkit.WriteOK(writer, request, authData(resp.GetToken(), nil)) } +// quickCreateAccount 为游戏厂商联调快速创建一个完整账号;返回 uid 即 App 登录账号和游戏 uid。 +func (h *Handler) quickCreateAccount(writer http.ResponseWriter, request *http.Request) { + var body struct { + Password string `json:"password"` + Username string `json:"username"` + Avatar string `json:"avatar"` + Gender string `json:"gender"` + Country string `json:"country"` + InviteCode string `json:"invite_code"` + DeviceID string `json:"device_id"` + Device string `json:"device"` + OSVersion string `json:"os_version"` + Birth string `json:"birth"` + AppVersion string `json:"app_version"` + BuildNumber string `json:"build_number"` + Source string `json:"source"` + InstallChannel string `json:"install_channel"` + Campaign string `json:"campaign"` + Platform string `json:"platform"` + Language string `json:"language"` + Timezone string `json:"timezone"` + } + if !decode(writer, request, &body) { + return + } + body.Password = strings.TrimSpace(body.Password) + if body.Password == "" { + httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument") + return + } + + // 默认值全部保持可落库、可登录、可过 user-service 资料校验;调用方仍可按需覆盖。 + if strings.TrimSpace(body.Username) == "" { + body.Username = "quick_" + strconv.FormatInt(time.Now().UnixMilli(), 10) + } + if strings.TrimSpace(body.Avatar) == "" { + body.Avatar = "https://cdn.example.com/avatar/default.png" + } + if strings.TrimSpace(body.Gender) == "" { + body.Gender = "unknown" + } + if strings.TrimSpace(body.Country) == "" { + body.Country = "SG" + } + if strings.TrimSpace(body.DeviceID) == "" { + body.DeviceID = idgen.New("quick_device") + } + if strings.TrimSpace(body.Platform) == "" { + body.Platform = "android" + } + if strings.TrimSpace(body.Language) == "" { + body.Language = "zh-CN" + } + if strings.TrimSpace(body.Timezone) == "" { + body.Timezone = "Asia/Shanghai" + } + if strings.TrimSpace(body.Source) == "" { + body.Source = "quick_account" + } + if strings.TrimSpace(body.InstallChannel) == "" { + body.InstallChannel = "game_integration" + } + + if !h.allowPublicAuthRequest(writer, request, authRateInput{ + operation: authOperationThirdParty, + deviceID: body.DeviceID, + provider: "quick_account", + }) { + return + } + if !h.allowLoginRisk(writer, request, loginRiskInput{ + Channel: "quick_account", + Platform: body.Platform, + Language: body.Language, + Timezone: body.Timezone, + }) { + return + } + if h.userClient == nil { + httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") + return + } + + resp, err := h.userClient.QuickCreateAccount(request.Context(), &userv1.QuickCreateAccountRequest{ + Meta: authRequestMetaWithLoginContext(request, body.DeviceID, body.Platform, body.Language, body.Timezone), + Password: body.Password, + Username: body.Username, + Avatar: body.Avatar, + Gender: body.Gender, + Country: body.Country, + InviteCode: body.InviteCode, + DeviceId: body.DeviceID, + Device: body.Device, + OsVersion: body.OSVersion, + Birth: body.Birth, + AppVersion: body.AppVersion, + BuildNumber: body.BuildNumber, + Source: body.Source, + InstallChannel: body.InstallChannel, + Campaign: body.Campaign, + Platform: body.Platform, + Language: body.Language, + Timezone: body.Timezone, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + + token := authData(resp.GetToken(), nil) + httpkit.WriteOK(writer, request, quickCreateAccountData{ + UID: token.DisplayUserID, + Account: token.DisplayUserID, + AccessToken: token.AccessToken, + RefreshToken: token.RefreshToken, + PasswordSet: resp.GetPasswordSet(), + Token: token, + }) +} + // loginThirdParty 处理三方登录即注册。 func (h *Handler) loginThirdParty(writer http.ResponseWriter, request *http.Request) { var body struct { diff --git a/services/gateway-service/internal/transport/http/game_handler_test.go b/services/gateway-service/internal/transport/http/game_handler_test.go index 82d20872..0f7ec1b7 100644 --- a/services/gateway-service/internal/transport/http/game_handler_test.go +++ b/services/gateway-service/internal/transport/http/game_handler_test.go @@ -64,8 +64,9 @@ func TestLaunchGameForwardsDisplayUserID(t *testing.T) { handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{}) handler.SetGameClient(gameClient) router := handler.Routes(auth.NewVerifier("secret")) + accessToken := signGatewayToken(t, "secret", 42) request := httptest.NewRequest(http.MethodPost, "/api/v1/games/demo_rocket_001/launch", bytes.NewReader([]byte(`{"scene":"voice_room","room_id":"room-1"}`))) - request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42)) + request.Header.Set("Authorization", "Bearer "+accessToken) recorder := httptest.NewRecorder() router.ServeHTTP(recorder, request) @@ -73,7 +74,7 @@ func TestLaunchGameForwardsDisplayUserID(t *testing.T) { if recorder.Code != http.StatusOK { t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String()) } - if gameClient.lastLaunch.GetGameId() != "demo_rocket_001" || gameClient.lastLaunch.GetDisplayUserId() != "100001" || gameClient.lastLaunch.GetRoomId() != "room-1" { + if gameClient.lastLaunch.GetGameId() != "demo_rocket_001" || gameClient.lastLaunch.GetDisplayUserId() != "100001" || gameClient.lastLaunch.GetRoomId() != "room-1" || gameClient.lastLaunch.GetAccessToken() != accessToken { t.Fatalf("LaunchGame request mismatch: %+v", gameClient.lastLaunch) } } diff --git a/services/gateway-service/internal/transport/http/gameapi/game_handler.go b/services/gateway-service/internal/transport/http/gameapi/game_handler.go index 2bb89511..02df7674 100644 --- a/services/gateway-service/internal/transport/http/gameapi/game_handler.go +++ b/services/gateway-service/internal/transport/http/gameapi/game_handler.go @@ -73,6 +73,7 @@ func (h *Handler) launchGame(writer http.ResponseWriter, request *http.Request) GameId: gameID, Scene: body.Scene, RoomId: body.RoomID, + AccessToken: bearerAccessToken(request), }) httpkit.Write(writer, request, gameLaunchDataFromProto(resp), err) } @@ -132,6 +133,14 @@ func requestLanguage(request *http.Request) string { return strings.TrimSpace(value) } +func bearerAccessToken(request *http.Request) string { + header := strings.TrimSpace(request.Header.Get("Authorization")) + if !strings.HasPrefix(header, "Bearer ") { + return "" + } + return strings.TrimSpace(strings.TrimPrefix(header, "Bearer ")) +} + func flattenedHeaders(request *http.Request) map[string]string { headers := make(map[string]string, len(request.Header)) for key, values := range request.Header { diff --git a/services/gateway-service/internal/transport/http/httproutes/router.go b/services/gateway-service/internal/transport/http/httproutes/router.go index 53dbe244..8e9d0de7 100644 --- a/services/gateway-service/internal/transport/http/httproutes/router.go +++ b/services/gateway-service/internal/transport/http/httproutes/router.go @@ -29,11 +29,12 @@ type Config struct { } type AuthHandlers struct { - LoginPassword http.HandlerFunc - SetPassword http.HandlerFunc - LoginThirdParty http.HandlerFunc - RefreshToken http.HandlerFunc - Logout http.HandlerFunc + LoginPassword http.HandlerFunc + SetPassword http.HandlerFunc + QuickCreateAccount http.HandlerFunc + LoginThirdParty http.HandlerFunc + RefreshToken http.HandlerFunc + Logout http.HandlerFunc } type AppHandlers struct { @@ -220,6 +221,7 @@ func (r routes) registerAuthRoutes() { h := r.config.Auth r.public("/auth/account/login", "", h.LoginPassword) r.auth("/auth/password/set", "", h.SetPassword) + r.public("/auth/account/quick-create", http.MethodPost, h.QuickCreateAccount) r.public("/auth/third-party/login", "", h.LoginThirdParty) r.public("/auth/token/refresh", "", h.RefreshToken) r.public("/auth/logout", "", h.Logout) diff --git a/services/gateway-service/internal/transport/http/response_test.go b/services/gateway-service/internal/transport/http/response_test.go index 628b3259..e803e159 100644 --- a/services/gateway-service/internal/transport/http/response_test.go +++ b/services/gateway-service/internal/transport/http/response_test.go @@ -236,6 +236,7 @@ type fakeUserAuthClient struct { lastLoginThirdParty *userv1.LoginThirdPartyRequest lastLoginPassword *userv1.LoginPasswordRequest lastSetPassword *userv1.SetPasswordRequest + lastQuickCreate *userv1.QuickCreateAccountRequest lastRefresh *userv1.RefreshTokenRequest lastLogout *userv1.LogoutRequest lastBlocked *userv1.RecordLoginBlockedRequest @@ -445,6 +446,21 @@ func (f *fakeUserAuthClient) SetPassword(_ context.Context, req *userv1.SetPassw return &userv1.SetPasswordResponse{PasswordSet: true}, nil } +func (f *fakeUserAuthClient) QuickCreateAccount(_ context.Context, req *userv1.QuickCreateAccountRequest) (*userv1.QuickCreateAccountResponse, error) { + f.lastQuickCreate = req + return &userv1.QuickCreateAccountResponse{Token: &userv1.AuthToken{ + UserId: 10001, + DisplayUserId: "100001", + SessionId: "sess-quick", + AccessToken: "access-quick", + RefreshToken: "refresh-quick", + ExpiresInSec: 1800, + TokenType: "Bearer", + ProfileCompleted: true, + OnboardingStatus: "completed", + }, PasswordSet: true}, nil +} + func (f *fakeUserAuthClient) RefreshToken(_ context.Context, req *userv1.RefreshTokenRequest) (*userv1.RefreshTokenResponse, error) { f.lastRefresh = req f.refreshCount++ @@ -2563,6 +2579,50 @@ func TestAccountLoginAcceptsAccountField(t *testing.T) { } } +func TestQuickCreateAccountCreatesCompletedPasswordAccount(t *testing.T) { + userClient := &fakeUserAuthClient{} + router := NewHandler(&fakeRoomClient{}, userClient).Routes(auth.NewVerifier("secret")) + body := []byte(`{"password":"secret-pass"}`) + request := httptest.NewRequest(http.MethodPost, "/api/v1/auth/account/quick-create", bytes.NewReader(body)) + request.Header.Set("X-Request-ID", "req-quick-create") + request.Header.Set("X-App-Code", "lalu") + 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()) + } + var response httpkit.ResponseEnvelope + if err := json.NewDecoder(recorder.Body).Decode(&response); err != nil { + t.Fatalf("decode response failed: %v", err) + } + if response.Code != httpkit.CodeOK || response.RequestID != assertGeneratedRequestID(t, recorder, "req-quick-create") { + t.Fatalf("unexpected envelope: %+v", response) + } + req := userClient.lastQuickCreate + if req == nil { + t.Fatal("QuickCreateAccount request was not sent") + } + if req.GetPassword() != "secret-pass" || req.GetUsername() == "" || req.GetAvatar() == "" { + t.Fatalf("quick create profile defaults were not populated: %+v", req) + } + if req.GetCountry() != "SG" || req.GetGender() != "unknown" || req.GetDeviceId() == "" { + t.Fatalf("quick create required defaults mismatch: %+v", req) + } + if req.GetPlatform() != "android" || req.GetLanguage() != "zh-CN" || req.GetTimezone() != "Asia/Shanghai" { + t.Fatalf("quick create login context mismatch: %+v", req) + } + if req.GetMeta().GetAppCode() != "lalu" || req.GetMeta().GetDeviceId() != req.GetDeviceId() { + t.Fatalf("quick create meta mismatch: %+v", req.GetMeta()) + } + + data, ok := response.Data.(map[string]any) + if !ok || data["uid"] != "100001" || data["account"] != "100001" || data["access_token"] != "access-quick" || data["password_set"] != true { + t.Fatalf("quick create response mismatch: %+v", response.Data) + } +} + func TestLoginRiskFastGuardBlocksLanguage(t *testing.T) { userClient := &fakeUserAuthClient{} handler := NewHandler(&fakeRoomClient{}, userClient) diff --git a/services/gateway-service/internal/transport/http/router.go b/services/gateway-service/internal/transport/http/router.go index b0eda327..bd8250bb 100644 --- a/services/gateway-service/internal/transport/http/router.go +++ b/services/gateway-service/internal/transport/http/router.go @@ -114,11 +114,12 @@ func (h *Handler) Routes(jwtVerifier *auth.Verifier) http.Handler { return h.profileAPIHandler(jwtVerifier, handler) }, Auth: httproutes.AuthHandlers{ - LoginPassword: h.loginPassword, - SetPassword: h.setPassword, - LoginThirdParty: h.loginThirdParty, - RefreshToken: h.refreshToken, - Logout: h.logout, + LoginPassword: h.loginPassword, + SetPassword: h.setPassword, + QuickCreateAccount: h.quickCreateAccount, + LoginThirdParty: h.loginThirdParty, + RefreshToken: h.refreshToken, + Logout: h.logout, }, App: httproutes.AppHandlers{ ListRegistrationCountries: userAPI.ListRegistrationCountries, diff --git a/services/user-service/internal/service/auth/quick_account.go b/services/user-service/internal/service/auth/quick_account.go new file mode 100644 index 00000000..74cda293 --- /dev/null +++ b/services/user-service/internal/service/auth/quick_account.go @@ -0,0 +1,119 @@ +package auth + +import ( + "context" + "strings" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + authdomain "hyapp/services/user-service/internal/domain/auth" + invitedomain "hyapp/services/user-service/internal/domain/invite" + userdomain "hyapp/services/user-service/internal/domain/user" +) + +// QuickCreateAccount 创建一个已完成资料、已设置密码、可立即登录的账号。 +// 该能力只复用内部领域事务,不依赖 firebase/mock provider,方便游戏方联调时快速拿 uid/token。 +func (s *Service) QuickCreateAccount(ctx context.Context, password string, registration authdomain.ThirdPartyRegistration, meta Meta) (authdomain.Token, error) { + meta.AppCode = appcode.Normalize(meta.AppCode) + registration.AppCode = meta.AppCode + registration = normalizeThirdPartyRegistration(registration, meta) + meta.Platform = registration.Platform + meta.Language = registration.Language + meta.Timezone = registration.Timezone + password = strings.TrimSpace(password) + if password == "" { + return authdomain.Token{}, xerr.New(xerr.InvalidArgument, "password is required") + } + if registration.DeviceID == "" || registration.Platform == "" { + // refresh session 必须绑定设备,平台也会进入注册来源和风控审计。 + return authdomain.Token{}, xerr.New(xerr.InvalidArgument, "device_id and platform are required") + } + if registration.Username == "" || registration.Avatar == "" || registration.Gender == "" || registration.Country == "" { + // 快捷账号直接跳过 onboarding,因此必须一次性写齐客户端准入所需的最小资料。 + return authdomain.Token{}, xerr.New(xerr.InvalidArgument, "username, avatar, gender and country are required") + } + if err := validateThirdPartyRegistration(registration); err != nil { + return authdomain.Token{}, err + } + if s.authRepository == nil { + return authdomain.Token{}, xerr.New(xerr.Unavailable, "auth repository is not configured") + } + + registration, err := s.resolveRegistrationCountry(ctx, registration) + if err != nil { + return authdomain.Token{}, err + } + passwordHash, err := hashPassword(password) + if err != nil { + return authdomain.Token{}, err + } + + var lastErr error + for attempt := 0; attempt < s.allocateMaxAttempts; attempt++ { + user, displayIdentity := s.newUserWithIdentity(attempt) + user = applyThirdPartyRegistration(user, registration) + user.ProfileCompleted = true + user.ProfileCompletedAtMs = user.CreatedAtMs + user.OnboardingStatus = userdomain.OnboardingStatusCompleted + + displayUserID, err := s.authRepository.AllocateDisplayUserID(ctx, registration.AppCode) + if err != nil { + return authdomain.Token{}, err + } + user.DefaultDisplayUserID = displayUserID + user.CurrentDisplayUserID = displayUserID + displayIdentity.AppCode = registration.AppCode + displayIdentity.DisplayUserID = displayUserID + displayIdentity.DefaultDisplayUserID = displayUserID + if !userdomain.ValidDisplayUserID(displayIdentity.DisplayUserID) { + // 分配器或历史种子异常时不写库,直接尝试下一个候选。 + continue + } + + session, refreshToken, err := s.newSession(registration.AppCode, user.UserID, registration.DeviceID) + if err != nil { + return authdomain.Token{}, err + } + account := authdomain.PasswordAccount{ + AppCode: registration.AppCode, + UserID: user.UserID, + DisplayUserID: displayUserID, + PasswordHash: passwordHash, + HashAlg: hashAlgBcrypt, + CreatedAtMs: user.CreatedAtMs, + UpdatedAtMs: user.UpdatedAtMs, + } + inviteBind := invitedomain.BindCommand{ + AppCode: registration.AppCode, + InvitedUserID: user.UserID, + InvitedRegionID: registration.RegionID, + InviteCode: registration.InviteCode, + Source: "quick_account_creation", + RequestID: meta.RequestID, + BoundAtMs: user.CreatedAtMs, + } + err = s.authRepository.CreatePasswordUser(ctx, user, displayIdentity, account, session, inviteBind) + if err == nil { + s.audit(ctx, meta, user.UserID, loginPassword, "", resultSuccess, "") + token, tokenErr := s.issueToken(user, session.SessionID, refreshToken) + if tokenErr != nil { + return authdomain.Token{}, tokenErr + } + s.enqueueLoginIPRiskJob(ctx, meta, token, "account", registration.Platform, registration.Language, registration.Timezone) + return token, nil + } + if xerr.IsCode(err, xerr.DisplayUserIDExists) { + // 默认短号冲突可重试,避免少量并发建号把快捷入口打成失败。 + lastErr = err + continue + } + + s.audit(ctx, meta, 0, loginPassword, "", resultFailed, string(xerr.CodeOf(err))) + return authdomain.Token{}, err + } + + if lastErr != nil { + s.audit(ctx, meta, 0, loginPassword, "", resultFailed, string(xerr.DisplayUserIDAllocateFailed)) + } + return authdomain.Token{}, xerr.New(xerr.DisplayUserIDAllocateFailed, "display_user_id allocation failed") +} diff --git a/services/user-service/internal/service/auth/service.go b/services/user-service/internal/service/auth/service.go index 82a8315e..6187ff90 100644 --- a/services/user-service/internal/service/auth/service.go +++ b/services/user-service/internal/service/auth/service.go @@ -40,6 +40,8 @@ type AuthRepository interface { AllocateDisplayUserID(ctx context.Context, appCode string) (string, error) // SetPassword 为已有用户首次写入密码身份。 SetPassword(ctx context.Context, account authdomain.PasswordAccount) error + // CreatePasswordUser 原子创建用户、默认短号、密码身份和首个 session。 + CreatePasswordUser(ctx context.Context, user userdomain.User, identity userdomain.Identity, account authdomain.PasswordAccount, session authdomain.Session, invite invitedomain.BindCommand) error // FindPasswordByDisplayUserID 通过当前 active display_user_id 读取密码身份。 FindPasswordByDisplayUserID(ctx context.Context, displayUserID string, nowMs int64) (authdomain.PasswordAccount, error) // CreateSession 创建新的 refresh session。 diff --git a/services/user-service/internal/service/auth/service_test.go b/services/user-service/internal/service/auth/service_test.go index 3837a07c..5c0d04af 100644 --- a/services/user-service/internal/service/auth/service_test.go +++ b/services/user-service/internal/service/auth/service_test.go @@ -224,6 +224,51 @@ func TestThirdPartyUserSetsPasswordThenLogsIn(t *testing.T) { } } +func TestQuickCreateAccountCreatesCompletedPasswordLogin(t *testing.T) { + // 快捷建号必须一次性得到可登录短号、已完成资料快照和密码身份,服务游戏联调直接取 uid/token。 + ctx := context.Background() + repository := mysqltest.NewRepository(t) + seedCountry(t, repository, "SG") + now := time.UnixMilli(2000) + svc := newAuthService(repository, &now, []int64{900011}, []string{"100011"}) + + token, err := svc.QuickCreateAccount(ctx, "secret-pass", authdomain.ThirdPartyRegistration{ + Username: "Lingxian Test", + Avatar: "https://cdn.example/avatar.png", + Gender: "unknown", + Country: "SG", + DeviceID: "quick-dev", + Platform: "ios", + Language: "en-US", + Timezone: "Asia/Shanghai", + AppVersion: "1.0.0", + }, authservice.Meta{RequestID: "req-quick-create", AppCode: "lalu", ClientIP: "203.0.113.10", UserAgent: "quick-test/1.0"}) + if err != nil { + t.Fatalf("QuickCreateAccount failed: %v", err) + } + if token.UserID != 900011 || token.DisplayUserID == "" || token.AccessToken == "" || token.RefreshToken == "" { + t.Fatalf("unexpected quick token: %+v", token) + } + if !token.ProfileCompleted || token.OnboardingStatus != string(userdomain.OnboardingStatusCompleted) { + t.Fatalf("quick account must be completed: %+v", token) + } + user, err := repository.GetUser(ctx, token.UserID) + if err != nil { + t.Fatalf("GetUser failed: %v", err) + } + if user.Username != "Lingxian Test" || user.Country != "SG" || !user.ProfileCompleted { + t.Fatalf("quick user profile mismatch: %+v", user) + } + + loginToken, err := svc.LoginPassword(ctx, token.DisplayUserID, "secret-pass", "quick-dev", authservice.Meta{RequestID: "req-quick-login", AppCode: "lalu"}) + if err != nil { + t.Fatalf("LoginPassword for quick account failed: %v", err) + } + if loginToken.UserID != token.UserID || loginToken.DisplayUserID != token.DisplayUserID || !loginToken.ProfileCompleted { + t.Fatalf("quick account login token mismatch: %+v", loginToken) + } +} + func TestRefreshTokenCarriesCompletedOnboardingStatus(t *testing.T) { // gateway profile gate 依赖 access token 快照;refresh 必须在用户完成注册后带出最新状态。 ctx := context.Background() diff --git a/services/user-service/internal/storage/mysql/auth/password.go b/services/user-service/internal/storage/mysql/auth/password.go index 87c52b4b..0f7826d4 100644 --- a/services/user-service/internal/storage/mysql/auth/password.go +++ b/services/user-service/internal/storage/mysql/auth/password.go @@ -7,7 +7,11 @@ import ( "hyapp/pkg/appcode" "hyapp/pkg/xerr" authdomain "hyapp/services/user-service/internal/domain/auth" + invitedomain "hyapp/services/user-service/internal/domain/invite" + userdomain "hyapp/services/user-service/internal/domain/user" identitystorage "hyapp/services/user-service/internal/storage/mysql/identity" + invitestorage "hyapp/services/user-service/internal/storage/mysql/invite" + userstorage "hyapp/services/user-service/internal/storage/mysql/user" ) func (r *Repository) SetPassword(ctx context.Context, account authdomain.PasswordAccount) error { @@ -24,6 +28,39 @@ func (r *Repository) SetPassword(ctx context.Context, account authdomain.Passwor return nil } +// CreatePasswordUser 原子创建完整密码账号,服务快捷建号和联调账号准备。 +func (r *Repository) CreatePasswordUser(ctx context.Context, user userdomain.User, identity userdomain.Identity, account authdomain.PasswordAccount, session authdomain.Session, inviteBind invitedomain.BindCommand) error { + // 账号创建必须和默认短号、密码身份、refresh session 同事务提交,避免返回不可登录的 uid。 + tx, err := r.db.BeginTx(ctx, nil) + if err != nil { + return err + } + defer tx.Rollback() + + if err := userstorage.InsertUserIdentity(ctx, tx, user, identity); err != nil { + // 默认短号唯一键冲突交给 service 使用新 user_id/display_user_id 重试。 + return mapAuthDuplicateError(err) + } + if _, err := invitestorage.EnsurePrimaryCodeForUser(ctx, tx, user.AppCode, user.UserID, user.CreatedAtMs); err != nil { + return err + } + if _, err := invitestorage.BindRelation(ctx, tx, inviteBind); err != nil { + return err + } + if _, err := tx.ExecContext(ctx, ` + INSERT INTO password_accounts (app_code, user_id, password_hash, hash_alg, created_at_ms, updated_at_ms) + VALUES (?, ?, ?, ?, ?, ?) + `, appcode.Normalize(account.AppCode), account.UserID, account.PasswordHash, account.HashAlg, account.CreatedAtMs, account.UpdatedAtMs); err != nil { + return mapAuthDuplicateError(err) + } + if err := insertSession(ctx, tx, session); err != nil { + // session 写入失败时必须回滚用户和密码身份,否则客户端拿不到 refresh token 却占用账号。 + return err + } + + return tx.Commit() +} + // FindPasswordByDisplayUserID 通过当前 active display_user_id 查找用户密码身份。 func (r *Repository) FindPasswordByDisplayUserID(ctx context.Context, displayUserID string, nowMs int64) (authdomain.PasswordAccount, error) { diff --git a/services/user-service/internal/testutil/mysqltest/mysqltest.go b/services/user-service/internal/testutil/mysqltest/mysqltest.go index 0309801f..f9b7a7af 100644 --- a/services/user-service/internal/testutil/mysqltest/mysqltest.go +++ b/services/user-service/internal/testutil/mysqltest/mysqltest.go @@ -241,6 +241,11 @@ func (r *Repository) SetPassword(ctx context.Context, account authdomain.Passwor return r.Repository.AuthRepository().SetPassword(ctx, account) } +// CreatePasswordUser 让测试 wrapper 继续满足认证接口。 +func (r *Repository) CreatePasswordUser(ctx context.Context, user userdomain.User, identity userdomain.Identity, account authdomain.PasswordAccount, session authdomain.Session, invite invitedomain.BindCommand) error { + return r.Repository.AuthRepository().CreatePasswordUser(ctx, user, identity, account, session, invite) +} + // FindPasswordByDisplayUserID 让测试 wrapper 继续满足认证接口。 func (r *Repository) FindPasswordByDisplayUserID(ctx context.Context, displayUserID string, nowMs int64) (authdomain.PasswordAccount, error) { return r.Repository.AuthRepository().FindPasswordByDisplayUserID(ctx, displayUserID, nowMs) diff --git a/services/user-service/internal/transport/grpc/server.go b/services/user-service/internal/transport/grpc/server.go index 416b87e1..071b7341 100644 --- a/services/user-service/internal/transport/grpc/server.go +++ b/services/user-service/internal/transport/grpc/server.go @@ -136,6 +136,37 @@ func (s *Server) SetPassword(ctx context.Context, req *userv1.SetPasswordRequest return &userv1.SetPasswordResponse{PasswordSet: true}, nil } +// QuickCreateAccount 为游戏联调快速创建一个已完成资料且可密码登录的账号。 +func (s *Server) QuickCreateAccount(ctx context.Context, req *userv1.QuickCreateAccountRequest) (*userv1.QuickCreateAccountResponse, error) { + ctx = contextWithApp(ctx, req.GetMeta()) + registration := authdomain.ThirdPartyRegistration{ + Username: req.GetUsername(), + Gender: req.GetGender(), + Country: req.GetCountry(), + InviteCode: req.GetInviteCode(), + IP: req.GetMeta().GetClientIp(), + DeviceID: req.GetDeviceId(), + Device: req.GetDevice(), + OSVersion: req.GetOsVersion(), + Avatar: req.GetAvatar(), + BirthDate: req.GetBirth(), + AppVersion: req.GetAppVersion(), + BuildNumber: req.GetBuildNumber(), + Source: req.GetSource(), + InstallChannel: req.GetInstallChannel(), + Campaign: req.GetCampaign(), + Platform: req.GetPlatform(), + Language: req.GetLanguage(), + Timezone: req.GetTimezone(), + } + token, err := s.authSvc.QuickCreateAccount(ctx, req.GetPassword(), registration, authMeta(req.GetMeta())) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + + return &userv1.QuickCreateAccountResponse{Token: toProtoToken(token), PasswordSet: true}, nil +} + // RefreshToken 执行 refresh token 轮换。 func (s *Server) RefreshToken(ctx context.Context, req *userv1.RefreshTokenRequest) (*userv1.RefreshTokenResponse, error) { ctx = contextWithApp(ctx, req.GetMeta())