From 70502685cee7154d966a2d3aa96b39c5779b067a Mon Sep 17 00:00:00 2001 From: Gordon <1432970085@qq.com> Date: Tue, 28 Feb 2023 16:35:53 +0800 Subject: [PATCH 1/8] invite user to groups api add --- cmd/open_im_api/main.go | 2 + internal/api/group/group.go | 41 +++ internal/rpc/group/group.go | 29 ++ pkg/base_info/group_api_struct.go | 10 +- pkg/common/db/model.go | 4 + pkg/common/db/mongoModel.go | 30 ++ pkg/proto/group/group.pb.go | 580 +++++++++++++++++++----------- pkg/proto/group/group.proto | 12 + 8 files changed, 494 insertions(+), 214 deletions(-) diff --git a/cmd/open_im_api/main.go b/cmd/open_im_api/main.go index 71d47edc0..34c002e0e 100644 --- a/cmd/open_im_api/main.go +++ b/cmd/open_im_api/main.go @@ -111,6 +111,8 @@ func main() { groupRouterGroup.POST("/get_group_all_member_list", group.GetGroupAllMemberList) //1 groupRouterGroup.POST("/get_group_members_info", group.GetGroupMembersInfo) //1 groupRouterGroup.POST("/invite_user_to_group", group.InviteUserToGroup) //1 + //only for supergroup + groupRouterGroup.POST("/invite_user_to_groups", group.InviteUserToGroups) groupRouterGroup.POST("/get_joined_group_list", group.GetJoinedGroupList) groupRouterGroup.POST("/dismiss_group", group.DismissGroup) // groupRouterGroup.POST("/mute_group_member", group.MuteGroupMember) diff --git a/internal/api/group/group.go b/internal/api/group/group.go index 1cddd7ede..5a234a3bb 100644 --- a/internal/api/group/group.go +++ b/internal/api/group/group.go @@ -370,6 +370,47 @@ func InviteUserToGroup(c *gin.Context) { log.NewInfo(req.OperationID, "InviteUserToGroup api return ", resp) c.JSON(http.StatusOK, resp) } +func InviteUserToGroups(c *gin.Context) { + params := api.InviteUserToGroupsReq{} + if err := c.BindJSON(¶ms); err != nil { + log.NewError("0", "BindJSON failed ", err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()}) + return + } + req := &rpc.InviteUserToGroupsReq{} + utils.CopyStructFields(req, ¶ms) + + var ok bool + var errInfo string + ok, req.OpUserID, errInfo = token_verify.GetUserIDFromToken(c.Request.Header.Get("token"), req.OperationID) + if !ok { + errMsg := req.OperationID + " " + "GetUserIDFromToken failed " + errInfo + " token:" + c.Request.Header.Get("token") + log.NewError(req.OperationID, errMsg) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 500, "errMsg": errMsg}) + return + } + + log.NewInfo(req.OperationID, "InviteUserToGroup args ", req.String()) + + etcdConn := getcdv3.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImGroupName, req.OperationID) + if etcdConn == nil { + errMsg := req.OperationID + "getcdv3.GetDefaultConn == nil" + log.NewError(req.OperationID, errMsg) + c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg}) + return + } + client := rpc.NewGroupClient(etcdConn) + RpcResp, err := client.InviteUserToGroups(context.Background(), req) + if err != nil { + log.NewError(req.OperationID, "InviteUserToGroup failed ", err.Error(), req.String()) + c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()}) + return + } + resp := api.InviteUserToGroupResp{CommResp: api.CommResp{ErrCode: RpcResp.ErrCode, ErrMsg: RpcResp.ErrMsg}} + + log.NewInfo(req.OperationID, "InviteUserToGroups api return ", resp) + c.JSON(http.StatusOK, resp) +} // @Summary 创建群组 // @Description 创建群组 diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 7411588fe..1e1ef8d4f 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -564,6 +564,35 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite return &resp, nil } +func (s *groupServer) InviteUserToGroups(ctx context.Context, req *pbGroup.InviteUserToGroupsReq) (*pbGroup.InviteUserToGroupsResp, error) { + if !token_verify.IsManagerUserID(req.OpUserID) { + log.NewError(req.OperationID, "no permission InviteUserToGroup ", req.String()) + return &pbGroup.InviteUserToGroupsResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: constant.ErrAccess.ErrMsg}, nil + } + for _, v := range req.GroupIDList { + groupInfo, err := imdb.GetGroupInfoByGroupID(v) + if err != nil { + log.NewError(req.OperationID, "GetGroupInfoByGroupID failed ", v, err) + return &pbGroup.InviteUserToGroupsResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: err.Error() + v}, nil + } + if groupInfo.Status == constant.GroupStatusDismissed { + errMsg := " group status is dismissed " + v + return &pbGroup.InviteUserToGroupsResp{ErrCode: constant.ErrStatus.ErrCode, ErrMsg: errMsg}, nil + } + } + if err := db.DB.AddUserToSuperGroups(req.GroupIDList, req.InvitedUserID); err != nil { + log.NewError(req.OperationID, "AddUserToSuperGroups failed ", err.Error()) + return &pbGroup.InviteUserToGroupsResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: err.Error()}, nil + } + if err := rocksCache.DelJoinedSuperGroupIDListFromCache(req.InvitedUserID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error()) + } + chat.SuperGroupNotification(req.OperationID, req.InvitedUserID, req.InvitedUserID) + + log.NewInfo(req.OperationID, "InviteUserToGroups rpc return ") + return nil, nil +} + func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbGroup.GetGroupAllMemberReq) (*pbGroup.GetGroupAllMemberResp, error) { log.NewInfo(req.OperationID, "GetGroupAllMember, args ", req.String()) var resp pbGroup.GetGroupAllMemberResp diff --git a/pkg/base_info/group_api_struct.go b/pkg/base_info/group_api_struct.go index 6218f13b2..505e3ada4 100644 --- a/pkg/base_info/group_api_struct.go +++ b/pkg/base_info/group_api_struct.go @@ -47,7 +47,15 @@ type InviteUserToGroupResp struct { CommResp UserIDResultList []*UserIDResult `json:"data"` } - +type InviteUserToGroupsReq struct { + GroupIDList string `json:"groupIDList" binding:"required"` + InvitedUserID string `json:"invitedUserID" binding:"required"` + Reason string `json:"reason"` + OperationID string `json:"operationID" binding:"required"` +} +type InviteUserToGroupsResp struct { + CommResp +} type GetJoinedGroupListReq struct { OperationID string `json:"operationID" binding:"required"` FromUserID string `json:"fromUserID" binding:"required"` diff --git a/pkg/common/db/model.go b/pkg/common/db/model.go index bf2058e51..173a15e8d 100644 --- a/pkg/common/db/model.go +++ b/pkg/common/db/model.go @@ -112,6 +112,10 @@ func init() { if err := createMongoIndex(mongoClient, cTag, true, "tag_id"); err != nil { panic(err.Error() + "index create failed " + cTag + " tag_id") } + if err := createMongoIndex(mongoClient, cUserToSuperGroup, true, "user_id"); err != nil { + panic(err.Error() + "index create failed " + cUserToSuperGroup + " user_id") + } + DB.mongoClient = mongoClient ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) diff --git a/pkg/common/db/mongoModel.go b/pkg/common/db/mongoModel.go index 61ad642b3..ab94a0df8 100644 --- a/pkg/common/db/mongoModel.go +++ b/pkg/common/db/mongoModel.go @@ -1233,6 +1233,36 @@ func (d *DataBases) AddUserToSuperGroup(groupID string, userIDList []string) err _ = session.CommitTransaction(ctx) return err } +func (d *DataBases) AddUserToSuperGroups(groupIDList []string, userID string) error { + ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) + c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup) + session, err := d.mongoClient.StartSession() + if err != nil { + return utils.Wrap(err, "start session failed") + } + defer session.EndSession(ctx) + sCtx := mongo.NewSessionContext(ctx, session) + if err != nil { + return utils.Wrap(err, "start transaction failed") + } + _, err = c.UpdateMany(sCtx, bson.M{"group_id": bson.M{"$in": groupIDList}}, bson.M{"$addToSet": bson.M{"member_id_list": userID}}) + if err != nil { + _ = session.AbortTransaction(ctx) + return utils.Wrap(err, "transaction failed") + } + c = d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cUserToSuperGroup) + upsert := true + opts := &options.UpdateOptions{ + Upsert: &upsert, + } + _, err = c.UpdateOne(sCtx, bson.M{"user_id": userID}, bson.M{"$addToSet": bson.M{"group_id_list": bson.M{"$each": groupIDList}}}, opts) + if err != nil { + _ = session.AbortTransaction(ctx) + return utils.Wrap(err, "transaction failed") + } + _ = session.CommitTransaction(ctx) + return err +} func (d *DataBases) RemoverUserFromSuperGroup(groupID string, userIDList []string) error { ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) diff --git a/pkg/proto/group/group.pb.go b/pkg/proto/group/group.pb.go index 9ed5f1cb4..aa983171f 100644 --- a/pkg/proto/group/group.pb.go +++ b/pkg/proto/group/group.pb.go @@ -37,7 +37,7 @@ func (m *CommonResp) Reset() { *m = CommonResp{} } func (m *CommonResp) String() string { return proto.CompactTextString(m) } func (*CommonResp) ProtoMessage() {} func (*CommonResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{0} + return fileDescriptor_group_e55c79105d50978e, []int{0} } func (m *CommonResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommonResp.Unmarshal(m, b) @@ -83,7 +83,7 @@ func (m *GroupAddMemberInfo) Reset() { *m = GroupAddMemberInfo{} } func (m *GroupAddMemberInfo) String() string { return proto.CompactTextString(m) } func (*GroupAddMemberInfo) ProtoMessage() {} func (*GroupAddMemberInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{1} + return fileDescriptor_group_e55c79105d50978e, []int{1} } func (m *GroupAddMemberInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupAddMemberInfo.Unmarshal(m, b) @@ -132,7 +132,7 @@ func (m *CreateGroupReq) Reset() { *m = CreateGroupReq{} } func (m *CreateGroupReq) String() string { return proto.CompactTextString(m) } func (*CreateGroupReq) ProtoMessage() {} func (*CreateGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{2} + return fileDescriptor_group_e55c79105d50978e, []int{2} } func (m *CreateGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateGroupReq.Unmarshal(m, b) @@ -200,7 +200,7 @@ func (m *CreateGroupResp) Reset() { *m = CreateGroupResp{} } func (m *CreateGroupResp) String() string { return proto.CompactTextString(m) } func (*CreateGroupResp) ProtoMessage() {} func (*CreateGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{3} + return fileDescriptor_group_e55c79105d50978e, []int{3} } func (m *CreateGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateGroupResp.Unmarshal(m, b) @@ -254,7 +254,7 @@ func (m *GetGroupsInfoReq) Reset() { *m = GetGroupsInfoReq{} } func (m *GetGroupsInfoReq) String() string { return proto.CompactTextString(m) } func (*GetGroupsInfoReq) ProtoMessage() {} func (*GetGroupsInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{4} + return fileDescriptor_group_e55c79105d50978e, []int{4} } func (m *GetGroupsInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsInfoReq.Unmarshal(m, b) @@ -308,7 +308,7 @@ func (m *GetGroupsInfoResp) Reset() { *m = GetGroupsInfoResp{} } func (m *GetGroupsInfoResp) String() string { return proto.CompactTextString(m) } func (*GetGroupsInfoResp) ProtoMessage() {} func (*GetGroupsInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{5} + return fileDescriptor_group_e55c79105d50978e, []int{5} } func (m *GetGroupsInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsInfoResp.Unmarshal(m, b) @@ -362,7 +362,7 @@ func (m *SetGroupInfoReq) Reset() { *m = SetGroupInfoReq{} } func (m *SetGroupInfoReq) String() string { return proto.CompactTextString(m) } func (*SetGroupInfoReq) ProtoMessage() {} func (*SetGroupInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{6} + return fileDescriptor_group_e55c79105d50978e, []int{6} } func (m *SetGroupInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupInfoReq.Unmarshal(m, b) @@ -414,7 +414,7 @@ func (m *SetGroupInfoResp) Reset() { *m = SetGroupInfoResp{} } func (m *SetGroupInfoResp) String() string { return proto.CompactTextString(m) } func (*SetGroupInfoResp) ProtoMessage() {} func (*SetGroupInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{7} + return fileDescriptor_group_e55c79105d50978e, []int{7} } func (m *SetGroupInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupInfoResp.Unmarshal(m, b) @@ -454,7 +454,7 @@ func (m *GetGroupApplicationListReq) Reset() { *m = GetGroupApplicationL func (m *GetGroupApplicationListReq) String() string { return proto.CompactTextString(m) } func (*GetGroupApplicationListReq) ProtoMessage() {} func (*GetGroupApplicationListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{8} + return fileDescriptor_group_e55c79105d50978e, []int{8} } func (m *GetGroupApplicationListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupApplicationListReq.Unmarshal(m, b) @@ -508,7 +508,7 @@ func (m *GetGroupApplicationListResp) Reset() { *m = GetGroupApplication func (m *GetGroupApplicationListResp) String() string { return proto.CompactTextString(m) } func (*GetGroupApplicationListResp) ProtoMessage() {} func (*GetGroupApplicationListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{9} + return fileDescriptor_group_e55c79105d50978e, []int{9} } func (m *GetGroupApplicationListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupApplicationListResp.Unmarshal(m, b) @@ -562,7 +562,7 @@ func (m *GetUserReqApplicationListReq) Reset() { *m = GetUserReqApplicat func (m *GetUserReqApplicationListReq) String() string { return proto.CompactTextString(m) } func (*GetUserReqApplicationListReq) ProtoMessage() {} func (*GetUserReqApplicationListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{10} + return fileDescriptor_group_e55c79105d50978e, []int{10} } func (m *GetUserReqApplicationListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetUserReqApplicationListReq.Unmarshal(m, b) @@ -615,7 +615,7 @@ func (m *GetUserReqApplicationListResp) Reset() { *m = GetUserReqApplica func (m *GetUserReqApplicationListResp) String() string { return proto.CompactTextString(m) } func (*GetUserReqApplicationListResp) ProtoMessage() {} func (*GetUserReqApplicationListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{11} + return fileDescriptor_group_e55c79105d50978e, []int{11} } func (m *GetUserReqApplicationListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetUserReqApplicationListResp.Unmarshal(m, b) @@ -664,7 +664,7 @@ func (m *TransferGroupOwnerReq) Reset() { *m = TransferGroupOwnerReq{} } func (m *TransferGroupOwnerReq) String() string { return proto.CompactTextString(m) } func (*TransferGroupOwnerReq) ProtoMessage() {} func (*TransferGroupOwnerReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{12} + return fileDescriptor_group_e55c79105d50978e, []int{12} } func (m *TransferGroupOwnerReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransferGroupOwnerReq.Unmarshal(m, b) @@ -730,7 +730,7 @@ func (m *TransferGroupOwnerResp) Reset() { *m = TransferGroupOwnerResp{} func (m *TransferGroupOwnerResp) String() string { return proto.CompactTextString(m) } func (*TransferGroupOwnerResp) ProtoMessage() {} func (*TransferGroupOwnerResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{13} + return fileDescriptor_group_e55c79105d50978e, []int{13} } func (m *TransferGroupOwnerResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransferGroupOwnerResp.Unmarshal(m, b) @@ -773,7 +773,7 @@ func (m *JoinGroupReq) Reset() { *m = JoinGroupReq{} } func (m *JoinGroupReq) String() string { return proto.CompactTextString(m) } func (*JoinGroupReq) ProtoMessage() {} func (*JoinGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{14} + return fileDescriptor_group_e55c79105d50978e, []int{14} } func (m *JoinGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_JoinGroupReq.Unmarshal(m, b) @@ -846,7 +846,7 @@ func (m *JoinGroupResp) Reset() { *m = JoinGroupResp{} } func (m *JoinGroupResp) String() string { return proto.CompactTextString(m) } func (*JoinGroupResp) ProtoMessage() {} func (*JoinGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{15} + return fileDescriptor_group_e55c79105d50978e, []int{15} } func (m *JoinGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_JoinGroupResp.Unmarshal(m, b) @@ -889,7 +889,7 @@ func (m *GroupApplicationResponseReq) Reset() { *m = GroupApplicationRes func (m *GroupApplicationResponseReq) String() string { return proto.CompactTextString(m) } func (*GroupApplicationResponseReq) ProtoMessage() {} func (*GroupApplicationResponseReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{16} + return fileDescriptor_group_e55c79105d50978e, []int{16} } func (m *GroupApplicationResponseReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupApplicationResponseReq.Unmarshal(m, b) @@ -962,7 +962,7 @@ func (m *GroupApplicationResponseResp) Reset() { *m = GroupApplicationRe func (m *GroupApplicationResponseResp) String() string { return proto.CompactTextString(m) } func (*GroupApplicationResponseResp) ProtoMessage() {} func (*GroupApplicationResponseResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{17} + return fileDescriptor_group_e55c79105d50978e, []int{17} } func (m *GroupApplicationResponseResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupApplicationResponseResp.Unmarshal(m, b) @@ -1002,7 +1002,7 @@ func (m *QuitGroupReq) Reset() { *m = QuitGroupReq{} } func (m *QuitGroupReq) String() string { return proto.CompactTextString(m) } func (*QuitGroupReq) ProtoMessage() {} func (*QuitGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{18} + return fileDescriptor_group_e55c79105d50978e, []int{18} } func (m *QuitGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuitGroupReq.Unmarshal(m, b) @@ -1054,7 +1054,7 @@ func (m *QuitGroupResp) Reset() { *m = QuitGroupResp{} } func (m *QuitGroupResp) String() string { return proto.CompactTextString(m) } func (*QuitGroupResp) ProtoMessage() {} func (*QuitGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{19} + return fileDescriptor_group_e55c79105d50978e, []int{19} } func (m *QuitGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuitGroupResp.Unmarshal(m, b) @@ -1096,7 +1096,7 @@ func (m *GetGroupMemberListReq) Reset() { *m = GetGroupMemberListReq{} } func (m *GetGroupMemberListReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMemberListReq) ProtoMessage() {} func (*GetGroupMemberListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{20} + return fileDescriptor_group_e55c79105d50978e, []int{20} } func (m *GetGroupMemberListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMemberListReq.Unmarshal(m, b) @@ -1165,7 +1165,7 @@ func (m *GetGroupMemberListResp) Reset() { *m = GetGroupMemberListResp{} func (m *GetGroupMemberListResp) String() string { return proto.CompactTextString(m) } func (*GetGroupMemberListResp) ProtoMessage() {} func (*GetGroupMemberListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{21} + return fileDescriptor_group_e55c79105d50978e, []int{21} } func (m *GetGroupMemberListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMemberListResp.Unmarshal(m, b) @@ -1228,7 +1228,7 @@ func (m *GetGroupMembersInfoReq) Reset() { *m = GetGroupMembersInfoReq{} func (m *GetGroupMembersInfoReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersInfoReq) ProtoMessage() {} func (*GetGroupMembersInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{22} + return fileDescriptor_group_e55c79105d50978e, []int{22} } func (m *GetGroupMembersInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersInfoReq.Unmarshal(m, b) @@ -1296,7 +1296,7 @@ func (m *GetGroupMembersInfoResp) Reset() { *m = GetGroupMembersInfoResp func (m *GetGroupMembersInfoResp) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersInfoResp) ProtoMessage() {} func (*GetGroupMembersInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{23} + return fileDescriptor_group_e55c79105d50978e, []int{23} } func (m *GetGroupMembersInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersInfoResp.Unmarshal(m, b) @@ -1352,7 +1352,7 @@ func (m *KickGroupMemberReq) Reset() { *m = KickGroupMemberReq{} } func (m *KickGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*KickGroupMemberReq) ProtoMessage() {} func (*KickGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{24} + return fileDescriptor_group_e55c79105d50978e, []int{24} } func (m *KickGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KickGroupMemberReq.Unmarshal(m, b) @@ -1419,7 +1419,7 @@ func (m *Id2Result) Reset() { *m = Id2Result{} } func (m *Id2Result) String() string { return proto.CompactTextString(m) } func (*Id2Result) ProtoMessage() {} func (*Id2Result) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{25} + return fileDescriptor_group_e55c79105d50978e, []int{25} } func (m *Id2Result) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Id2Result.Unmarshal(m, b) @@ -1466,7 +1466,7 @@ func (m *KickGroupMemberResp) Reset() { *m = KickGroupMemberResp{} } func (m *KickGroupMemberResp) String() string { return proto.CompactTextString(m) } func (*KickGroupMemberResp) ProtoMessage() {} func (*KickGroupMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{26} + return fileDescriptor_group_e55c79105d50978e, []int{26} } func (m *KickGroupMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KickGroupMemberResp.Unmarshal(m, b) @@ -1520,7 +1520,7 @@ func (m *GetJoinedGroupListReq) Reset() { *m = GetJoinedGroupListReq{} } func (m *GetJoinedGroupListReq) String() string { return proto.CompactTextString(m) } func (*GetJoinedGroupListReq) ProtoMessage() {} func (*GetJoinedGroupListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{27} + return fileDescriptor_group_e55c79105d50978e, []int{27} } func (m *GetJoinedGroupListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedGroupListReq.Unmarshal(m, b) @@ -1574,7 +1574,7 @@ func (m *GetJoinedGroupListResp) Reset() { *m = GetJoinedGroupListResp{} func (m *GetJoinedGroupListResp) String() string { return proto.CompactTextString(m) } func (*GetJoinedGroupListResp) ProtoMessage() {} func (*GetJoinedGroupListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{28} + return fileDescriptor_group_e55c79105d50978e, []int{28} } func (m *GetJoinedGroupListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedGroupListResp.Unmarshal(m, b) @@ -1630,7 +1630,7 @@ func (m *InviteUserToGroupReq) Reset() { *m = InviteUserToGroupReq{} } func (m *InviteUserToGroupReq) String() string { return proto.CompactTextString(m) } func (*InviteUserToGroupReq) ProtoMessage() {} func (*InviteUserToGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{29} + return fileDescriptor_group_e55c79105d50978e, []int{29} } func (m *InviteUserToGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InviteUserToGroupReq.Unmarshal(m, b) @@ -1698,7 +1698,7 @@ func (m *InviteUserToGroupResp) Reset() { *m = InviteUserToGroupResp{} } func (m *InviteUserToGroupResp) String() string { return proto.CompactTextString(m) } func (*InviteUserToGroupResp) ProtoMessage() {} func (*InviteUserToGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{30} + return fileDescriptor_group_e55c79105d50978e, []int{30} } func (m *InviteUserToGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InviteUserToGroupResp.Unmarshal(m, b) @@ -1739,6 +1739,122 @@ func (m *InviteUserToGroupResp) GetId2ResultList() []*Id2Result { return nil } +type InviteUserToGroupsReq struct { + OperationID string `protobuf:"bytes,1,opt,name=OperationID" json:"OperationID,omitempty"` + GroupIDList []string `protobuf:"bytes,2,rep,name=groupIDList" json:"groupIDList,omitempty"` + Reason string `protobuf:"bytes,3,opt,name=Reason" json:"Reason,omitempty"` + InvitedUserID string `protobuf:"bytes,4,opt,name=invitedUserID" json:"invitedUserID,omitempty"` + OpUserID string `protobuf:"bytes,5,opt,name=OpUserID" json:"OpUserID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InviteUserToGroupsReq) Reset() { *m = InviteUserToGroupsReq{} } +func (m *InviteUserToGroupsReq) String() string { return proto.CompactTextString(m) } +func (*InviteUserToGroupsReq) ProtoMessage() {} +func (*InviteUserToGroupsReq) Descriptor() ([]byte, []int) { + return fileDescriptor_group_e55c79105d50978e, []int{31} +} +func (m *InviteUserToGroupsReq) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InviteUserToGroupsReq.Unmarshal(m, b) +} +func (m *InviteUserToGroupsReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InviteUserToGroupsReq.Marshal(b, m, deterministic) +} +func (dst *InviteUserToGroupsReq) XXX_Merge(src proto.Message) { + xxx_messageInfo_InviteUserToGroupsReq.Merge(dst, src) +} +func (m *InviteUserToGroupsReq) XXX_Size() int { + return xxx_messageInfo_InviteUserToGroupsReq.Size(m) +} +func (m *InviteUserToGroupsReq) XXX_DiscardUnknown() { + xxx_messageInfo_InviteUserToGroupsReq.DiscardUnknown(m) +} + +var xxx_messageInfo_InviteUserToGroupsReq proto.InternalMessageInfo + +func (m *InviteUserToGroupsReq) GetOperationID() string { + if m != nil { + return m.OperationID + } + return "" +} + +func (m *InviteUserToGroupsReq) GetGroupIDList() []string { + if m != nil { + return m.GroupIDList + } + return nil +} + +func (m *InviteUserToGroupsReq) GetReason() string { + if m != nil { + return m.Reason + } + return "" +} + +func (m *InviteUserToGroupsReq) GetInvitedUserID() string { + if m != nil { + return m.InvitedUserID + } + return "" +} + +func (m *InviteUserToGroupsReq) GetOpUserID() string { + if m != nil { + return m.OpUserID + } + return "" +} + +type InviteUserToGroupsResp struct { + ErrCode int32 `protobuf:"varint,1,opt,name=ErrCode" json:"ErrCode,omitempty"` + ErrMsg string `protobuf:"bytes,2,opt,name=ErrMsg" json:"ErrMsg,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InviteUserToGroupsResp) Reset() { *m = InviteUserToGroupsResp{} } +func (m *InviteUserToGroupsResp) String() string { return proto.CompactTextString(m) } +func (*InviteUserToGroupsResp) ProtoMessage() {} +func (*InviteUserToGroupsResp) Descriptor() ([]byte, []int) { + return fileDescriptor_group_e55c79105d50978e, []int{32} +} +func (m *InviteUserToGroupsResp) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InviteUserToGroupsResp.Unmarshal(m, b) +} +func (m *InviteUserToGroupsResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InviteUserToGroupsResp.Marshal(b, m, deterministic) +} +func (dst *InviteUserToGroupsResp) XXX_Merge(src proto.Message) { + xxx_messageInfo_InviteUserToGroupsResp.Merge(dst, src) +} +func (m *InviteUserToGroupsResp) XXX_Size() int { + return xxx_messageInfo_InviteUserToGroupsResp.Size(m) +} +func (m *InviteUserToGroupsResp) XXX_DiscardUnknown() { + xxx_messageInfo_InviteUserToGroupsResp.DiscardUnknown(m) +} + +var xxx_messageInfo_InviteUserToGroupsResp proto.InternalMessageInfo + +func (m *InviteUserToGroupsResp) GetErrCode() int32 { + if m != nil { + return m.ErrCode + } + return 0 +} + +func (m *InviteUserToGroupsResp) GetErrMsg() string { + if m != nil { + return m.ErrMsg + } + return "" +} + type GetGroupAllMemberReq struct { GroupID string `protobuf:"bytes,1,opt,name=GroupID" json:"GroupID,omitempty"` OpUserID string `protobuf:"bytes,2,opt,name=OpUserID" json:"OpUserID,omitempty"` @@ -1754,7 +1870,7 @@ func (m *GetGroupAllMemberReq) Reset() { *m = GetGroupAllMemberReq{} } func (m *GetGroupAllMemberReq) String() string { return proto.CompactTextString(m) } func (*GetGroupAllMemberReq) ProtoMessage() {} func (*GetGroupAllMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{31} + return fileDescriptor_group_e55c79105d50978e, []int{33} } func (m *GetGroupAllMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAllMemberReq.Unmarshal(m, b) @@ -1822,7 +1938,7 @@ func (m *GetGroupAllMemberResp) Reset() { *m = GetGroupAllMemberResp{} } func (m *GetGroupAllMemberResp) String() string { return proto.CompactTextString(m) } func (*GetGroupAllMemberResp) ProtoMessage() {} func (*GetGroupAllMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{32} + return fileDescriptor_group_e55c79105d50978e, []int{34} } func (m *GetGroupAllMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAllMemberResp.Unmarshal(m, b) @@ -1876,7 +1992,7 @@ func (m *CMSGroup) Reset() { *m = CMSGroup{} } func (m *CMSGroup) String() string { return proto.CompactTextString(m) } func (*CMSGroup) ProtoMessage() {} func (*CMSGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{33} + return fileDescriptor_group_e55c79105d50978e, []int{35} } func (m *CMSGroup) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CMSGroup.Unmarshal(m, b) @@ -1931,7 +2047,7 @@ func (m *GetGroupsReq) Reset() { *m = GetGroupsReq{} } func (m *GetGroupsReq) String() string { return proto.CompactTextString(m) } func (*GetGroupsReq) ProtoMessage() {} func (*GetGroupsReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{34} + return fileDescriptor_group_e55c79105d50978e, []int{36} } func (m *GetGroupsReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsReq.Unmarshal(m, b) @@ -1993,7 +2109,7 @@ func (m *GetGroupsResp) Reset() { *m = GetGroupsResp{} } func (m *GetGroupsResp) String() string { return proto.CompactTextString(m) } func (*GetGroupsResp) ProtoMessage() {} func (*GetGroupsResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{35} + return fileDescriptor_group_e55c79105d50978e, []int{37} } func (m *GetGroupsResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsResp.Unmarshal(m, b) @@ -2053,7 +2169,7 @@ func (m *GetGroupMemberReq) Reset() { *m = GetGroupMemberReq{} } func (m *GetGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMemberReq) ProtoMessage() {} func (*GetGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{36} + return fileDescriptor_group_e55c79105d50978e, []int{38} } func (m *GetGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMemberReq.Unmarshal(m, b) @@ -2101,7 +2217,7 @@ func (m *GetGroupMembersCMSReq) Reset() { *m = GetGroupMembersCMSReq{} } func (m *GetGroupMembersCMSReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersCMSReq) ProtoMessage() {} func (*GetGroupMembersCMSReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{37} + return fileDescriptor_group_e55c79105d50978e, []int{39} } func (m *GetGroupMembersCMSReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersCMSReq.Unmarshal(m, b) @@ -2163,7 +2279,7 @@ func (m *GetGroupMembersCMSResp) Reset() { *m = GetGroupMembersCMSResp{} func (m *GetGroupMembersCMSResp) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersCMSResp) ProtoMessage() {} func (*GetGroupMembersCMSResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{38} + return fileDescriptor_group_e55c79105d50978e, []int{40} } func (m *GetGroupMembersCMSResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersCMSResp.Unmarshal(m, b) @@ -2224,7 +2340,7 @@ func (m *DismissGroupReq) Reset() { *m = DismissGroupReq{} } func (m *DismissGroupReq) String() string { return proto.CompactTextString(m) } func (*DismissGroupReq) ProtoMessage() {} func (*DismissGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{39} + return fileDescriptor_group_e55c79105d50978e, []int{41} } func (m *DismissGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DismissGroupReq.Unmarshal(m, b) @@ -2276,7 +2392,7 @@ func (m *DismissGroupResp) Reset() { *m = DismissGroupResp{} } func (m *DismissGroupResp) String() string { return proto.CompactTextString(m) } func (*DismissGroupResp) ProtoMessage() {} func (*DismissGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{40} + return fileDescriptor_group_e55c79105d50978e, []int{42} } func (m *DismissGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DismissGroupResp.Unmarshal(m, b) @@ -2318,7 +2434,7 @@ func (m *MuteGroupMemberReq) Reset() { *m = MuteGroupMemberReq{} } func (m *MuteGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*MuteGroupMemberReq) ProtoMessage() {} func (*MuteGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{41} + return fileDescriptor_group_e55c79105d50978e, []int{43} } func (m *MuteGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupMemberReq.Unmarshal(m, b) @@ -2384,7 +2500,7 @@ func (m *MuteGroupMemberResp) Reset() { *m = MuteGroupMemberResp{} } func (m *MuteGroupMemberResp) String() string { return proto.CompactTextString(m) } func (*MuteGroupMemberResp) ProtoMessage() {} func (*MuteGroupMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{42} + return fileDescriptor_group_e55c79105d50978e, []int{44} } func (m *MuteGroupMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupMemberResp.Unmarshal(m, b) @@ -2425,7 +2541,7 @@ func (m *CancelMuteGroupMemberReq) Reset() { *m = CancelMuteGroupMemberR func (m *CancelMuteGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupMemberReq) ProtoMessage() {} func (*CancelMuteGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{43} + return fileDescriptor_group_e55c79105d50978e, []int{45} } func (m *CancelMuteGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupMemberReq.Unmarshal(m, b) @@ -2484,7 +2600,7 @@ func (m *CancelMuteGroupMemberResp) Reset() { *m = CancelMuteGroupMember func (m *CancelMuteGroupMemberResp) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupMemberResp) ProtoMessage() {} func (*CancelMuteGroupMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{44} + return fileDescriptor_group_e55c79105d50978e, []int{46} } func (m *CancelMuteGroupMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupMemberResp.Unmarshal(m, b) @@ -2524,7 +2640,7 @@ func (m *MuteGroupReq) Reset() { *m = MuteGroupReq{} } func (m *MuteGroupReq) String() string { return proto.CompactTextString(m) } func (*MuteGroupReq) ProtoMessage() {} func (*MuteGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{45} + return fileDescriptor_group_e55c79105d50978e, []int{47} } func (m *MuteGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupReq.Unmarshal(m, b) @@ -2576,7 +2692,7 @@ func (m *MuteGroupResp) Reset() { *m = MuteGroupResp{} } func (m *MuteGroupResp) String() string { return proto.CompactTextString(m) } func (*MuteGroupResp) ProtoMessage() {} func (*MuteGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{46} + return fileDescriptor_group_e55c79105d50978e, []int{48} } func (m *MuteGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupResp.Unmarshal(m, b) @@ -2616,7 +2732,7 @@ func (m *CancelMuteGroupReq) Reset() { *m = CancelMuteGroupReq{} } func (m *CancelMuteGroupReq) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupReq) ProtoMessage() {} func (*CancelMuteGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{47} + return fileDescriptor_group_e55c79105d50978e, []int{49} } func (m *CancelMuteGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupReq.Unmarshal(m, b) @@ -2668,7 +2784,7 @@ func (m *CancelMuteGroupResp) Reset() { *m = CancelMuteGroupResp{} } func (m *CancelMuteGroupResp) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupResp) ProtoMessage() {} func (*CancelMuteGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{48} + return fileDescriptor_group_e55c79105d50978e, []int{50} } func (m *CancelMuteGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupResp.Unmarshal(m, b) @@ -2710,7 +2826,7 @@ func (m *SetGroupMemberNicknameReq) Reset() { *m = SetGroupMemberNicknam func (m *SetGroupMemberNicknameReq) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberNicknameReq) ProtoMessage() {} func (*SetGroupMemberNicknameReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{49} + return fileDescriptor_group_e55c79105d50978e, []int{51} } func (m *SetGroupMemberNicknameReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberNicknameReq.Unmarshal(m, b) @@ -2776,7 +2892,7 @@ func (m *SetGroupMemberNicknameResp) Reset() { *m = SetGroupMemberNickna func (m *SetGroupMemberNicknameResp) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberNicknameResp) ProtoMessage() {} func (*SetGroupMemberNicknameResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{50} + return fileDescriptor_group_e55c79105d50978e, []int{52} } func (m *SetGroupMemberNicknameResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberNicknameResp.Unmarshal(m, b) @@ -2816,7 +2932,7 @@ func (m *GetJoinedSuperGroupListReq) Reset() { *m = GetJoinedSuperGroupL func (m *GetJoinedSuperGroupListReq) String() string { return proto.CompactTextString(m) } func (*GetJoinedSuperGroupListReq) ProtoMessage() {} func (*GetJoinedSuperGroupListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{51} + return fileDescriptor_group_e55c79105d50978e, []int{53} } func (m *GetJoinedSuperGroupListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedSuperGroupListReq.Unmarshal(m, b) @@ -2869,7 +2985,7 @@ func (m *GetJoinedSuperGroupListResp) Reset() { *m = GetJoinedSuperGroup func (m *GetJoinedSuperGroupListResp) String() string { return proto.CompactTextString(m) } func (*GetJoinedSuperGroupListResp) ProtoMessage() {} func (*GetJoinedSuperGroupListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{52} + return fileDescriptor_group_e55c79105d50978e, []int{54} } func (m *GetJoinedSuperGroupListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedSuperGroupListResp.Unmarshal(m, b) @@ -2916,7 +3032,7 @@ func (m *GetSuperGroupsInfoReq) Reset() { *m = GetSuperGroupsInfoReq{} } func (m *GetSuperGroupsInfoReq) String() string { return proto.CompactTextString(m) } func (*GetSuperGroupsInfoReq) ProtoMessage() {} func (*GetSuperGroupsInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{53} + return fileDescriptor_group_e55c79105d50978e, []int{55} } func (m *GetSuperGroupsInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSuperGroupsInfoReq.Unmarshal(m, b) @@ -2969,7 +3085,7 @@ func (m *GetSuperGroupsInfoResp) Reset() { *m = GetSuperGroupsInfoResp{} func (m *GetSuperGroupsInfoResp) String() string { return proto.CompactTextString(m) } func (*GetSuperGroupsInfoResp) ProtoMessage() {} func (*GetSuperGroupsInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{54} + return fileDescriptor_group_e55c79105d50978e, []int{56} } func (m *GetSuperGroupsInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSuperGroupsInfoResp.Unmarshal(m, b) @@ -3021,7 +3137,7 @@ func (m *SetGroupMemberInfoReq) Reset() { *m = SetGroupMemberInfoReq{} } func (m *SetGroupMemberInfoReq) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberInfoReq) ProtoMessage() {} func (*SetGroupMemberInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{55} + return fileDescriptor_group_e55c79105d50978e, []int{57} } func (m *SetGroupMemberInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberInfoReq.Unmarshal(m, b) @@ -3108,7 +3224,7 @@ func (m *SetGroupMemberInfoResp) Reset() { *m = SetGroupMemberInfoResp{} func (m *SetGroupMemberInfoResp) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberInfoResp) ProtoMessage() {} func (*SetGroupMemberInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{56} + return fileDescriptor_group_e55c79105d50978e, []int{58} } func (m *SetGroupMemberInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberInfoResp.Unmarshal(m, b) @@ -3148,7 +3264,7 @@ func (m *GetGroupAbstractInfoReq) Reset() { *m = GetGroupAbstractInfoReq func (m *GetGroupAbstractInfoReq) String() string { return proto.CompactTextString(m) } func (*GetGroupAbstractInfoReq) ProtoMessage() {} func (*GetGroupAbstractInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{57} + return fileDescriptor_group_e55c79105d50978e, []int{59} } func (m *GetGroupAbstractInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAbstractInfoReq.Unmarshal(m, b) @@ -3202,7 +3318,7 @@ func (m *GetGroupAbstractInfoResp) Reset() { *m = GetGroupAbstractInfoRe func (m *GetGroupAbstractInfoResp) String() string { return proto.CompactTextString(m) } func (*GetGroupAbstractInfoResp) ProtoMessage() {} func (*GetGroupAbstractInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{58} + return fileDescriptor_group_e55c79105d50978e, []int{60} } func (m *GetGroupAbstractInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAbstractInfoResp.Unmarshal(m, b) @@ -3256,7 +3372,7 @@ func (m *GroupIsExistReq) Reset() { *m = GroupIsExistReq{} } func (m *GroupIsExistReq) String() string { return proto.CompactTextString(m) } func (*GroupIsExistReq) ProtoMessage() {} func (*GroupIsExistReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{59} + return fileDescriptor_group_e55c79105d50978e, []int{61} } func (m *GroupIsExistReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupIsExistReq.Unmarshal(m, b) @@ -3309,7 +3425,7 @@ func (m *GroupIsExistResp) Reset() { *m = GroupIsExistResp{} } func (m *GroupIsExistResp) String() string { return proto.CompactTextString(m) } func (*GroupIsExistResp) ProtoMessage() {} func (*GroupIsExistResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{60} + return fileDescriptor_group_e55c79105d50978e, []int{62} } func (m *GroupIsExistResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupIsExistResp.Unmarshal(m, b) @@ -3356,7 +3472,7 @@ func (m *UserIsInGroupReq) Reset() { *m = UserIsInGroupReq{} } func (m *UserIsInGroupReq) String() string { return proto.CompactTextString(m) } func (*UserIsInGroupReq) ProtoMessage() {} func (*UserIsInGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{61} + return fileDescriptor_group_e55c79105d50978e, []int{63} } func (m *UserIsInGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UserIsInGroupReq.Unmarshal(m, b) @@ -3409,7 +3525,7 @@ func (m *UserIsInGroupResp) Reset() { *m = UserIsInGroupResp{} } func (m *UserIsInGroupResp) String() string { return proto.CompactTextString(m) } func (*UserIsInGroupResp) ProtoMessage() {} func (*UserIsInGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5cfdf63bf5b84d31, []int{62} + return fileDescriptor_group_e55c79105d50978e, []int{64} } func (m *UserIsInGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UserIsInGroupResp.Unmarshal(m, b) @@ -3475,6 +3591,8 @@ func init() { proto.RegisterType((*GetJoinedGroupListResp)(nil), "group.GetJoinedGroupListResp") proto.RegisterType((*InviteUserToGroupReq)(nil), "group.InviteUserToGroupReq") proto.RegisterType((*InviteUserToGroupResp)(nil), "group.InviteUserToGroupResp") + proto.RegisterType((*InviteUserToGroupsReq)(nil), "group.InviteUserToGroupsReq") + proto.RegisterType((*InviteUserToGroupsResp)(nil), "group.InviteUserToGroupsResp") proto.RegisterType((*GetGroupAllMemberReq)(nil), "group.GetGroupAllMemberReq") proto.RegisterType((*GetGroupAllMemberResp)(nil), "group.GetGroupAllMemberResp") proto.RegisterType((*CMSGroup)(nil), "group.CMSGroup") @@ -3536,6 +3654,7 @@ type GroupClient interface { KickGroupMember(ctx context.Context, in *KickGroupMemberReq, opts ...grpc.CallOption) (*KickGroupMemberResp, error) GetJoinedGroupList(ctx context.Context, in *GetJoinedGroupListReq, opts ...grpc.CallOption) (*GetJoinedGroupListResp, error) InviteUserToGroup(ctx context.Context, in *InviteUserToGroupReq, opts ...grpc.CallOption) (*InviteUserToGroupResp, error) + InviteUserToGroups(ctx context.Context, in *InviteUserToGroupsReq, opts ...grpc.CallOption) (*InviteUserToGroupsResp, error) GetGroupAllMember(ctx context.Context, in *GetGroupAllMemberReq, opts ...grpc.CallOption) (*GetGroupAllMemberResp, error) GetGroups(ctx context.Context, in *GetGroupsReq, opts ...grpc.CallOption) (*GetGroupsResp, error) GetGroupMembersCMS(ctx context.Context, in *GetGroupMembersCMSReq, opts ...grpc.CallOption) (*GetGroupMembersCMSResp, error) @@ -3687,6 +3806,15 @@ func (c *groupClient) InviteUserToGroup(ctx context.Context, in *InviteUserToGro return out, nil } +func (c *groupClient) InviteUserToGroups(ctx context.Context, in *InviteUserToGroupsReq, opts ...grpc.CallOption) (*InviteUserToGroupsResp, error) { + out := new(InviteUserToGroupsResp) + err := grpc.Invoke(ctx, "/group.group/inviteUserToGroups", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *groupClient) GetGroupAllMember(ctx context.Context, in *GetGroupAllMemberReq, opts ...grpc.CallOption) (*GetGroupAllMemberResp, error) { out := new(GetGroupAllMemberResp) err := grpc.Invoke(ctx, "/group.group/getGroupAllMember", in, out, c.cc, opts...) @@ -3839,6 +3967,7 @@ type GroupServer interface { KickGroupMember(context.Context, *KickGroupMemberReq) (*KickGroupMemberResp, error) GetJoinedGroupList(context.Context, *GetJoinedGroupListReq) (*GetJoinedGroupListResp, error) InviteUserToGroup(context.Context, *InviteUserToGroupReq) (*InviteUserToGroupResp, error) + InviteUserToGroups(context.Context, *InviteUserToGroupsReq) (*InviteUserToGroupsResp, error) GetGroupAllMember(context.Context, *GetGroupAllMemberReq) (*GetGroupAllMemberResp, error) GetGroups(context.Context, *GetGroupsReq) (*GetGroupsResp, error) GetGroupMembersCMS(context.Context, *GetGroupMembersCMSReq) (*GetGroupMembersCMSResp, error) @@ -4112,6 +4241,24 @@ func _Group_InviteUserToGroup_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Group_InviteUserToGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InviteUserToGroupsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GroupServer).InviteUserToGroups(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/group.group/InviteUserToGroups", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GroupServer).InviteUserToGroups(ctx, req.(*InviteUserToGroupsReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Group_GetGroupAllMember_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetGroupAllMemberReq) if err := dec(in); err != nil { @@ -4442,6 +4589,10 @@ var _Group_serviceDesc = grpc.ServiceDesc{ MethodName: "inviteUserToGroup", Handler: _Group_InviteUserToGroup_Handler, }, + { + MethodName: "inviteUserToGroups", + Handler: _Group_InviteUserToGroups_Handler, + }, { MethodName: "getGroupAllMember", Handler: _Group_GetGroupAllMember_Handler, @@ -4507,157 +4658,160 @@ var _Group_serviceDesc = grpc.ServiceDesc{ Metadata: "group/group.proto", } -func init() { proto.RegisterFile("group/group.proto", fileDescriptor_group_5cfdf63bf5b84d31) } +func init() { proto.RegisterFile("group/group.proto", fileDescriptor_group_e55c79105d50978e) } -var fileDescriptor_group_5cfdf63bf5b84d31 = []byte{ - // 2370 bytes of a gzipped FileDescriptorProto +var fileDescriptor_group_e55c79105d50978e = []byte{ + // 2425 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x1a, 0x4d, 0x6f, 0x1c, 0x49, 0x55, 0x3d, 0xe3, 0x89, 0xed, 0x67, 0x4f, 0xc6, 0x2e, 0xc7, 0xce, 0xa4, 0xe3, 0x38, 0xde, 0xde, - 0xb0, 0x58, 0x28, 0xb1, 0xc1, 0x2b, 0x45, 0xcb, 0x2e, 0xb0, 0xc4, 0x5f, 0xf1, 0x6c, 0x62, 0x1b, - 0xf7, 0x64, 0x41, 0x5a, 0x09, 0x85, 0xf6, 0x4c, 0xb9, 0x77, 0xf0, 0x4c, 0x77, 0xbb, 0xab, 0x27, - 0xce, 0x72, 0x59, 0x71, 0x41, 0x02, 0x21, 0x21, 0xc4, 0x75, 0x11, 0x82, 0x0b, 0x08, 0x01, 0xe2, - 0x00, 0x67, 0xfe, 0x00, 0x88, 0x0b, 0x17, 0xc4, 0x8d, 0x3f, 0xc0, 0x85, 0x1f, 0xb0, 0xea, 0xaa, - 0xea, 0xea, 0xea, 0xae, 0xee, 0x9e, 0xd9, 0xf6, 0x26, 0xb9, 0x8c, 0xa6, 0x5e, 0xbd, 0xaa, 0x7a, - 0xef, 0xd5, 0x7b, 0xaf, 0xde, 0x47, 0xc3, 0xbc, 0xed, 0xbb, 0x43, 0x6f, 0x83, 0xfe, 0xae, 0x7b, - 0xbe, 0x1b, 0xb8, 0xa8, 0x46, 0x07, 0xfa, 0xda, 0x91, 0x87, 0x9d, 0x7b, 0xad, 0x83, 0x7b, 0x6d, - 0xec, 0x3f, 0xc3, 0xfe, 0x86, 0x77, 0x66, 0x6f, 0x50, 0x84, 0x0d, 0xd2, 0x3d, 0x7b, 0x7a, 0x41, - 0x36, 0x2e, 0x08, 0x5b, 0xa0, 0xaf, 0x8f, 0xc4, 0xf4, 0x2d, 0xcf, 0xc3, 0x3e, 0xc7, 0x37, 0xbe, - 0x01, 0xb0, 0xed, 0x0e, 0x06, 0xae, 0x63, 0x62, 0xe2, 0xa1, 0x26, 0x4c, 0xee, 0xfa, 0xfe, 0xb6, - 0xdb, 0xc5, 0x4d, 0x6d, 0x55, 0x5b, 0xab, 0x99, 0xd1, 0x10, 0x2d, 0xc1, 0x95, 0x5d, 0xdf, 0x3f, - 0x20, 0x76, 0xb3, 0xb2, 0xaa, 0xad, 0x4d, 0x9b, 0x7c, 0x64, 0xbc, 0x07, 0xe8, 0x61, 0x48, 0xe2, - 0x83, 0x6e, 0xf7, 0x00, 0x0f, 0x4e, 0xb0, 0xdf, 0x72, 0x4e, 0xdd, 0x10, 0xfb, 0x7d, 0x82, 0xfd, - 0xd6, 0x0e, 0xdd, 0x66, 0xda, 0xe4, 0x23, 0xb4, 0x0c, 0xd3, 0xa6, 0xdb, 0xc7, 0x8f, 0xf1, 0x33, - 0xdc, 0xa7, 0x1b, 0xd5, 0xcc, 0x18, 0x60, 0xfc, 0x4f, 0x83, 0xab, 0xdb, 0x3e, 0xb6, 0x02, 0x4c, - 0xb7, 0x34, 0xf1, 0x39, 0x7a, 0x00, 0x57, 0x5b, 0x4e, 0x2f, 0x60, 0x5b, 0x3f, 0xee, 0x91, 0xa0, - 0xa9, 0xad, 0x56, 0xd7, 0x66, 0x36, 0x6f, 0xac, 0x33, 0x29, 0xa9, 0x67, 0x9b, 0xa9, 0x05, 0xe8, - 0x6d, 0x98, 0xa6, 0x58, 0xe1, 0x24, 0x3d, 0x73, 0x66, 0x73, 0x79, 0x9d, 0x50, 0xe9, 0x3c, 0xb5, - 0xbc, 0xde, 0x53, 0xcf, 0xf2, 0xad, 0x01, 0x59, 0x17, 0x38, 0x66, 0x8c, 0x8e, 0x56, 0x61, 0xe6, - 0xc8, 0xc3, 0xbe, 0x15, 0xf4, 0x5c, 0xa7, 0xb5, 0xd3, 0xac, 0x52, 0x66, 0x64, 0x10, 0xd2, 0x61, - 0xea, 0xc8, 0xe3, 0xbc, 0x4e, 0xd0, 0x69, 0x31, 0xa6, 0xab, 0x2f, 0x1c, 0xec, 0xf3, 0xe9, 0x1a, - 0x5f, 0x1d, 0x83, 0x8c, 0x8f, 0xa1, 0x91, 0x60, 0xb8, 0xcc, 0x15, 0x24, 0x19, 0xac, 0x7e, 0x26, - 0x06, 0x0d, 0x1f, 0xe6, 0x1e, 0xe2, 0x80, 0x8e, 0x09, 0x9d, 0xc3, 0xe7, 0x21, 0xd9, 0x0c, 0x61, - 0x47, 0x08, 0x7c, 0xda, 0x94, 0x41, 0x69, 0xb1, 0x54, 0x8a, 0xc5, 0x52, 0x4d, 0x8a, 0xc5, 0xf8, - 0xb1, 0x06, 0xf3, 0xa9, 0x43, 0x4b, 0xf1, 0xbd, 0x05, 0x75, 0xc1, 0x08, 0xa5, 0xb4, 0x4a, 0x55, - 0xa3, 0x98, 0xf7, 0xe4, 0x12, 0xe3, 0x97, 0x1a, 0x34, 0xda, 0x9c, 0x96, 0x88, 0xff, 0xc7, 0xd0, - 0xb0, 0xa3, 0xf1, 0x9e, 0xeb, 0xb7, 0x71, 0x40, 0x29, 0x9a, 0xd9, 0x34, 0x8a, 0x76, 0x66, 0x98, - 0x66, 0x7a, 0x69, 0x42, 0x12, 0x95, 0x0c, 0x05, 0x29, 0x54, 0x2f, 0x63, 0x17, 0xe6, 0x92, 0xe4, - 0x11, 0x0f, 0x7d, 0x45, 0x36, 0x59, 0x4e, 0xda, 0x3c, 0xb7, 0x87, 0x78, 0xc2, 0x94, 0x90, 0x8c, - 0x1f, 0x80, 0x1e, 0x49, 0xfc, 0x81, 0xe7, 0xf5, 0x7b, 0x1d, 0xba, 0x7f, 0x28, 0x81, 0x90, 0x61, - 0x99, 0x44, 0xad, 0x98, 0xc4, 0x8c, 0xab, 0x5e, 0x01, 0xd8, 0xf3, 0xdd, 0x41, 0xe2, 0xb2, 0x25, - 0x88, 0xf1, 0x89, 0x06, 0x37, 0x73, 0x0f, 0x2f, 0x75, 0xf1, 0x8f, 0x60, 0x2e, 0x72, 0x10, 0x43, - 0x4c, 0x02, 0xe9, 0xee, 0x6f, 0xe7, 0xdd, 0x10, 0x47, 0x35, 0x95, 0x85, 0x46, 0x00, 0xcb, 0x0f, - 0x71, 0x10, 0xd2, 0x6a, 0xe2, 0xf3, 0x0c, 0xe1, 0xe4, 0xb9, 0xb2, 0xcb, 0xdd, 0xeb, 0xaf, 0x34, - 0xb8, 0x55, 0x70, 0x6c, 0xa9, 0x5b, 0xce, 0x94, 0x4b, 0xa5, 0xac, 0x5c, 0xfe, 0xa6, 0xc1, 0xe2, - 0x13, 0xdf, 0x72, 0xc8, 0x29, 0xf6, 0xe9, 0x24, 0xf5, 0x5b, 0xa1, 0x44, 0x9a, 0x30, 0xc9, 0x9d, - 0x01, 0x17, 0x49, 0x34, 0x44, 0x6f, 0xc0, 0xd5, 0xa3, 0x7e, 0x57, 0xf6, 0x79, 0x4c, 0x32, 0x29, - 0x68, 0x88, 0x77, 0x88, 0x2f, 0x64, 0x3c, 0x26, 0xa2, 0x14, 0x34, 0x2d, 0xc7, 0x89, 0x62, 0x3f, - 0x53, 0x4b, 0xf9, 0x99, 0x47, 0xb0, 0x94, 0xc5, 0x40, 0x39, 0x0b, 0xfa, 0xbb, 0x06, 0xb3, 0xef, - 0xb9, 0x3d, 0x47, 0xbc, 0x4c, 0xf9, 0x52, 0x58, 0x01, 0x30, 0xf1, 0xf9, 0x01, 0x26, 0xc4, 0xb2, - 0x31, 0x97, 0x80, 0x04, 0x29, 0xf2, 0x8d, 0x63, 0x70, 0xbc, 0x02, 0x10, 0xd2, 0xd1, 0x76, 0x87, - 0x7e, 0x07, 0x53, 0x9e, 0x6b, 0xa6, 0x04, 0x41, 0x77, 0xa0, 0xde, 0x72, 0x9e, 0xf5, 0x02, 0x21, - 0xda, 0x2b, 0x74, 0x8f, 0x24, 0xd0, 0xd8, 0x82, 0xba, 0xc4, 0x4d, 0x39, 0x91, 0xfc, 0x3b, 0x34, - 0xec, 0x94, 0x55, 0x87, 0x13, 0xae, 0x43, 0x30, 0x7f, 0x47, 0x64, 0x5e, 0xb4, 0xe2, 0xdb, 0x4b, - 0xdb, 0x90, 0x24, 0xdf, 0xaa, 0x22, 0x5f, 0xc9, 0xe1, 0x4c, 0xa4, 0x1d, 0x4e, 0x38, 0xbf, 0x6f, - 0x39, 0xdd, 0x3e, 0xee, 0x86, 0xae, 0x83, 0x69, 0x85, 0x04, 0x41, 0x06, 0xcc, 0xb2, 0x91, 0x89, - 0xc9, 0xb0, 0x1f, 0x50, 0x01, 0xd5, 0xcc, 0x04, 0xcc, 0x38, 0x86, 0xe5, 0x7c, 0xd6, 0xca, 0x89, - 0xeb, 0x14, 0x66, 0x8f, 0x87, 0xbd, 0x60, 0x0c, 0x05, 0xba, 0xdc, 0xf3, 0xba, 0x05, 0x75, 0xe9, - 0x9c, 0x72, 0xb4, 0xfe, 0x5a, 0x83, 0xc5, 0xc8, 0x67, 0xc7, 0xa1, 0x54, 0x31, 0xd5, 0x97, 0x72, - 0x88, 0xa1, 0x9b, 0xdd, 0xeb, 0xf5, 0x03, 0xec, 0xd3, 0x0b, 0xad, 0x99, 0x7c, 0x14, 0x9e, 0x77, - 0x88, 0x9f, 0x07, 0x6d, 0x7c, 0xce, 0x75, 0x3d, 0x1a, 0x1a, 0x7f, 0xd0, 0x60, 0x29, 0x8b, 0xc6, - 0x52, 0x4f, 0xca, 0x1e, 0xc0, 0x20, 0x8e, 0x31, 0xd9, 0x63, 0xf2, 0x46, 0x9e, 0xd3, 0x64, 0xa7, - 0xed, 0x0d, 0xfb, 0x7d, 0xfa, 0x26, 0x4b, 0x2b, 0xc3, 0x93, 0x1d, 0x4e, 0x2e, 0xe3, 0x23, 0x1a, - 0x1a, 0xbf, 0x57, 0xc8, 0x15, 0x01, 0x57, 0xa1, 0x2b, 0x91, 0xc8, 0xaa, 0xd0, 0x48, 0x4c, 0x3e, - 0xee, 0x72, 0xae, 0x24, 0x24, 0xd6, 0xdd, 0xb6, 0x3a, 0x1f, 0x32, 0x3f, 0x32, 0x65, 0x46, 0x43, - 0xe3, 0x17, 0x1a, 0x5c, 0xcf, 0x24, 0xf6, 0x55, 0x0a, 0xd7, 0xf8, 0xb3, 0x06, 0xe8, 0x51, 0xaf, - 0x73, 0x26, 0xe1, 0x15, 0x8b, 0xef, 0x4b, 0x30, 0x17, 0xe2, 0xe3, 0x2e, 0x13, 0x89, 0x24, 0x44, - 0x05, 0x1e, 0x12, 0x6f, 0x62, 0x8b, 0xb8, 0x0e, 0x17, 0x24, 0x1f, 0xa5, 0xc5, 0x58, 0x2b, 0x36, - 0xc6, 0x2b, 0x29, 0x63, 0x7c, 0x07, 0xa6, 0x5b, 0xdd, 0x4d, 0xe6, 0x54, 0x72, 0x43, 0x09, 0x7a, - 0x34, 0x75, 0x45, 0x2c, 0x25, 0xe2, 0x23, 0xe3, 0x63, 0x58, 0x50, 0xd8, 0x2d, 0x75, 0x01, 0xf7, - 0xa1, 0x2e, 0xa8, 0x90, 0xee, 0x60, 0x8e, 0x3b, 0x01, 0x31, 0x67, 0x26, 0xd1, 0x8c, 0x21, 0xf5, - 0x02, 0xe1, 0x43, 0x81, 0xbb, 0x94, 0x8a, 0xc8, 0x0b, 0x24, 0x5d, 0xb0, 0xa6, 0xb8, 0xe0, 0x55, - 0x98, 0x71, 0x55, 0x0f, 0xe6, 0x8e, 0xe9, 0xc1, 0x7e, 0xc4, 0x4c, 0x45, 0x39, 0xf7, 0x52, 0xd9, - 0xd1, 0xd8, 0x19, 0x42, 0x8c, 0x6e, 0xfc, 0x45, 0x83, 0x6b, 0xec, 0xdd, 0x0c, 0x29, 0x7b, 0xe2, - 0x0a, 0xdf, 0x3d, 0xda, 0x43, 0xe7, 0x3f, 0x5f, 0xb1, 0xa2, 0x4d, 0x24, 0x14, 0xed, 0x2e, 0xcc, - 0xb3, 0xb3, 0x64, 0x6d, 0xad, 0x51, 0x6d, 0x55, 0x27, 0x0a, 0x95, 0xee, 0x87, 0x1a, 0x2c, 0x66, - 0x90, 0xfd, 0x52, 0x55, 0xe7, 0x13, 0x0d, 0xae, 0x89, 0xa8, 0xbf, 0xdf, 0x1f, 0xc7, 0x5a, 0x2f, - 0xfd, 0x80, 0x1c, 0x9d, 0x9e, 0x12, 0x1c, 0x44, 0x0f, 0x08, 0x1b, 0xa1, 0x6b, 0x50, 0xdb, 0x76, - 0x87, 0x4e, 0xc0, 0x9f, 0x0f, 0x36, 0x30, 0x7e, 0x2e, 0x3d, 0x70, 0x12, 0x79, 0xaf, 0xd4, 0xbd, - 0xfd, 0x46, 0x83, 0xa9, 0xed, 0x83, 0x36, 0x45, 0x4b, 0x26, 0xf5, 0xda, 0x67, 0xab, 0x5a, 0xac, - 0xf3, 0x9a, 0x8c, 0x08, 0xa5, 0x0f, 0xad, 0x41, 0x14, 0x88, 0x66, 0xcc, 0x84, 0x6e, 0x32, 0x09, - 0x15, 0x12, 0x56, 0xe0, 0xc6, 0x9f, 0x34, 0x98, 0x15, 0xc9, 0x7b, 0x78, 0x9f, 0x3b, 0x00, 0xdf, - 0xb2, 0xec, 0x9e, 0x43, 0xef, 0x81, 0x53, 0x7a, 0x27, 0x83, 0x52, 0x9e, 0x5b, 0xc4, 0xb8, 0xa6, - 0xb4, 0x0e, 0x2d, 0x73, 0x76, 0x25, 0x4a, 0x63, 0x40, 0x81, 0x31, 0x8d, 0x7c, 0xe4, 0x8c, 0x7f, - 0x69, 0x50, 0x97, 0x08, 0x26, 0x1e, 0xba, 0x07, 0xd3, 0x91, 0x98, 0x09, 0x2f, 0x27, 0x35, 0xa2, - 0x70, 0x88, 0xc3, 0xcd, 0x18, 0x03, 0xed, 0x26, 0x18, 0x64, 0x05, 0xa4, 0x2f, 0x64, 0x32, 0xc8, - 0xe2, 0xc3, 0x1c, 0x0e, 0x75, 0x98, 0x62, 0x0c, 0x0d, 0x07, 0x94, 0x89, 0x9a, 0x29, 0xc6, 0x61, - 0x84, 0xd6, 0x89, 0x23, 0xb4, 0x89, 0xdc, 0x08, 0x2d, 0x46, 0x32, 0x8e, 0xe2, 0x1a, 0xca, 0x38, - 0xb6, 0x35, 0xd2, 0x61, 0x19, 0x7f, 0x55, 0x42, 0x3e, 0xb2, 0x7d, 0xd0, 0x1e, 0x69, 0xb1, 0x29, - 0xf5, 0x12, 0xe3, 0x94, 0x5e, 0x54, 0x4b, 0xea, 0xc5, 0xe8, 0xfb, 0xfd, 0xbf, 0x1a, 0x57, 0x51, - 0xba, 0x89, 0x87, 0xbe, 0x09, 0x93, 0xcc, 0xbc, 0xa2, 0x6b, 0x1e, 0xd7, 0x2a, 0xa3, 0x65, 0x9f, - 0xd7, 0xdd, 0xaf, 0x00, 0xb0, 0x13, 0x0e, 0x87, 0x03, 0xc2, 0x6f, 0x5f, 0x82, 0x94, 0xb9, 0xff, - 0x1e, 0x34, 0x76, 0x7a, 0x64, 0xd0, 0x23, 0x44, 0x3c, 0x4a, 0x3a, 0x4c, 0xb9, 0xa9, 0x32, 0x8e, - 0xeb, 0x8d, 0xfd, 0x20, 0x37, 0x61, 0xd2, 0x4e, 0xda, 0x18, 0x1f, 0x1a, 0xbb, 0x30, 0x97, 0x3c, - 0x8a, 0xe5, 0x14, 0x9d, 0x71, 0x72, 0x0a, 0x89, 0xe2, 0xdf, 0x69, 0x80, 0x0e, 0x86, 0xbc, 0xd4, - 0x19, 0xeb, 0xec, 0x0b, 0xa2, 0x3a, 0xf4, 0xd6, 0x43, 0x39, 0x43, 0xe4, 0xa3, 0x30, 0xfb, 0x1b, - 0x0c, 0x03, 0xdc, 0x6d, 0xe3, 0x8e, 0xeb, 0x74, 0x09, 0x7d, 0x16, 0xea, 0x66, 0x02, 0x66, 0xec, - 0xc3, 0x82, 0x42, 0x69, 0x39, 0xa6, 0x7f, 0xa2, 0x41, 0x73, 0xdb, 0x72, 0x3a, 0xb8, 0xff, 0xea, - 0x59, 0x37, 0x0e, 0xe1, 0x46, 0x0e, 0x2d, 0xe5, 0x98, 0x3b, 0x85, 0x59, 0xb1, 0xd3, 0x8b, 0x54, - 0xc0, 0x2d, 0xa8, 0x4b, 0xe7, 0x94, 0xa3, 0xb5, 0x0f, 0x28, 0xc5, 0xfb, 0x8b, 0xa4, 0x78, 0x1f, - 0x16, 0x94, 0xd3, 0xca, 0xd1, 0xfd, 0x5b, 0x0d, 0x6e, 0xb4, 0x13, 0xee, 0xed, 0xb0, 0xd7, 0x39, - 0x73, 0xac, 0x01, 0xe6, 0xae, 0xd9, 0x4e, 0xba, 0x66, 0x3b, 0x76, 0xcd, 0x0e, 0x47, 0x8c, 0x5c, - 0x73, 0x34, 0x4e, 0x70, 0x5d, 0x2d, 0xe6, 0x7a, 0x42, 0xe5, 0x3a, 0xd6, 0xae, 0x5a, 0x42, 0xbb, - 0x8e, 0x40, 0xcf, 0x23, 0xb4, 0x5c, 0x11, 0xc2, 0xa7, 0x45, 0x6b, 0x96, 0x05, 0xb4, 0x87, 0x1e, - 0xaf, 0xe2, 0x45, 0x29, 0x48, 0x8a, 0x50, 0xad, 0x88, 0xd0, 0x4a, 0xc2, 0x03, 0x14, 0xb0, 0x6f, - 0xfc, 0x94, 0x15, 0xab, 0xb3, 0x0f, 0x2d, 0x75, 0x83, 0x97, 0x4a, 0x40, 0x2e, 0xe8, 0x9b, 0x1c, - 0xd3, 0xf1, 0xd2, 0x7a, 0x34, 0x3f, 0x63, 0xaf, 0xaa, 0x72, 0x72, 0x39, 0x11, 0x7c, 0x1e, 0x9d, - 0x9a, 0xff, 0x56, 0x60, 0x31, 0xa9, 0x5f, 0x52, 0xf9, 0x24, 0xc7, 0x08, 0x4a, 0x68, 0xc0, 0x18, - 0x06, 0xf0, 0x96, 0x64, 0x5a, 0x35, 0x1e, 0x99, 0xdb, 0xae, 0x6b, 0xf7, 0x31, 0xeb, 0xa9, 0x9e, - 0x0c, 0x4f, 0xd7, 0xdb, 0x81, 0xdf, 0x73, 0xec, 0x6f, 0x5b, 0xfd, 0x21, 0x96, 0x0c, 0xef, 0x3e, - 0x4c, 0x9e, 0x5a, 0x1d, 0xfc, 0xbe, 0xf9, 0x98, 0xe6, 0x6c, 0xa3, 0x16, 0x46, 0xc8, 0xe8, 0xab, - 0x30, 0xed, 0x8b, 0xb6, 0xe9, 0x24, 0x5d, 0x79, 0x53, 0x59, 0xd9, 0x72, 0x82, 0x37, 0x37, 0xd9, - 0xc2, 0x18, 0x1b, 0xdd, 0x85, 0x0a, 0x7e, 0xde, 0x9c, 0x1a, 0xe3, 0xb4, 0x0a, 0x7e, 0x6e, 0x3c, - 0x82, 0xa5, 0x2c, 0x19, 0x97, 0xb3, 0xdf, 0xf3, 0xb8, 0x86, 0xf4, 0xe0, 0x84, 0x04, 0xbe, 0xd5, - 0x09, 0x46, 0x5f, 0x99, 0x7c, 0x35, 0x95, 0xe2, 0xab, 0xa9, 0x2a, 0x57, 0x63, 0xfc, 0x51, 0x83, - 0x66, 0xf6, 0x99, 0xe5, 0x3a, 0x2a, 0x77, 0x79, 0x4f, 0x5e, 0xc4, 0x6a, 0x27, 0xd8, 0xe7, 0x45, - 0x1a, 0x75, 0x02, 0x7d, 0x19, 0x16, 0xec, 0x64, 0x35, 0x72, 0xdf, 0x22, 0x1f, 0x52, 0x3a, 0x27, - 0xcc, 0xac, 0x29, 0xe3, 0x1c, 0x1a, 0x4c, 0xcb, 0xc9, 0xee, 0xf3, 0xd8, 0xaf, 0xd9, 0xaa, 0x65, - 0x4b, 0xa0, 0x4b, 0x8a, 0xe8, 0x1f, 0x1a, 0xcf, 0xf6, 0xc4, 0x99, 0xe5, 0x44, 0xf3, 0x10, 0x80, - 0xef, 0x70, 0x60, 0x79, 0xbc, 0xcd, 0xf4, 0x45, 0xb9, 0x2b, 0x2f, 0xed, 0xbf, 0x1e, 0x63, 0xee, - 0x3a, 0x81, 0xff, 0x91, 0x29, 0x2d, 0xd5, 0xbf, 0x0e, 0x8d, 0xd4, 0x34, 0x9a, 0x83, 0xea, 0x19, - 0xfe, 0x88, 0xab, 0x46, 0xf8, 0x37, 0xcc, 0xe2, 0x9f, 0x85, 0x5a, 0x4a, 0x19, 0x9e, 0x32, 0xd9, - 0xe0, 0xed, 0xca, 0x5b, 0x9a, 0xe1, 0xc0, 0x1c, 0xe5, 0x9d, 0xb4, 0x12, 0xbd, 0x99, 0x1c, 0xf5, - 0x5a, 0x01, 0x18, 0xa6, 0x6b, 0x81, 0x12, 0x64, 0x0c, 0xf9, 0xfd, 0x53, 0x83, 0xf9, 0xd4, 0x81, - 0xe5, 0x04, 0xb8, 0x9f, 0x21, 0xc0, 0x35, 0xbe, 0x44, 0x39, 0xe0, 0x05, 0x4a, 0x70, 0xf3, 0x3f, - 0xf3, 0xc0, 0x3e, 0x33, 0x41, 0x5f, 0x83, 0x99, 0x4e, 0xfc, 0x39, 0x02, 0x5a, 0x8c, 0x18, 0x48, - 0x7c, 0x93, 0xa1, 0x2f, 0x65, 0x81, 0x89, 0x87, 0xee, 0xc3, 0xf4, 0xf7, 0xa3, 0x9e, 0x12, 0x5a, - 0xe0, 0x48, 0x72, 0xcf, 0x4c, 0xbf, 0xa6, 0x02, 0xd9, 0xba, 0xf3, 0xa8, 0x61, 0x21, 0xd6, 0xc9, - 0xad, 0x12, 0xb1, 0x2e, 0xd9, 0xd7, 0xd8, 0x82, 0xba, 0x2d, 0x7f, 0x46, 0x80, 0xae, 0x47, 0xea, - 0x97, 0xfa, 0xa2, 0x41, 0x6f, 0x66, 0x4f, 0x10, 0x0f, 0xbd, 0x0b, 0xb3, 0x44, 0xea, 0xaf, 0xa3, - 0x88, 0xb7, 0xd4, 0x37, 0x01, 0xfa, 0xf5, 0x4c, 0x38, 0xf1, 0xd0, 0xf7, 0xe0, 0xba, 0x9d, 0xdd, - 0xdc, 0x46, 0xaf, 0xa5, 0x4e, 0x55, 0x9b, 0xcb, 0xba, 0x31, 0x0a, 0x85, 0x78, 0xe8, 0x14, 0x6e, - 0xd8, 0x79, 0x9d, 0x62, 0xf4, 0x7a, 0xbc, 0x41, 0x6e, 0x0b, 0x5b, 0xbf, 0x33, 0x1a, 0x89, 0x78, - 0xe8, 0x18, 0x50, 0xa0, 0xb4, 0x4b, 0xd1, 0x32, 0x5f, 0x9b, 0xd9, 0x0a, 0xd6, 0x6f, 0x15, 0xcc, - 0x12, 0x0f, 0x75, 0xa0, 0x69, 0xe7, 0x74, 0xd1, 0x90, 0x91, 0xf8, 0x82, 0x27, 0xb3, 0x83, 0xa8, - 0xbf, 0x3e, 0x12, 0x87, 0xd1, 0x6d, 0x2b, 0x6d, 0x20, 0x41, 0x77, 0x66, 0x17, 0x4b, 0xd0, 0x9d, - 0xd3, 0x3f, 0x7a, 0x02, 0x0b, 0xb6, 0xda, 0xfd, 0x40, 0xd9, 0xab, 0x84, 0x96, 0xad, 0x14, 0x4d, - 0x53, 0x83, 0x6f, 0x9c, 0x25, 0xcb, 0xf9, 0x28, 0xfa, 0x8c, 0x49, 0xed, 0x6a, 0xe8, 0x7a, 0xde, - 0x94, 0x60, 0x39, 0x55, 0x1f, 0x97, 0x59, 0x56, 0x4b, 0xf6, 0x32, 0xcb, 0x59, 0x85, 0xf5, 0x43, - 0x98, 0xef, 0xa5, 0x4b, 0xc6, 0xe8, 0x66, 0x54, 0xe5, 0xcd, 0xa8, 0x81, 0xeb, 0xcb, 0xf9, 0x93, - 0x6c, 0x3f, 0x3b, 0x5d, 0x5f, 0x15, 0xfb, 0x65, 0x15, 0x86, 0xf5, 0xe5, 0xfc, 0x49, 0xe6, 0x24, - 0x84, 0xf5, 0x0a, 0x27, 0x21, 0x17, 0x22, 0x85, 0x93, 0x48, 0x16, 0xfb, 0x8e, 0x01, 0xa9, 0xd5, - 0xa1, 0x1c, 0xed, 0xe0, 0x05, 0xaf, 0x1c, 0xed, 0x10, 0x65, 0xa5, 0x77, 0x61, 0x56, 0xae, 0x87, - 0x08, 0x9f, 0x91, 0xaa, 0xc7, 0x08, 0x9f, 0xa1, 0x14, 0x4f, 0xf6, 0xa1, 0x91, 0xca, 0xc0, 0x85, - 0x22, 0xa8, 0x55, 0x02, 0xa1, 0x08, 0x59, 0x49, 0xfb, 0x07, 0xb0, 0x98, 0x99, 0xd1, 0xa3, 0xdb, - 0x91, 0x8f, 0xce, 0xa9, 0x3d, 0xe8, 0xab, 0xc5, 0x08, 0x4c, 0xe2, 0x02, 0x2c, 0x24, 0x2e, 0x67, - 0xcf, 0x42, 0xe2, 0xc9, 0x24, 0x77, 0x1f, 0x1a, 0xa9, 0x4d, 0x05, 0x77, 0x6a, 0x06, 0x2e, 0xb8, - 0xcb, 0x4a, 0x97, 0xbf, 0x9b, 0x8e, 0x46, 0xa3, 0x8c, 0x12, 0xad, 0xa6, 0xdc, 0xb1, 0x92, 0x19, - 0xeb, 0xaf, 0x8d, 0xc0, 0x60, 0xae, 0x3b, 0x27, 0xd5, 0x93, 0x5d, 0x77, 0x4e, 0xfe, 0x29, 0xbb, - 0xee, 0xdc, 0x6c, 0x91, 0x29, 0x5f, 0x2a, 0x89, 0x92, 0x95, 0x4f, 0xcd, 0xec, 0x64, 0xe5, 0xcb, - 0xca, 0xbe, 0x8e, 0x01, 0xa9, 0x11, 0xba, 0xd8, 0x32, 0x33, 0x41, 0x12, 0x5b, 0xe6, 0x84, 0xf6, - 0xdf, 0x91, 0x3a, 0x35, 0x52, 0xcc, 0x8c, 0xd2, 0xfe, 0x2c, 0x15, 0xc4, 0xeb, 0xb7, 0x0b, 0xe7, - 0x99, 0xa1, 0xc8, 0x91, 0xa0, 0x30, 0x94, 0x54, 0xc8, 0x2b, 0x0c, 0x45, 0x09, 0x4b, 0xb7, 0xa0, - 0x9e, 0x88, 0x84, 0xc4, 0x0b, 0x9f, 0x8e, 0xf8, 0xc4, 0x0b, 0xaf, 0x04, 0x4e, 0x5b, 0xb7, 0x3f, - 0xb8, 0x75, 0xe4, 0x61, 0xe7, 0x69, 0xeb, 0x40, 0xfa, 0x16, 0x96, 0x22, 0xbf, 0x43, 0x7f, 0x4f, - 0xae, 0x50, 0xd0, 0x9b, 0x9f, 0x06, 0x00, 0x00, 0xff, 0xff, 0xe7, 0x7e, 0x59, 0x05, 0x7e, 0x2b, - 0x00, 0x00, + 0xb0, 0x58, 0x28, 0xb1, 0xc1, 0x2b, 0x45, 0xcb, 0x2e, 0xb0, 0xc4, 0x5f, 0xf1, 0x24, 0xb1, 0x8d, + 0x7b, 0xb2, 0x20, 0xad, 0x84, 0x42, 0x7b, 0xa6, 0xdc, 0x3b, 0x78, 0xa6, 0xbb, 0xdd, 0xd5, 0x13, + 0x67, 0xb9, 0xac, 0xb8, 0x20, 0x81, 0x90, 0x10, 0xe2, 0xba, 0x08, 0xc1, 0x05, 0x84, 0x60, 0xc5, + 0x01, 0xce, 0xfc, 0x01, 0x10, 0x17, 0x2e, 0x5c, 0xf9, 0x03, 0x5c, 0xf8, 0x01, 0xab, 0xae, 0xaa, + 0xae, 0xae, 0xee, 0xea, 0xee, 0x99, 0x6d, 0x6f, 0x36, 0x97, 0xd1, 0xd4, 0xab, 0x57, 0x55, 0xef, + 0xbd, 0x7a, 0xef, 0xd5, 0xfb, 0x68, 0x98, 0xb7, 0x7d, 0x77, 0xe8, 0x6d, 0xd0, 0xdf, 0x75, 0xcf, + 0x77, 0x03, 0x17, 0xd5, 0xe8, 0x40, 0x5f, 0x3b, 0xf2, 0xb0, 0x73, 0xaf, 0x75, 0x70, 0xaf, 0x8d, + 0xfd, 0xe7, 0xd8, 0xdf, 0xf0, 0xce, 0xec, 0x0d, 0x8a, 0xb0, 0x41, 0xba, 0x67, 0xcf, 0x2e, 0xc8, + 0xc6, 0x05, 0x61, 0x0b, 0xf4, 0xf5, 0x91, 0x98, 0xbe, 0xe5, 0x79, 0xd8, 0xe7, 0xf8, 0xc6, 0xb7, + 0x00, 0xb6, 0xdd, 0xc1, 0xc0, 0x75, 0x4c, 0x4c, 0x3c, 0xd4, 0x84, 0xc9, 0x5d, 0xdf, 0xdf, 0x76, + 0xbb, 0xb8, 0xa9, 0xad, 0x6a, 0x6b, 0x35, 0x33, 0x1a, 0xa2, 0x25, 0xb8, 0xb2, 0xeb, 0xfb, 0x07, + 0xc4, 0x6e, 0x56, 0x56, 0xb5, 0xb5, 0x69, 0x93, 0x8f, 0x8c, 0x47, 0x80, 0x1e, 0x86, 0x24, 0x3e, + 0xe8, 0x76, 0x0f, 0xf0, 0xe0, 0x04, 0xfb, 0x2d, 0xe7, 0xd4, 0x0d, 0xb1, 0xdf, 0x23, 0xd8, 0x6f, + 0xed, 0xd0, 0x6d, 0xa6, 0x4d, 0x3e, 0x42, 0xcb, 0x30, 0x6d, 0xba, 0x7d, 0xfc, 0x04, 0x3f, 0xc7, + 0x7d, 0xba, 0x51, 0xcd, 0x8c, 0x01, 0xc6, 0xff, 0x34, 0xb8, 0xba, 0xed, 0x63, 0x2b, 0xc0, 0x74, + 0x4b, 0x13, 0x9f, 0xa3, 0x07, 0x70, 0xb5, 0xe5, 0xf4, 0x02, 0xb6, 0xf5, 0x93, 0x1e, 0x09, 0x9a, + 0xda, 0x6a, 0x75, 0x6d, 0x66, 0xf3, 0xc6, 0x3a, 0x93, 0x92, 0x7a, 0xb6, 0x99, 0x5a, 0x80, 0xde, + 0x86, 0x69, 0x8a, 0x15, 0x4e, 0xd2, 0x33, 0x67, 0x36, 0x97, 0xd7, 0x09, 0x95, 0xce, 0x33, 0xcb, + 0xeb, 0x3d, 0xf3, 0x2c, 0xdf, 0x1a, 0x90, 0x75, 0x81, 0x63, 0xc6, 0xe8, 0x68, 0x15, 0x66, 0x8e, + 0x3c, 0xec, 0x5b, 0x41, 0xcf, 0x75, 0x5a, 0x3b, 0xcd, 0x2a, 0x65, 0x46, 0x06, 0x21, 0x1d, 0xa6, + 0x8e, 0x3c, 0xce, 0xeb, 0x04, 0x9d, 0x16, 0x63, 0xba, 0xfa, 0xc2, 0xc1, 0x3e, 0x9f, 0xae, 0xf1, + 0xd5, 0x31, 0xc8, 0xf8, 0x08, 0x1a, 0x09, 0x86, 0xcb, 0x5c, 0x41, 0x92, 0xc1, 0xea, 0x67, 0x62, + 0xd0, 0xf0, 0x61, 0xee, 0x21, 0x0e, 0xe8, 0x98, 0xd0, 0x39, 0x7c, 0x1e, 0x92, 0xcd, 0x10, 0x76, + 0x84, 0xc0, 0xa7, 0x4d, 0x19, 0x94, 0x16, 0x4b, 0xa5, 0x58, 0x2c, 0xd5, 0xa4, 0x58, 0x8c, 0x9f, + 0x6a, 0x30, 0x9f, 0x3a, 0xb4, 0x14, 0xdf, 0x5b, 0x50, 0x17, 0x8c, 0x50, 0x4a, 0xab, 0x54, 0x35, + 0x8a, 0x79, 0x4f, 0x2e, 0x31, 0x7e, 0xad, 0x41, 0xa3, 0xcd, 0x69, 0x89, 0xf8, 0x7f, 0x02, 0x0d, + 0x3b, 0x1a, 0xef, 0xb9, 0x7e, 0x1b, 0x07, 0x94, 0xa2, 0x99, 0x4d, 0xa3, 0x68, 0x67, 0x86, 0x69, + 0xa6, 0x97, 0x26, 0x24, 0x51, 0xc9, 0x50, 0x90, 0x42, 0xf5, 0x32, 0x76, 0x61, 0x2e, 0x49, 0x1e, + 0xf1, 0xd0, 0xd7, 0x64, 0x93, 0xe5, 0xa4, 0xcd, 0x73, 0x7b, 0x88, 0x27, 0x4c, 0x09, 0xc9, 0xf8, + 0x11, 0xe8, 0x91, 0xc4, 0x1f, 0x78, 0x5e, 0xbf, 0xd7, 0xa1, 0xfb, 0x87, 0x12, 0x08, 0x19, 0x96, + 0x49, 0xd4, 0x8a, 0x49, 0xcc, 0xb8, 0xea, 0x15, 0x80, 0x3d, 0xdf, 0x1d, 0x24, 0x2e, 0x5b, 0x82, + 0x18, 0x1f, 0x6b, 0x70, 0x33, 0xf7, 0xf0, 0x52, 0x17, 0xff, 0x18, 0xe6, 0x22, 0x07, 0x31, 0xc4, + 0x24, 0x90, 0xee, 0xfe, 0x76, 0xde, 0x0d, 0x71, 0x54, 0x53, 0x59, 0x68, 0x04, 0xb0, 0xfc, 0x10, + 0x07, 0x21, 0xad, 0x26, 0x3e, 0xcf, 0x10, 0x4e, 0x9e, 0x2b, 0xbb, 0xdc, 0xbd, 0xfe, 0x46, 0x83, + 0x5b, 0x05, 0xc7, 0x96, 0xba, 0xe5, 0x4c, 0xb9, 0x54, 0xca, 0xca, 0xe5, 0xef, 0x1a, 0x2c, 0x3e, + 0xf5, 0x2d, 0x87, 0x9c, 0x62, 0x9f, 0x4e, 0x52, 0xbf, 0x15, 0x4a, 0xa4, 0x09, 0x93, 0xdc, 0x19, + 0x70, 0x91, 0x44, 0x43, 0xf4, 0x06, 0x5c, 0x3d, 0xea, 0x77, 0x65, 0x9f, 0xc7, 0x24, 0x93, 0x82, + 0x86, 0x78, 0x87, 0xf8, 0x42, 0xc6, 0x63, 0x22, 0x4a, 0x41, 0xd3, 0x72, 0x9c, 0x28, 0xf6, 0x33, + 0xb5, 0x94, 0x9f, 0x79, 0x0c, 0x4b, 0x59, 0x0c, 0x94, 0xb3, 0xa0, 0x7f, 0x68, 0x30, 0xfb, 0xc8, + 0xed, 0x39, 0xe2, 0x65, 0xca, 0x97, 0xc2, 0x0a, 0x80, 0x89, 0xcf, 0x0f, 0x30, 0x21, 0x96, 0x8d, + 0xb9, 0x04, 0x24, 0x48, 0x91, 0x6f, 0x1c, 0x83, 0xe3, 0x15, 0x80, 0x90, 0x8e, 0xb6, 0x3b, 0xf4, + 0x3b, 0x98, 0xf2, 0x5c, 0x33, 0x25, 0x08, 0xba, 0x03, 0xf5, 0x96, 0xf3, 0xbc, 0x17, 0x08, 0xd1, + 0x5e, 0xa1, 0x7b, 0x24, 0x81, 0xc6, 0x16, 0xd4, 0x25, 0x6e, 0xca, 0x89, 0xe4, 0x3f, 0xa1, 0x61, + 0xa7, 0xac, 0x3a, 0x9c, 0x70, 0x1d, 0x82, 0xf9, 0x3b, 0x22, 0xf3, 0xa2, 0x15, 0xdf, 0x5e, 0xda, + 0x86, 0x24, 0xf9, 0x56, 0x15, 0xf9, 0x4a, 0x0e, 0x67, 0x22, 0xed, 0x70, 0xc2, 0xf9, 0x7d, 0xcb, + 0xe9, 0xf6, 0x71, 0x37, 0x74, 0x1d, 0x4c, 0x2b, 0x24, 0x08, 0x32, 0x60, 0x96, 0x8d, 0x4c, 0x4c, + 0x86, 0xfd, 0x80, 0x0a, 0xa8, 0x66, 0x26, 0x60, 0xc6, 0x31, 0x2c, 0xe7, 0xb3, 0x56, 0x4e, 0x5c, + 0xa7, 0x30, 0x7b, 0x3c, 0xec, 0x05, 0x63, 0x28, 0xd0, 0xe5, 0x9e, 0xd7, 0x2d, 0xa8, 0x4b, 0xe7, + 0x94, 0xa3, 0xf5, 0xb7, 0x1a, 0x2c, 0x46, 0x3e, 0x3b, 0x0e, 0xa5, 0x8a, 0xa9, 0xbe, 0x94, 0x43, + 0x0c, 0xdd, 0xec, 0x5e, 0xaf, 0x1f, 0x60, 0x9f, 0x5e, 0x68, 0xcd, 0xe4, 0xa3, 0xf0, 0xbc, 0x43, + 0xfc, 0x22, 0x68, 0xe3, 0x73, 0xae, 0xeb, 0xd1, 0xd0, 0xf8, 0x93, 0x06, 0x4b, 0x59, 0x34, 0x96, + 0x7a, 0x52, 0xf6, 0x00, 0x06, 0x71, 0x8c, 0xc9, 0x1e, 0x93, 0x37, 0xf2, 0x9c, 0x26, 0x3b, 0x6d, + 0x6f, 0xd8, 0xef, 0xd3, 0x37, 0x59, 0x5a, 0x19, 0x9e, 0xec, 0x70, 0x72, 0x19, 0x1f, 0xd1, 0xd0, + 0xf8, 0xa3, 0x42, 0xae, 0x08, 0xb8, 0x0a, 0x5d, 0x89, 0x44, 0x56, 0x85, 0x46, 0x62, 0xf2, 0x71, + 0x97, 0x73, 0x25, 0x21, 0xb1, 0xee, 0xb6, 0xd5, 0xf9, 0x80, 0xf9, 0x91, 0x29, 0x33, 0x1a, 0x1a, + 0xbf, 0xd2, 0xe0, 0x7a, 0x26, 0xb1, 0xaf, 0x52, 0xb8, 0xc6, 0x5f, 0x34, 0x40, 0x8f, 0x7b, 0x9d, + 0x33, 0x09, 0xaf, 0x58, 0x7c, 0x5f, 0x81, 0xb9, 0x10, 0x1f, 0x77, 0x99, 0x48, 0x24, 0x21, 0x2a, + 0xf0, 0x90, 0x78, 0x13, 0x5b, 0xc4, 0x75, 0xb8, 0x20, 0xf9, 0x28, 0x2d, 0xc6, 0x5a, 0xb1, 0x31, + 0x5e, 0x49, 0x19, 0xe3, 0x3b, 0x30, 0xdd, 0xea, 0x6e, 0x32, 0xa7, 0x92, 0x1b, 0x4a, 0xd0, 0xa3, + 0xa9, 0x2b, 0x62, 0x29, 0x11, 0x1f, 0x19, 0x1f, 0xc1, 0x82, 0xc2, 0x6e, 0xa9, 0x0b, 0xb8, 0x0f, + 0x75, 0x41, 0x85, 0x74, 0x07, 0x73, 0xdc, 0x09, 0x88, 0x39, 0x33, 0x89, 0x66, 0x0c, 0xa9, 0x17, + 0x08, 0x1f, 0x0a, 0xdc, 0xa5, 0x54, 0x44, 0x5e, 0x20, 0xe9, 0x82, 0x35, 0xc5, 0x05, 0xaf, 0xc2, + 0x8c, 0xab, 0x7a, 0x30, 0x77, 0x4c, 0x0f, 0xf6, 0x13, 0x66, 0x2a, 0xca, 0xb9, 0x97, 0xca, 0x8e, + 0xc6, 0xce, 0x10, 0x62, 0x74, 0xe3, 0xaf, 0x1a, 0x5c, 0x63, 0xef, 0x66, 0x48, 0xd9, 0x53, 0x57, + 0xf8, 0xee, 0xd1, 0x1e, 0x3a, 0xff, 0xf9, 0x8a, 0x15, 0x6d, 0x22, 0xa1, 0x68, 0x77, 0x61, 0x9e, + 0x9d, 0x25, 0x6b, 0x6b, 0x8d, 0x6a, 0xab, 0x3a, 0x51, 0xa8, 0x74, 0x3f, 0xd6, 0x60, 0x31, 0x83, + 0xec, 0x2f, 0x54, 0x75, 0xfe, 0x96, 0x45, 0x03, 0x19, 0x2f, 0x2c, 0x58, 0x85, 0x19, 0x5b, 0x4a, + 0x40, 0x99, 0xc5, 0xca, 0xa0, 0x5c, 0x63, 0xbd, 0x03, 0xf5, 0x9e, 0x2c, 0x2a, 0x2e, 0xe2, 0x24, + 0xb0, 0x30, 0x68, 0x7c, 0x04, 0x4b, 0x59, 0x64, 0x97, 0xaa, 0x8d, 0x7c, 0xac, 0xc1, 0x35, 0x91, + 0xf9, 0xf4, 0xfb, 0xe3, 0x78, 0xac, 0x4b, 0x3f, 0xa2, 0x47, 0xa7, 0xa7, 0x04, 0x07, 0xd1, 0x23, + 0xca, 0x46, 0xe8, 0x1a, 0xd4, 0xb6, 0xdd, 0xa1, 0x13, 0xf0, 0x27, 0x94, 0x0d, 0x8c, 0x5f, 0x4a, + 0x8f, 0xbc, 0x44, 0xde, 0x2b, 0x75, 0xf1, 0xbf, 0xd3, 0x60, 0x6a, 0xfb, 0xa0, 0x4d, 0xd1, 0x92, + 0x85, 0x0d, 0xed, 0xb3, 0x55, 0x6e, 0xd6, 0x79, 0x5d, 0x4a, 0xa4, 0x13, 0x87, 0xd6, 0x20, 0x0a, + 0xc6, 0x33, 0x66, 0xc2, 0xa7, 0x22, 0x09, 0x15, 0x12, 0x56, 0xe0, 0xc6, 0x27, 0x1a, 0xcc, 0x8a, + 0x02, 0x46, 0x78, 0x9f, 0x3b, 0x00, 0xdf, 0xb1, 0xec, 0x9e, 0x43, 0xef, 0x81, 0x53, 0x7a, 0x27, + 0x83, 0x52, 0x9e, 0x5f, 0xc5, 0xb8, 0xa6, 0xb4, 0x0e, 0x2d, 0x73, 0x76, 0x25, 0x4a, 0x63, 0x40, + 0x81, 0x43, 0x19, 0xf9, 0xd0, 0x1b, 0xff, 0xd6, 0xa0, 0x2e, 0x11, 0x4c, 0x3c, 0x74, 0x0f, 0xa6, + 0x23, 0x31, 0x13, 0x5e, 0x52, 0x6b, 0x44, 0x21, 0x21, 0x87, 0x9b, 0x31, 0x06, 0xda, 0x4d, 0x30, + 0xc8, 0x8a, 0x68, 0x5f, 0xca, 0x64, 0x90, 0xc5, 0xc8, 0x39, 0x1c, 0xea, 0x30, 0xc5, 0x18, 0x1a, + 0x0e, 0x28, 0x13, 0x35, 0x53, 0x8c, 0xc3, 0x28, 0xb5, 0x13, 0x47, 0xa9, 0x13, 0xb9, 0x51, 0x6a, + 0x8c, 0x64, 0x1c, 0xc5, 0x75, 0xa4, 0x71, 0x6c, 0x6b, 0xa4, 0xd3, 0xa6, 0x4e, 0x2b, 0x15, 0xf6, + 0x6c, 0x1f, 0xb4, 0x47, 0x5a, 0x6c, 0x4a, 0xbd, 0xc4, 0x38, 0xa5, 0x17, 0xd5, 0x92, 0x7a, 0x31, + 0xfa, 0x7e, 0xff, 0xaf, 0xc6, 0x96, 0x94, 0x6e, 0xe2, 0xa1, 0x6f, 0xc3, 0x24, 0x33, 0xaf, 0xe8, + 0x9a, 0xc7, 0xb5, 0xca, 0x68, 0xd9, 0xe7, 0x75, 0xf7, 0x2b, 0x00, 0xec, 0x84, 0xc3, 0xe1, 0x80, + 0xf0, 0xdb, 0x97, 0x20, 0x65, 0xee, 0xbf, 0x07, 0x8d, 0x9d, 0x1e, 0x19, 0xf4, 0x08, 0x11, 0x0f, + 0xb3, 0x0e, 0x53, 0x6e, 0xaa, 0x94, 0xe5, 0x7a, 0x63, 0x07, 0x25, 0x4d, 0x98, 0xb4, 0x93, 0x36, + 0xc6, 0x87, 0xc6, 0x2e, 0xcc, 0x25, 0x8f, 0x62, 0x79, 0x55, 0x67, 0x9c, 0xbc, 0x4a, 0xa2, 0xf8, + 0x0f, 0x1a, 0xa0, 0x83, 0x21, 0x2f, 0xf7, 0xc6, 0x3a, 0xfb, 0x92, 0xa8, 0x0e, 0xbd, 0xf5, 0x50, + 0x7e, 0x07, 0xf9, 0x28, 0xcc, 0x80, 0x07, 0xc3, 0x00, 0x77, 0xdb, 0xb8, 0xe3, 0x3a, 0x5d, 0x42, + 0x9f, 0x85, 0xba, 0x99, 0x80, 0x19, 0xfb, 0xb0, 0xa0, 0x50, 0x5a, 0x8e, 0xe9, 0x9f, 0x69, 0xd0, + 0xdc, 0xb6, 0x9c, 0x0e, 0xee, 0xbf, 0x7a, 0xd6, 0x8d, 0x43, 0xb8, 0x91, 0x43, 0x4b, 0x39, 0xe6, + 0x4e, 0x61, 0x56, 0xec, 0xf4, 0x32, 0x15, 0x70, 0x0b, 0xea, 0xd2, 0x39, 0xe5, 0x68, 0xed, 0x03, + 0x4a, 0xf1, 0xfe, 0x32, 0x29, 0xde, 0x87, 0x05, 0xe5, 0xb4, 0x72, 0x74, 0xff, 0x5e, 0x83, 0x1b, + 0xed, 0x84, 0x7b, 0x3b, 0xec, 0x75, 0xce, 0x1c, 0x6b, 0x80, 0xb9, 0x6b, 0xb6, 0x93, 0xae, 0xd9, + 0x8e, 0x5d, 0xb3, 0xc3, 0x11, 0x23, 0xd7, 0x1c, 0x8d, 0x13, 0x5c, 0x57, 0x8b, 0xb9, 0x9e, 0x50, + 0xb9, 0x8e, 0xb5, 0xab, 0x96, 0xd0, 0xae, 0x23, 0xd0, 0xf3, 0x08, 0x2d, 0x57, 0x88, 0xf1, 0x69, + 0xe1, 0x9e, 0x65, 0x42, 0xed, 0xa1, 0xc7, 0x2b, 0x99, 0x51, 0x1a, 0x96, 0x22, 0x54, 0x2b, 0x22, + 0xb4, 0x92, 0xf0, 0x00, 0x05, 0xec, 0x1b, 0x3f, 0x67, 0x05, 0xfb, 0xec, 0x43, 0x4b, 0xdd, 0xe0, + 0xa5, 0x92, 0xb0, 0x0b, 0xfa, 0x26, 0xc7, 0x74, 0x7c, 0x61, 0x7d, 0xaa, 0x5f, 0xb0, 0x57, 0x55, + 0x39, 0xb9, 0x9c, 0x08, 0x3e, 0x8f, 0x6e, 0xd5, 0x7f, 0x2b, 0xb0, 0x98, 0xd4, 0x2f, 0xa9, 0x84, + 0x94, 0x63, 0x04, 0x25, 0x34, 0x60, 0x0c, 0x03, 0x78, 0x4b, 0x32, 0xad, 0x1a, 0x8f, 0xcc, 0x6d, + 0xd7, 0xb5, 0xfb, 0x98, 0xf5, 0x95, 0x4f, 0x86, 0xa7, 0xeb, 0xed, 0xc0, 0xef, 0x39, 0xf6, 0x77, + 0xad, 0xfe, 0x10, 0x4b, 0x86, 0x77, 0x1f, 0x26, 0x4f, 0xad, 0x0e, 0x7e, 0xcf, 0x7c, 0x42, 0xf3, + 0xd6, 0x51, 0x0b, 0x23, 0x64, 0xf4, 0x75, 0x98, 0xf6, 0x45, 0xeb, 0x78, 0x92, 0xae, 0xbc, 0xa9, + 0xac, 0x6c, 0x39, 0xc1, 0x9b, 0x9b, 0x6c, 0x61, 0x8c, 0x8d, 0xee, 0x42, 0x05, 0xbf, 0x68, 0x4e, + 0x8d, 0x71, 0x5a, 0x05, 0xbf, 0x30, 0x1e, 0xc3, 0x52, 0x96, 0x8c, 0xcb, 0xd9, 0xef, 0x79, 0x5c, + 0x47, 0x7b, 0x70, 0x42, 0x02, 0xdf, 0xea, 0x04, 0xa3, 0xaf, 0x4c, 0xbe, 0x9a, 0x4a, 0xf1, 0xd5, + 0x54, 0x95, 0xab, 0x31, 0xfe, 0xac, 0x41, 0x33, 0xfb, 0xcc, 0x72, 0x5d, 0xa5, 0xbb, 0xfc, 0xbb, + 0x04, 0x11, 0xab, 0x9d, 0x60, 0x9f, 0x17, 0xaa, 0xd4, 0x09, 0xf4, 0x55, 0x58, 0xb0, 0x93, 0x15, + 0xd9, 0x7d, 0x8b, 0x7c, 0x40, 0xe9, 0x9c, 0x30, 0xb3, 0xa6, 0x8c, 0x73, 0x68, 0x30, 0x2d, 0x27, + 0xbb, 0x2f, 0x62, 0xbf, 0x66, 0xab, 0x96, 0x2d, 0x17, 0x00, 0x2e, 0x27, 0xa2, 0x7f, 0x6a, 0x3c, + 0xdb, 0x13, 0x67, 0x96, 0x13, 0xcd, 0x43, 0x00, 0xbe, 0xc3, 0x81, 0xe5, 0xf1, 0x56, 0xdb, 0x97, + 0xe5, 0x2f, 0x13, 0xa4, 0xfd, 0xd7, 0x63, 0xcc, 0x5d, 0x27, 0xf0, 0x3f, 0x34, 0xa5, 0xa5, 0xfa, + 0x37, 0xa1, 0x91, 0x9a, 0x46, 0x73, 0x50, 0x3d, 0xc3, 0x1f, 0x72, 0xd5, 0x08, 0xff, 0x86, 0x59, + 0xfc, 0xf3, 0x50, 0x4b, 0x29, 0xc3, 0x53, 0x26, 0x1b, 0xbc, 0x5d, 0x79, 0x4b, 0x33, 0x1c, 0x98, + 0xa3, 0xbc, 0x93, 0x56, 0xa2, 0x3f, 0x95, 0xa3, 0x5e, 0x2b, 0x00, 0xc3, 0x74, 0x3d, 0x54, 0x82, + 0x8c, 0x21, 0xbf, 0x7f, 0x69, 0x30, 0x9f, 0x3a, 0xb0, 0x9c, 0x00, 0xf7, 0x33, 0x04, 0xb8, 0xc6, + 0x97, 0x28, 0x07, 0xbc, 0x44, 0x09, 0x6e, 0x7e, 0x82, 0x80, 0x7d, 0x6a, 0x83, 0xbe, 0x01, 0x33, + 0x9d, 0xf8, 0x93, 0x0c, 0xb4, 0x18, 0x31, 0x90, 0xf8, 0x2e, 0x45, 0x5f, 0xca, 0x02, 0x13, 0x0f, + 0xdd, 0x87, 0xe9, 0x1f, 0x46, 0x7d, 0x35, 0xb4, 0xc0, 0x91, 0xe4, 0xbe, 0xa1, 0x7e, 0x4d, 0x05, + 0xb2, 0x75, 0xe7, 0x51, 0xd3, 0x46, 0xac, 0x93, 0xdb, 0x45, 0x62, 0x5d, 0xb2, 0xb7, 0xb3, 0x05, + 0x75, 0x5b, 0xfe, 0x94, 0x02, 0x5d, 0x8f, 0xd4, 0x2f, 0xf5, 0x55, 0x87, 0xde, 0xcc, 0x9e, 0x20, + 0x1e, 0x7a, 0x17, 0x66, 0x89, 0xf4, 0x8d, 0x01, 0x8a, 0x78, 0x4b, 0x7d, 0x17, 0xa1, 0x5f, 0xcf, + 0x84, 0x13, 0x0f, 0xfd, 0x00, 0xae, 0xdb, 0xd9, 0x0d, 0x7e, 0xf4, 0x5a, 0xea, 0x54, 0xb5, 0xc1, + 0xae, 0x1b, 0xa3, 0x50, 0x88, 0x87, 0x4e, 0xe1, 0x86, 0x9d, 0xd7, 0x2d, 0x47, 0xaf, 0xc7, 0x1b, + 0xe4, 0xb6, 0xf1, 0xf5, 0x3b, 0xa3, 0x91, 0x88, 0x87, 0x8e, 0x01, 0x05, 0x4a, 0xcb, 0x18, 0x2d, + 0xf3, 0xb5, 0x99, 0xed, 0x70, 0xfd, 0x56, 0xc1, 0x2c, 0xf1, 0x50, 0x07, 0x9a, 0x76, 0x4e, 0x27, + 0x11, 0x19, 0x89, 0xaf, 0x98, 0x32, 0xbb, 0xa8, 0xfa, 0xeb, 0x23, 0x71, 0x18, 0xdd, 0xb6, 0xd2, + 0x0a, 0x13, 0x74, 0x67, 0x76, 0xf2, 0x04, 0xdd, 0x39, 0x3d, 0xb4, 0xa7, 0xb0, 0x60, 0xab, 0x1d, + 0x20, 0x94, 0xbd, 0x4a, 0x68, 0xd9, 0x4a, 0xd1, 0x34, 0x35, 0xf8, 0xc6, 0x59, 0xb2, 0xa5, 0x81, + 0xa2, 0x4f, 0xb9, 0xd4, 0xce, 0x8e, 0xae, 0xe7, 0x4d, 0x09, 0x96, 0x53, 0x3d, 0x02, 0x99, 0x65, + 0xb5, 0x6d, 0x21, 0xb3, 0x9c, 0xd5, 0x5c, 0x38, 0x84, 0xf9, 0x5e, 0xba, 0xf6, 0x8b, 0x6e, 0x46, + 0x95, 0xee, 0x8c, 0x3e, 0x80, 0xbe, 0x9c, 0x3f, 0xc9, 0x48, 0x54, 0xf6, 0x23, 0x28, 0x77, 0x0d, + 0x91, 0x49, 0xcc, 0x29, 0x42, 0x1f, 0xc2, 0xbc, 0x9d, 0x2e, 0xd9, 0x0a, 0x12, 0xb3, 0x6a, 0xcd, + 0xfa, 0x72, 0xfe, 0x24, 0xf3, 0x3b, 0xc2, 0x21, 0x08, 0xbf, 0x23, 0xd7, 0x36, 0x85, 0xdf, 0x49, + 0xd6, 0x0f, 0x8f, 0x01, 0xa9, 0x05, 0xa7, 0x1c, 0x85, 0xe3, 0x35, 0xb4, 0x1c, 0x85, 0x13, 0x95, + 0xaa, 0x77, 0x61, 0x56, 0x2e, 0xb1, 0x08, 0x37, 0x94, 0x2a, 0xf1, 0x08, 0x37, 0xa4, 0xd4, 0x63, + 0xf6, 0xa1, 0x91, 0x4a, 0xea, 0x85, 0x6e, 0xa9, 0x85, 0x07, 0xa1, 0x5b, 0x59, 0x75, 0x80, 0xf7, + 0x61, 0x31, 0xb3, 0x48, 0x80, 0x6e, 0x47, 0x6e, 0x3f, 0xa7, 0x9c, 0xa1, 0xaf, 0x16, 0x23, 0x30, + 0x89, 0x0b, 0xb0, 0x90, 0xb8, 0x9c, 0x90, 0x0b, 0x89, 0x27, 0xf3, 0xe6, 0x7d, 0x68, 0xa4, 0x36, + 0x15, 0xdc, 0xa9, 0x49, 0xbd, 0xe0, 0x2e, 0x2b, 0x03, 0xff, 0x7e, 0x3a, 0xc0, 0x8d, 0x92, 0x54, + 0xb4, 0x9a, 0xf2, 0xf0, 0x4a, 0xb2, 0xad, 0xbf, 0x36, 0x02, 0x83, 0xbd, 0x06, 0x39, 0xd9, 0xa3, + 0xfc, 0x1a, 0xe4, 0xa4, 0xb4, 0xf2, 0x6b, 0x90, 0x9b, 0x80, 0x32, 0xe5, 0x4b, 0xe5, 0x65, 0xb2, + 0xf2, 0xa9, 0xc9, 0xa2, 0xac, 0x7c, 0x59, 0x09, 0xdd, 0x31, 0x20, 0x35, 0xe8, 0x17, 0x5b, 0x66, + 0xe6, 0x5c, 0x62, 0xcb, 0x9c, 0x6c, 0xe1, 0x7b, 0x52, 0xf3, 0x47, 0x0a, 0xc3, 0x51, 0xda, 0x45, + 0xa6, 0xf2, 0x02, 0xfd, 0x76, 0xe1, 0x3c, 0x33, 0x14, 0x39, 0xb8, 0x14, 0x86, 0x92, 0x8a, 0xa2, + 0x85, 0xa1, 0x28, 0x91, 0xee, 0x16, 0xd4, 0x13, 0xc1, 0x95, 0x08, 0x1a, 0xd2, 0x41, 0xa4, 0x08, + 0x1a, 0x94, 0x58, 0x6c, 0xeb, 0xf6, 0xfb, 0xb7, 0x8e, 0x3c, 0xec, 0x3c, 0x6b, 0x1d, 0x48, 0x9f, + 0x18, 0x53, 0xe4, 0x77, 0xe8, 0xef, 0xc9, 0x15, 0x0a, 0x7a, 0xf3, 0xd3, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x7a, 0x7b, 0x02, 0xb3, 0xd5, 0x2c, 0x00, 0x00, } diff --git a/pkg/proto/group/group.proto b/pkg/proto/group/group.proto index b05b840e6..8968b7e8e 100644 --- a/pkg/proto/group/group.proto +++ b/pkg/proto/group/group.proto @@ -200,6 +200,17 @@ message InviteUserToGroupResp { repeated Id2Result Id2ResultList = 3; // 0 ok, -1 error } +message InviteUserToGroupsReq { + string OperationID = 1; + repeated string groupIDList = 2; + string Reason = 3; + string invitedUserID = 4; + string OpUserID = 5; //group member or app manager +} +message InviteUserToGroupsResp { + int32 ErrCode = 1; + string ErrMsg = 2; +} message GetGroupAllMemberReq { string GroupID = 1; @@ -413,6 +424,7 @@ service group{ rpc kickGroupMember(KickGroupMemberReq) returns (KickGroupMemberResp); rpc getJoinedGroupList(GetJoinedGroupListReq) returns (GetJoinedGroupListResp); rpc inviteUserToGroup(InviteUserToGroupReq) returns (InviteUserToGroupResp); + rpc inviteUserToGroups(InviteUserToGroupsReq) returns (InviteUserToGroupsResp); rpc getGroupAllMember(GetGroupAllMemberReq) returns(GetGroupAllMemberResp); rpc GetGroups(GetGroupsReq) returns(GetGroupsResp); From c6ea841064f93a5c2a9bf632462d640ae0faa1be Mon Sep 17 00:00:00 2001 From: wangchuxiao Date: Wed, 1 Mar 2023 00:38:36 +0800 Subject: [PATCH 2/8] k8s --- deploy_k8s/admin_cms/deployment.yaml | 17 ++++++++--------- deploy_k8s/api/deployment.yaml | 16 +++++++--------- deploy_k8s/auth/deployment.yaml | 16 +++++++--------- deploy_k8s/build_push_all_images.sh | 2 +- deploy_k8s/cache/deployment.yaml | 16 +++++++--------- deploy_k8s/cms_api/deployment.yaml | 16 +++++++--------- deploy_k8s/conversation/deployment.yaml | 16 +++++++--------- deploy_k8s/demo/deployment.yaml | 16 +++++++--------- deploy_k8s/friend/deployment.yaml | 16 +++++++--------- deploy_k8s/group/deployment.yaml | 16 +++++++--------- deploy_k8s/k8s_openim_deploy.md | 9 ++++----- deploy_k8s/msg/deployment.yaml | 16 +++++++--------- deploy_k8s/msg_gateway/deployment.yaml | 16 +++++++--------- deploy_k8s/msg_transfer/deployment.yaml | 16 +++++++--------- deploy_k8s/office/deployment.yaml | 16 +++++++--------- deploy_k8s/organization/deployment.yaml | 16 +++++++--------- deploy_k8s/push/deployment.yaml | 16 +++++++--------- deploy_k8s/sdk_server/deployment.yaml | 2 +- deploy_k8s/user/deployment.yaml | 16 +++++++--------- pkg/common/constant/constant.go | 2 +- 20 files changed, 120 insertions(+), 152 deletions(-) diff --git a/deploy_k8s/admin_cms/deployment.yaml b/deploy_k8s/admin_cms/deployment.yaml index cfee86a69..07402457d 100644 --- a/deploy_k8s/admin_cms/deployment.yaml +++ b/deploy_k8s/admin_cms/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: admin-cms - image: openim/admin_cms:v2.3.4 + image: openim/admin_cms:v2.3.8 # imagePullPolicy: Always #每次启动都重新拉取镜像 ports: - containerPort: 10200 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,11 +30,13 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig + strategy: #更新策略 type: RollingUpdate # 滚动更新 diff --git a/deploy_k8s/api/deployment.yaml b/deploy_k8s/api/deployment.yaml index e2c1a451b..0d8f4c03d 100644 --- a/deploy_k8s/api/deployment.yaml +++ b/deploy_k8s/api/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: api - image: openim/api:v2.3.4 + image: openim/api:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10002 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,11 +30,12 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: openim-config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 --- diff --git a/deploy_k8s/auth/deployment.yaml b/deploy_k8s/auth/deployment.yaml index 733c52306..fb3fe4659 100644 --- a/deploy_k8s/auth/deployment.yaml +++ b/deploy_k8s/auth/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: auth - image: openim/auth:v2.3.4 + image: openim/auth:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10160 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,10 +30,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 \ No newline at end of file diff --git a/deploy_k8s/build_push_all_images.sh b/deploy_k8s/build_push_all_images.sh index f2a6b1b49..33ce6e94a 100644 --- a/deploy_k8s/build_push_all_images.sh +++ b/deploy_k8s/build_push_all_images.sh @@ -2,7 +2,7 @@ source ./path_info.cfg # images version -version=v2.3.4 +version=v2.3.8 git pull cd ../script/; ./build_all_service.sh cd ../deploy_k8s/ diff --git a/deploy_k8s/cache/deployment.yaml b/deploy_k8s/cache/deployment.yaml index c17749e10..df30f8809 100644 --- a/deploy_k8s/cache/deployment.yaml +++ b/deploy_k8s/cache/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: cache - image: openim/cache:v2.3.4 + image: openim/cache:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10240 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,10 +30,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: openim-config - - name: usualconfig - configMap: - name: openim-usualConfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 \ No newline at end of file diff --git a/deploy_k8s/cms_api/deployment.yaml b/deploy_k8s/cms_api/deployment.yaml index 2af5d3377..ab014a7a2 100644 --- a/deploy_k8s/cms_api/deployment.yaml +++ b/deploy_k8s/cms_api/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: cms-api - image: openim/cms_api:v2.3.4 + image: openim/cms_api:v2.3.8 imagePullPolicy: Always ports: - containerPort: 10006 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,11 +30,12 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 --- diff --git a/deploy_k8s/conversation/deployment.yaml b/deploy_k8s/conversation/deployment.yaml index 993761195..733617f00 100644 --- a/deploy_k8s/conversation/deployment.yaml +++ b/deploy_k8s/conversation/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: conversation - image: openim/conversation:v2.3.4 + image: openim/conversation:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10230 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -34,11 +31,12 @@ spec: volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 diff --git a/deploy_k8s/demo/deployment.yaml b/deploy_k8s/demo/deployment.yaml index a7f5550a1..11a55b0db 100644 --- a/deploy_k8s/demo/deployment.yaml +++ b/deploy_k8s/demo/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: demo - image: openim/demo:v2.3.4 + image: openim/demo:v2.3.8 imagePullPolicy: Always ports: - containerPort: 10004 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,11 +30,12 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 --- diff --git a/deploy_k8s/friend/deployment.yaml b/deploy_k8s/friend/deployment.yaml index dde9cbd4c..9c435f446 100644 --- a/deploy_k8s/friend/deployment.yaml +++ b/deploy_k8s/friend/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: friend - image: openim/friend:v2.3.4 + image: openim/friend:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10120 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,11 +30,12 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 diff --git a/deploy_k8s/group/deployment.yaml b/deploy_k8s/group/deployment.yaml index 96c3fe848..060b8f347 100644 --- a/deploy_k8s/group/deployment.yaml +++ b/deploy_k8s/group/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: group - image: openim/group:v2.3.4 + image: openim/group:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10150 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,10 +30,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 \ No newline at end of file diff --git a/deploy_k8s/k8s_openim_deploy.md b/deploy_k8s/k8s_openim_deploy.md index 4dad2c077..3faf58703 100644 --- a/deploy_k8s/k8s_openim_deploy.md +++ b/deploy_k8s/k8s_openim_deploy.md @@ -9,18 +9,17 @@ 6. 将rpcRegisterIP修改为空, 此地址为每个rpc注册到ETCD的地址, 置空每个rpc将会将pod地址注册到ETCD, 才能正确rpc请求(重要) 7. 如果使用minio作为对象存储, 还需要修改minio的地址 8. 其他如果使用离线推送,需要修改push离线推送配置 -9. 修改demo中的imAPIURL字段为openIM api的ingress或者service地址, 需要让demo的pod能正确请求到(重要) -10. 其他非必须配置修改, 如短信,推送等 + ### 2. 项目根目录创建im configMap到k8s openim namespace 1. 为open-IM项目创建单独命名空间 ``` kubectl create namespace openim ``` -2. 在项目根目录通过config/config.yaml +2. 修改config.yaml后在项目根目录创建configmap, config/usualConfig.yaml只需要挂载不需要修改配置 ``` - kubectl -n openim create configmap config --from-file=config/config.yaml - kubectl -n openim create configmap usualconfig --from-file=config/usualConfig.yaml + kubectl -n openim create configmap openim-config --from-file=config/config.yaml + kubectl -n openim create configmap openim-usualconfig --from-file=config/usualConfig.yaml ``` 查看configmap ``` diff --git a/deploy_k8s/msg/deployment.yaml b/deploy_k8s/msg/deployment.yaml index 5538203f6..5e5fe4157 100644 --- a/deploy_k8s/msg/deployment.yaml +++ b/deploy_k8s/msg/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: msg - image: openim/msg:v2.3.4 + image: openim/msg:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10130 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,10 +30,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualConfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 \ No newline at end of file diff --git a/deploy_k8s/msg_gateway/deployment.yaml b/deploy_k8s/msg_gateway/deployment.yaml index 18ad66ca3..068a405cf 100644 --- a/deploy_k8s/msg_gateway/deployment.yaml +++ b/deploy_k8s/msg_gateway/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: msg-gateway - image: openim/msg_gateway:v2.3.4 + image: openim/msg_gateway:v2.3.8 # imagePullPolicy: Always ports: - name: rpc-port @@ -26,9 +26,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -36,11 +33,12 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 --- diff --git a/deploy_k8s/msg_transfer/deployment.yaml b/deploy_k8s/msg_transfer/deployment.yaml index f47583b05..47d04b9d7 100644 --- a/deploy_k8s/msg_transfer/deployment.yaml +++ b/deploy_k8s/msg_transfer/deployment.yaml @@ -15,15 +15,12 @@ spec: spec: containers: - name: msg-transfer - image: openim/msg_transfer:v2.3.4 + image: openim/msg_transfer:v2.3.8 # imagePullPolicy: Always volumeMounts: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -31,10 +28,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 diff --git a/deploy_k8s/office/deployment.yaml b/deploy_k8s/office/deployment.yaml index 4e819971b..759643fe3 100644 --- a/deploy_k8s/office/deployment.yaml +++ b/deploy_k8s/office/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: office - image: openim/office:v2.3.4 + image: openim/office:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10210 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,10 +30,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 \ No newline at end of file diff --git a/deploy_k8s/organization/deployment.yaml b/deploy_k8s/organization/deployment.yaml index 0b60fb4c2..380628b36 100644 --- a/deploy_k8s/organization/deployment.yaml +++ b/deploy_k8s/organization/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: organization - image: openim/organization:v2.3.4 + image: openim/organization:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10220 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,10 +30,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 \ No newline at end of file diff --git a/deploy_k8s/push/deployment.yaml b/deploy_k8s/push/deployment.yaml index 1382e5a12..f6ec07500 100644 --- a/deploy_k8s/push/deployment.yaml +++ b/deploy_k8s/push/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: push - image: openim/push:v2.3.4 + image: openim/push:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10170 @@ -23,9 +23,6 @@ spec: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualConfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -33,10 +30,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 \ No newline at end of file diff --git a/deploy_k8s/sdk_server/deployment.yaml b/deploy_k8s/sdk_server/deployment.yaml index bee3dc4bf..6022c2077 100644 --- a/deploy_k8s/sdk_server/deployment.yaml +++ b/deploy_k8s/sdk_server/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: sdk-server - image: openim/sdk_server:v2.3.4 + image: openim/sdk_server:v2.3.8 # imagePullPolicy: Always ports: - containerPort: 10003 diff --git a/deploy_k8s/user/deployment.yaml b/deploy_k8s/user/deployment.yaml index c0c2d53bf..5ad75a922 100644 --- a/deploy_k8s/user/deployment.yaml +++ b/deploy_k8s/user/deployment.yaml @@ -15,15 +15,12 @@ spec: spec: containers: - name: user - image: openim/user:v2.3.4 + image: openim/user:v2.3.8 # imagePullPolicy: Always volumeMounts: - name: config mountPath: /Open-IM-Server/config readOnly: true - - name: usualconfig - mountPath: /Open-IM-Server/config - readOnly: true env: - name: CONFIG_NAME value: "/Open-IM-Server" @@ -31,10 +28,11 @@ spec: value: "/Open-IM-Server" volumes: - name: config - configMap: - name: config - - name: usualconfig - configMap: - name: usualconfig + projected: + sources: + - configMap: + name: openim-config + - configMap: + name: openim-usualconfig strategy: #更新策略 type: RollingUpdate # 滚动更新 diff --git a/pkg/common/constant/constant.go b/pkg/common/constant/constant.go index 9a24b694e..9bcef92bf 100644 --- a/pkg/common/constant/constant.go +++ b/pkg/common/constant/constant.go @@ -361,4 +361,4 @@ const StatisticsTimeInterval = 60 const MaxNotificationNum = 500 -const CurrentVersion = "v2.3.4-rc0" +const CurrentVersion = "v2.3.8-rc0" From 9dc798bc534559276a203c7b703387277863e14c Mon Sep 17 00:00:00 2001 From: Gordon <1432970085@qq.com> Date: Wed, 1 Mar 2023 14:54:22 +0800 Subject: [PATCH 3/8] ws recycle conn bug fix --- internal/msg_gateway/gate/ws_server.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/msg_gateway/gate/ws_server.go b/internal/msg_gateway/gate/ws_server.go index 81ce37d76..9025b287b 100644 --- a/internal/msg_gateway/gate/ws_server.go +++ b/internal/msg_gateway/gate/ws_server.go @@ -377,8 +377,12 @@ func (ws *WServer) delUserConn(conn *UserConn) { platform = k uid = v } - if oldConnMap, ok := ws.wsUserToConn[uid]; ok { - delete(oldConnMap, platform) + if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // only recycle self conn + if oldconn, okMap := oldConnMap[platform]; okMap { + if oldconn == conn { + delete(oldConnMap, platform) + } + } ws.wsUserToConn[uid] = oldConnMap if len(oldConnMap) == 0 { delete(ws.wsUserToConn, uid) From 7e48d1a00f3f7a7cc7b2d911db3b8d222d3c75a9 Mon Sep 17 00:00:00 2001 From: Gordon <1432970085@qq.com> Date: Thu, 2 Mar 2023 18:47:11 +0800 Subject: [PATCH 4/8] ws support same terminal login --- internal/msg_gateway/gate/relay_rpc_server.go | 306 +++++++++--------- internal/msg_gateway/gate/ws_server.go | 131 ++++---- 2 files changed, 226 insertions(+), 211 deletions(-) diff --git a/internal/msg_gateway/gate/relay_rpc_server.go b/internal/msg_gateway/gate/relay_rpc_server.go index 89a63a293..8e7589ab8 100644 --- a/internal/msg_gateway/gate/relay_rpc_server.go +++ b/internal/msg_gateway/gate/relay_rpc_server.go @@ -101,47 +101,48 @@ func (r *RPCServer) run() { } } func (r *RPCServer) OnlinePushMsg(_ context.Context, in *pbRelay.OnlinePushMsgReq) (*pbRelay.OnlinePushMsgResp, error) { - log.NewInfo(in.OperationID, "PushMsgToUser is arriving", in.String()) - var resp []*pbRelay.SingleMsgToUserPlatform - msgBytes, _ := proto.Marshal(in.MsgData) - mReply := Resp{ - ReqIdentifier: constant.WSPushMsg, - OperationID: in.OperationID, - Data: msgBytes, - } - var replyBytes bytes.Buffer - enc := gob.NewEncoder(&replyBytes) - err := enc.Encode(mReply) - if err != nil { - log.NewError(in.OperationID, "data encode err", err.Error()) - } - var tag bool - recvID := in.PushToUserID - for _, v := range r.platformList { - if conn := ws.getUserConn(recvID, v); conn != nil { - tag = true - resultCode := sendMsgToUser(conn, replyBytes.Bytes(), in, v, recvID) - temp := &pbRelay.SingleMsgToUserPlatform{ - ResultCode: resultCode, - RecvID: recvID, - RecvPlatFormID: int32(v), - } - resp = append(resp, temp) - } else { - temp := &pbRelay.SingleMsgToUserPlatform{ - ResultCode: -1, - RecvID: recvID, - RecvPlatFormID: int32(v), - } - resp = append(resp, temp) - } - } - if !tag { - log.NewDebug(in.OperationID, "push err ,no matched ws conn not in map", in.String()) - } - return &pbRelay.OnlinePushMsgResp{ - Resp: resp, - }, nil + //log.NewInfo(in.OperationID, "PushMsgToUser is arriving", in.String()) + //var resp []*pbRelay.SingleMsgToUserPlatform + //msgBytes, _ := proto.Marshal(in.MsgData) + //mReply := Resp{ + // ReqIdentifier: constant.WSPushMsg, + // OperationID: in.OperationID, + // Data: msgBytes, + //} + //var replyBytes bytes.Buffer + //enc := gob.NewEncoder(&replyBytes) + //err := enc.Encode(mReply) + //if err != nil { + // log.NewError(in.OperationID, "data encode err", err.Error()) + //} + //var tag bool + //recvID := in.PushToUserID + //for _, v := range r.platformList { + // if conn := ws.getUserConn(recvID, v); conn != nil { + // tag = true + // resultCode := sendMsgToUser(conn, replyBytes.Bytes(), in, v, recvID) + // temp := &pbRelay.SingleMsgToUserPlatform{ + // ResultCode: resultCode, + // RecvID: recvID, + // RecvPlatFormID: int32(v), + // } + // resp = append(resp, temp) + // } else { + // temp := &pbRelay.SingleMsgToUserPlatform{ + // ResultCode: -1, + // RecvID: recvID, + // RecvPlatFormID: int32(v), + // } + // resp = append(resp, temp) + // } + //} + //if !tag { + // log.NewDebug(in.OperationID, "push err ,no matched ws conn not in map", in.String()) + //} + //return &pbRelay.OnlinePushMsgResp{ + // Resp: resp, + //}, nil + return nil, nil } func (r *RPCServer) GetUsersOnlineStatus(_ context.Context, req *pbRelay.GetUsersOnlineStatusReq) (*pbRelay.GetUsersOnlineStatusResp, error) { log.NewInfo(req.OperationID, "rpc GetUsersOnlineStatus arrived server", req.String()) @@ -154,13 +155,13 @@ func (r *RPCServer) GetUsersOnlineStatus(_ context.Context, req *pbRelay.GetUser temp := new(pbRelay.GetUsersOnlineStatusResp_SuccessResult) temp.UserID = userID userConnMap := ws.getUserAllCons(userID) - for platform, userConn := range userConnMap { - if userConn != nil { + for platform, userConns := range userConnMap { + if len(userConns) != 0 { ps := new(pbRelay.GetUsersOnlineStatusResp_SuccessDetail) ps.Platform = constant.PlatformIDToName(platform) ps.Status = constant.OnlineStatus - ps.ConnID = userConn.connID - ps.IsBackground = userConn.IsBackground + ps.ConnID = userConns[0].connID + ps.IsBackground = userConns[0].IsBackground temp.Status = constant.OnlineStatus temp.DetailPlatformStatus = append(temp.DetailPlatformStatus, ps) } @@ -196,25 +197,28 @@ func (r *RPCServer) SuperGroupOnlineBatchPushOneMsg(_ context.Context, req *pbRe UserID: v, } userConnMap := ws.getUserAllCons(v) - for platform, userConn := range userConnMap { - if userConn != nil { - temp := &pbRelay.SingleMsgToUserPlatform{ - RecvID: v, - RecvPlatFormID: int32(platform), - } - if !userConn.IsBackground { - resultCode := sendMsgBatchToUser(userConn, replyBytes.Bytes(), req, platform, v) - if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) { - tempT.OnlinePush = true - promePkg.PromeInc(promePkg.MsgOnlinePushSuccessCounter) - log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recvPlatForm", constant.PlatformIDToName(platform), "recvID", v) - temp.ResultCode = resultCode + for platform, userConns := range userConnMap { + if len(userConns) != 0 { + for _, userConn := range userConns { + temp := &pbRelay.SingleMsgToUserPlatform{ + RecvID: v, + RecvPlatFormID: int32(platform), + } + if !userConn.IsBackground { + resultCode := sendMsgBatchToUser(userConn, replyBytes.Bytes(), req, platform, v) + if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) { + tempT.OnlinePush = true + promePkg.PromeInc(promePkg.MsgOnlinePushSuccessCounter) + log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recvPlatForm", constant.PlatformIDToName(platform), "recvID", v) + temp.ResultCode = resultCode + resp = append(resp, temp) + } + } else { + temp.ResultCode = -2 resp = append(resp, temp) } - } else { - temp.ResultCode = -2 - resp = append(resp, temp) } + } } tempT.Resp = resp @@ -247,22 +251,28 @@ func (r *RPCServer) SuperGroupBackgroundOnlinePush(_ context.Context, req *pbRel UserID: v, } userConnMap := ws.getUserAllCons(v) - for platform, userConn := range userConnMap { - if userConn != nil && userConn.IsBackground { - temp := &pbRelay.SingleMsgToUserPlatform{ - RecvID: v, - RecvPlatFormID: int32(platform), - } - if constant.PlatformIDToClass(int(userConn.PlatformID)) == constant.TerminalPC || userConn.PlatformID == constant.WebPlatformID { - resultCode := sendMsgBatchToUser(userConn, replyBytes.Bytes(), req, platform, v) - if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) { - tempT.OnlinePush = true - promePkg.PromeInc(promePkg.MsgOnlinePushSuccessCounter) - log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recvPlatForm", constant.PlatformIDToName(platform), "recvID", v) - temp.ResultCode = resultCode + for platform, userConns := range userConnMap { + if len(userConns) != 0 { + for _, userConn := range userConns { + temp := &pbRelay.SingleMsgToUserPlatform{ + RecvID: v, + RecvPlatFormID: int32(platform), + } + if !userConn.IsBackground { + resultCode := sendMsgBatchToUser(userConn, replyBytes.Bytes(), req, platform, v) + if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) { + tempT.OnlinePush = true + promePkg.PromeInc(promePkg.MsgOnlinePushSuccessCounter) + log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recvPlatForm", constant.PlatformIDToName(platform), "recvID", v) + temp.ResultCode = resultCode + resp = append(resp, temp) + } + } else { + temp.ResultCode = -2 resp = append(resp, temp) } } + } } tempT.Resp = resp @@ -274,76 +284,77 @@ func (r *RPCServer) SuperGroupBackgroundOnlinePush(_ context.Context, req *pbRel }, nil } func (r *RPCServer) OnlineBatchPushOneMsg(_ context.Context, req *pbRelay.OnlineBatchPushOneMsgReq) (*pbRelay.OnlineBatchPushOneMsgResp, error) { - log.NewInfo(req.OperationID, "BatchPushMsgToUser is arriving", req.String()) - var singleUserResult []*pbRelay.SingelMsgToUserResultList - - for _, v := range req.PushToUserIDList { - var resp []*pbRelay.SingleMsgToUserPlatform - tempT := &pbRelay.SingelMsgToUserResultList{ - UserID: v, - } - userConnMap := ws.getUserAllCons(v) - var platformList []int - for k, _ := range userConnMap { - platformList = append(platformList, k) - } - log.Debug(req.OperationID, "GetSingleUserMsgForPushPlatforms begin", req.MsgData.Seq, v, platformList, req.MsgData.String()) - needPushMapList := r.GetSingleUserMsgForPushPlatforms(req.OperationID, req.MsgData, v, platformList) - log.Debug(req.OperationID, "GetSingleUserMsgForPushPlatforms end", req.MsgData.Seq, v, platformList, len(needPushMapList)) - for platform, list := range needPushMapList { - if list != nil { - log.Debug(req.OperationID, "needPushMapList ", "userID: ", v, "platform: ", platform, "push msg num:") - //for _, v := range list { - // log.Debug(req.OperationID, "req.MsgData.MsgDataList begin", "len: ", len(req.MsgData.MsgDataList), v.String()) - // req.MsgData.MsgDataList = append(req.MsgData.MsgDataList, v) - // log.Debug(req.OperationID, "req.MsgData.MsgDataList end", "len: ", len(req.MsgData.MsgDataList)) - //} - msgBytes, err := proto.Marshal(list) - if err != nil { - log.Error(req.OperationID, "proto marshal err", err.Error()) - continue - } - req.MsgData.MsgDataList = msgBytes - //req.MsgData.MsgDataList = append(req.MsgData.MsgDataList, v) - log.Debug(req.OperationID, "r.encodeWsData no string") - //log.Debug(req.OperationID, "r.encodeWsData data0 list ", req.MsgData.MsgDataList[0].String()) - - log.Debug(req.OperationID, "r.encodeWsData ", req.MsgData.String()) - replyBytes, err := r.encodeWsData(req.MsgData, req.OperationID) - if err != nil { - log.Error(req.OperationID, "encodeWsData failed ", req.MsgData.String()) - continue - } - log.Debug(req.OperationID, "encodeWsData", "len: ", replyBytes.Len()) - resultCode := sendMsgBatchToUser(userConnMap[platform], replyBytes.Bytes(), req, platform, v) - if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) { - tempT.OnlinePush = true - log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recv PlatForm", constant.PlatformIDToName(platform), "recvID", v) - temp := &pbRelay.SingleMsgToUserPlatform{ - ResultCode: resultCode, - RecvID: v, - RecvPlatFormID: int32(platform), - } - resp = append(resp, temp) - } - } else { - if utils.IsContainInt(platform, r.pushTerminal) { - tempT.OnlinePush = true - temp := &pbRelay.SingleMsgToUserPlatform{ - ResultCode: 0, - RecvID: v, - RecvPlatFormID: int32(platform), - } - resp = append(resp, temp) - } - } - } - tempT.Resp = resp - singleUserResult = append(singleUserResult, tempT) - } - return &pbRelay.OnlineBatchPushOneMsgResp{ - SinglePushResult: singleUserResult, - }, nil + //log.NewInfo(req.OperationID, "BatchPushMsgToUser is arriving", req.String()) + //var singleUserResult []*pbRelay.SingelMsgToUserResultList + // + //for _, v := range req.PushToUserIDList { + // var resp []*pbRelay.SingleMsgToUserPlatform + // tempT := &pbRelay.SingelMsgToUserResultList{ + // UserID: v, + // } + // userConnMap := ws.getUserAllCons(v) + // var platformList []int + // for k, _ := range userConnMap { + // platformList = append(platformList, k) + // } + // log.Debug(req.OperationID, "GetSingleUserMsgForPushPlatforms begin", req.MsgData.Seq, v, platformList, req.MsgData.String()) + // needPushMapList := r.GetSingleUserMsgForPushPlatforms(req.OperationID, req.MsgData, v, platformList) + // log.Debug(req.OperationID, "GetSingleUserMsgForPushPlatforms end", req.MsgData.Seq, v, platformList, len(needPushMapList)) + // for platform, list := range needPushMapList { + // if list != nil { + // log.Debug(req.OperationID, "needPushMapList ", "userID: ", v, "platform: ", platform, "push msg num:") + // //for _, v := range list { + // // log.Debug(req.OperationID, "req.MsgData.MsgDataList begin", "len: ", len(req.MsgData.MsgDataList), v.String()) + // // req.MsgData.MsgDataList = append(req.MsgData.MsgDataList, v) + // // log.Debug(req.OperationID, "req.MsgData.MsgDataList end", "len: ", len(req.MsgData.MsgDataList)) + // //} + // msgBytes, err := proto.Marshal(list) + // if err != nil { + // log.Error(req.OperationID, "proto marshal err", err.Error()) + // continue + // } + // req.MsgData.MsgDataList = msgBytes + // //req.MsgData.MsgDataList = append(req.MsgData.MsgDataList, v) + // log.Debug(req.OperationID, "r.encodeWsData no string") + // //log.Debug(req.OperationID, "r.encodeWsData data0 list ", req.MsgData.MsgDataList[0].String()) + // + // log.Debug(req.OperationID, "r.encodeWsData ", req.MsgData.String()) + // replyBytes, err := r.encodeWsData(req.MsgData, req.OperationID) + // if err != nil { + // log.Error(req.OperationID, "encodeWsData failed ", req.MsgData.String()) + // continue + // } + // log.Debug(req.OperationID, "encodeWsData", "len: ", replyBytes.Len()) + // resultCode := sendMsgBatchToUser(userConnMap[platform], replyBytes.Bytes(), req, platform, v) + // if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) { + // tempT.OnlinePush = true + // log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recv PlatForm", constant.PlatformIDToName(platform), "recvID", v) + // temp := &pbRelay.SingleMsgToUserPlatform{ + // ResultCode: resultCode, + // RecvID: v, + // RecvPlatFormID: int32(platform), + // } + // resp = append(resp, temp) + // } + // } else { + // if utils.IsContainInt(platform, r.pushTerminal) { + // tempT.OnlinePush = true + // temp := &pbRelay.SingleMsgToUserPlatform{ + // ResultCode: 0, + // RecvID: v, + // RecvPlatFormID: int32(platform), + // } + // resp = append(resp, temp) + // } + // } + // } + // tempT.Resp = resp + // singleUserResult = append(singleUserResult, tempT) + //} + //return &pbRelay.OnlineBatchPushOneMsgResp{ + // SinglePushResult: singleUserResult, + //}, nil + return nil, nil } func (r *RPCServer) encodeWsData(wsData *sdk_ws.MsgData, operationID string) (bytes.Buffer, error) { log.Debug(operationID, "encodeWsData begin", wsData.String()) @@ -374,10 +385,11 @@ func (r *RPCServer) KickUserOffline(_ context.Context, req *pbRelay.KickUserOffl log.NewWarn(req.OperationID, "SetTokenKicked ", v, req.PlatformID, req.OperationID) SetTokenKicked(v, int(req.PlatformID), req.OperationID) oldConnMap := ws.getUserAllCons(v) - if conn, ok := oldConnMap[int(req.PlatformID)]; ok { // user->map[platform->conn] + if conns, ok := oldConnMap[int(req.PlatformID)]; ok { // user->map[platform->conn] log.NewWarn(req.OperationID, "send kick msg, close connection ", req.PlatformID, v) - ws.sendKickMsg(conn, req.OperationID) - conn.Close() + for _, conn := range conns { + ws.sendKickMsg(conn, req.OperationID) + } } } return &pbRelay.KickUserOfflineResp{}, nil diff --git a/internal/msg_gateway/gate/ws_server.go b/internal/msg_gateway/gate/ws_server.go index 9025b287b..7ffe7b94b 100644 --- a/internal/msg_gateway/gate/ws_server.go +++ b/internal/msg_gateway/gate/ws_server.go @@ -45,15 +45,13 @@ type WServer struct { wsAddr string wsMaxConnNum int wsUpGrader *websocket.Upgrader - wsConnToUser map[*UserConn]map[int]string - wsUserToConn map[string]map[int]*UserConn + wsUserToConn map[string]map[int][]*UserConn } func (ws *WServer) onInit(wsPort int) { ws.wsAddr = ":" + utils.IntToString(wsPort) ws.wsMaxConnNum = config.Config.LongConnSvr.WebsocketMaxConnNum - ws.wsConnToUser = make(map[*UserConn]map[int]string) - ws.wsUserToConn = make(map[string]map[int]*UserConn) + ws.wsUserToConn = make(map[string]map[int][]*UserConn) ws.wsUpGrader = &websocket.Upgrader{ HandshakeTimeout: time.Duration(config.Config.LongConnSvr.WebsocketTimeOut) * time.Second, ReadBufferSize: config.Config.LongConnSvr.WebsocketMaxMsgLen, @@ -203,8 +201,11 @@ func (ws *WServer) MultiTerminalLoginCheckerWithLock(uid string, platformID int, fallthrough case constant.AllLoginButSameTermKick: if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // user->map[platform->conn] - if oldConn, ok := oldConnMap[platformID]; ok { + if oldConns, ok := oldConnMap[platformID]; ok { log.NewDebug(operationID, uid, platformID, "kick old conn") + for _, conn := range oldConns { + ws.sendKickMsg(conn, operationID) + } m, err := db.DB.GetTokenMapByUidPid(uid, constant.PlatformIDToName(platformID)) if err != nil && err != go_redis.Nil { log.NewError(operationID, "get token from redis err", err.Error(), uid, constant.PlatformIDToName(platformID)) @@ -227,16 +228,12 @@ func (ws *WServer) MultiTerminalLoginCheckerWithLock(uid string, platformID int, log.NewError(operationID, "SetTokenMapByUidPid err", err.Error(), uid, platformID, m) return } - err = oldConn.Close() - //delete(oldConnMap, platformID) + + delete(oldConnMap, platformID) ws.wsUserToConn[uid] = oldConnMap if len(oldConnMap) == 0 { delete(ws.wsUserToConn, uid) } - delete(ws.wsConnToUser, oldConn) - if err != nil { - log.NewError(operationID, "conn close err", err.Error(), uid, platformID) - } } else { log.NewWarn(operationID, "abnormal uid-conn ", uid, platformID, oldConnMap[platformID]) } @@ -259,9 +256,11 @@ func (ws *WServer) MultiTerminalLoginChecker(uid string, platformID int, newConn fallthrough case constant.AllLoginButSameTermKick: if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // user->map[platform->conn] - if oldConn, ok := oldConnMap[platformID]; ok { + if oldConns, ok := oldConnMap[platformID]; ok { log.NewDebug(operationID, uid, platformID, "kick old conn") - ws.sendKickMsg(oldConn, operationID) + for _, conn := range oldConns { + ws.sendKickMsg(conn, operationID) + } m, err := db.DB.GetTokenMapByUidPid(uid, constant.PlatformIDToName(platformID)) if err != nil && err != go_redis.Nil { log.NewError(operationID, "get token from redis err", err.Error(), uid, constant.PlatformIDToName(platformID)) @@ -284,16 +283,11 @@ func (ws *WServer) MultiTerminalLoginChecker(uid string, platformID int, newConn log.NewError(operationID, "SetTokenMapByUidPid err", err.Error(), uid, platformID, m) return } - err = oldConn.Close() delete(oldConnMap, platformID) ws.wsUserToConn[uid] = oldConnMap if len(oldConnMap) == 0 { delete(ws.wsUserToConn, uid) } - delete(ws.wsConnToUser, oldConn) - if err != nil { - log.NewError(operationID, "conn close err", err.Error(), uid, platformID) - } callbackResp := callbackUserKickOff(operationID, uid, platformID) if callbackResp.ErrCode != 0 { log.NewError(operationID, utils.GetSelfFuncName(), "callbackUserOffline failed", callbackResp) @@ -328,6 +322,11 @@ func (ws *WServer) sendKickMsg(oldConn *UserConn, operationID string) { if err != nil { log.NewError(mReply.OperationID, mReply.ReqIdentifier, mReply.ErrCode, mReply.ErrMsg, "sendKickMsg WS WriteMsg error", oldConn.RemoteAddr().String(), err.Error()) } + errClose := oldConn.Close() + if errClose != nil { + log.NewError(mReply.OperationID, mReply.ReqIdentifier, mReply.ErrCode, mReply.ErrMsg, "close old conn error", oldConn.RemoteAddr().String(), err.Error()) + + } } func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token string, connID, operationID string) { @@ -341,23 +340,24 @@ func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token go ws.MultiTerminalLoginRemoteChecker(uid, int32(platformID), token, operationID) ws.MultiTerminalLoginChecker(uid, platformID, conn, token, operationID) if oldConnMap, ok := ws.wsUserToConn[uid]; ok { - oldConnMap[platformID] = conn + if conns, ok := oldConnMap[platformID]; ok { + conns = append(conns, conn) + oldConnMap[platformID] = conns + } else { + conns := make([]*UserConn, 2) + conns = append(conns, conn) + oldConnMap[platformID] = conns + } ws.wsUserToConn[uid] = oldConnMap log.Debug(operationID, "user not first come in, add conn ", uid, platformID, conn, oldConnMap) } else { - i := make(map[int]*UserConn) - i[platformID] = conn + i := make(map[int][]*UserConn) + conns := make([]*UserConn, 2) + conns = append(conns, conn) + i[platformID] = conns ws.wsUserToConn[uid] = i log.Debug(operationID, "user first come in, new user, conn", uid, platformID, conn, ws.wsUserToConn[uid]) } - if oldStringMap, ok := ws.wsConnToUser[conn]; ok { - oldStringMap[platformID] = uid - ws.wsConnToUser[conn] = oldStringMap - } else { - i := make(map[int]string) - i[platformID] = uid - ws.wsConnToUser[conn] = i - } count := 0 for _, v := range ws.wsUserToConn { count = count + len(v) @@ -370,36 +370,39 @@ func (ws *WServer) delUserConn(conn *UserConn) { rwLock.Lock() defer rwLock.Unlock() operationID := utils.OperationIDGenerator() - var uid string - var platform int - if oldStringMap, okg := ws.wsConnToUser[conn]; okg { - for k, v := range oldStringMap { - platform = k - uid = v - } - if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // only recycle self conn - if oldconn, okMap := oldConnMap[platform]; okMap { - if oldconn == conn { - delete(oldConnMap, platform) + platform := int(conn.PlatformID) + + if oldConnMap, ok := ws.wsUserToConn[conn.userID]; ok { // only recycle self conn + if oldconns, okMap := oldConnMap[platform]; okMap { + var flag bool + a := make([]*UserConn, 2) + for _, client := range oldconns { + if client != conn { + a = append(a, client) + flag = true } } - ws.wsUserToConn[uid] = oldConnMap - if len(oldConnMap) == 0 { - delete(ws.wsUserToConn, uid) + if flag { + oldConnMap[platform] = a + } else { + delete(oldConnMap, platform) } - count := 0 - for _, v := range ws.wsUserToConn { - count = count + len(v) - } - log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", uid, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn), "online_conn_num", count) - } else { - log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", uid, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn)) + } - delete(ws.wsConnToUser, conn) + ws.wsUserToConn[conn.userID] = oldConnMap + if len(oldConnMap) == 0 { + delete(ws.wsUserToConn, conn.userID) + } + count := 0 + for _, v := range ws.wsUserToConn { + count = count + len(v) + } + log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", conn.userID, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn), "online_conn_num", count) } + err := conn.Close() if err != nil { - log.Error(operationID, " close err", "", "uid", uid, "platform", platform) + log.Error(operationID, " close err", "", "uid", conn.userID, "platform", platform) } if conn.PlatformID == 0 || conn.connID == "" { log.NewWarn(operationID, utils.GetSelfFuncName(), "PlatformID or connID is null", conn.PlatformID, conn.connID) @@ -412,21 +415,21 @@ func (ws *WServer) delUserConn(conn *UserConn) { } -func (ws *WServer) getUserConn(uid string, platform int) *UserConn { +// func (ws *WServer) getUserConn(uid string, platform int) *UserConn { +// rwLock.RLock() +// defer rwLock.RUnlock() +// if connMap, ok := ws.wsUserToConn[uid]; ok { +// if conn, flag := connMap[platform]; flag { +// return conn +// } +// } +// return nil +// } +func (ws *WServer) getUserAllCons(uid string) map[int][]*UserConn { rwLock.RLock() defer rwLock.RUnlock() if connMap, ok := ws.wsUserToConn[uid]; ok { - if conn, flag := connMap[platform]; flag { - return conn - } - } - return nil -} -func (ws *WServer) getUserAllCons(uid string) map[int]*UserConn { - rwLock.RLock() - defer rwLock.RUnlock() - if connMap, ok := ws.wsUserToConn[uid]; ok { - newConnMap := make(map[int]*UserConn) + newConnMap := make(map[int][]*UserConn) for k, v := range connMap { newConnMap[k] = v } From 40a7bb9d4880066a5b327e99121a2f2a70542df5 Mon Sep 17 00:00:00 2001 From: Gordon <1432970085@qq.com> Date: Thu, 2 Mar 2023 19:08:35 +0800 Subject: [PATCH 5/8] test log --- internal/msg_gateway/gate/relay_rpc_server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/msg_gateway/gate/relay_rpc_server.go b/internal/msg_gateway/gate/relay_rpc_server.go index 8e7589ab8..c9a305581 100644 --- a/internal/msg_gateway/gate/relay_rpc_server.go +++ b/internal/msg_gateway/gate/relay_rpc_server.go @@ -199,6 +199,7 @@ func (r *RPCServer) SuperGroupOnlineBatchPushOneMsg(_ context.Context, req *pbRe userConnMap := ws.getUserAllCons(v) for platform, userConns := range userConnMap { if len(userConns) != 0 { + log.NewWarn(req.OperationID, "conns is ", len(userConns), platform, userConns) for _, userConn := range userConns { temp := &pbRelay.SingleMsgToUserPlatform{ RecvID: v, From c8038213c70689a207bcb3a435a17dc156060ab2 Mon Sep 17 00:00:00 2001 From: Gordon <1432970085@qq.com> Date: Thu, 2 Mar 2023 19:24:24 +0800 Subject: [PATCH 6/8] ws support same terminal login --- internal/msg_gateway/gate/ws_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/msg_gateway/gate/ws_server.go b/internal/msg_gateway/gate/ws_server.go index 7ffe7b94b..e1fe47fd9 100644 --- a/internal/msg_gateway/gate/ws_server.go +++ b/internal/msg_gateway/gate/ws_server.go @@ -352,7 +352,7 @@ func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token log.Debug(operationID, "user not first come in, add conn ", uid, platformID, conn, oldConnMap) } else { i := make(map[int][]*UserConn) - conns := make([]*UserConn, 2) + conns := make([]*UserConn, 1) conns = append(conns, conn) i[platformID] = conns ws.wsUserToConn[uid] = i From c182001fcf86bfd0da3dbc376f6f6206eaf7b739 Mon Sep 17 00:00:00 2001 From: Gordon <1432970085@qq.com> Date: Thu, 2 Mar 2023 19:36:48 +0800 Subject: [PATCH 7/8] ws support same terminal login --- internal/msg_gateway/gate/ws_server.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/msg_gateway/gate/ws_server.go b/internal/msg_gateway/gate/ws_server.go index e1fe47fd9..6d70a9332 100644 --- a/internal/msg_gateway/gate/ws_server.go +++ b/internal/msg_gateway/gate/ws_server.go @@ -344,7 +344,7 @@ func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token conns = append(conns, conn) oldConnMap[platformID] = conns } else { - conns := make([]*UserConn, 2) + var conns []*UserConn conns = append(conns, conn) oldConnMap[platformID] = conns } @@ -352,7 +352,7 @@ func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token log.Debug(operationID, "user not first come in, add conn ", uid, platformID, conn, oldConnMap) } else { i := make(map[int][]*UserConn) - conns := make([]*UserConn, 1) + var conns []*UserConn conns = append(conns, conn) i[platformID] = conns ws.wsUserToConn[uid] = i @@ -374,15 +374,16 @@ func (ws *WServer) delUserConn(conn *UserConn) { if oldConnMap, ok := ws.wsUserToConn[conn.userID]; ok { // only recycle self conn if oldconns, okMap := oldConnMap[platform]; okMap { - var flag bool - a := make([]*UserConn, 2) + + var a []*UserConn + for _, client := range oldconns { if client != conn { a = append(a, client) - flag = true + } } - if flag { + if len(a) != 0 { oldConnMap[platform] = a } else { delete(oldConnMap, platform) From d0b659ccea07960355ffa06c19069498d4853ca6 Mon Sep 17 00:00:00 2001 From: Gordon <1432970085@qq.com> Date: Tue, 7 Mar 2023 11:09:17 +0800 Subject: [PATCH 8/8] super group notification --- internal/msg_gateway/gate/relay_rpc_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/msg_gateway/gate/relay_rpc_server.go b/internal/msg_gateway/gate/relay_rpc_server.go index c9a305581..bc27d5f19 100644 --- a/internal/msg_gateway/gate/relay_rpc_server.go +++ b/internal/msg_gateway/gate/relay_rpc_server.go @@ -205,7 +205,7 @@ func (r *RPCServer) SuperGroupOnlineBatchPushOneMsg(_ context.Context, req *pbRe RecvID: v, RecvPlatFormID: int32(platform), } - if !userConn.IsBackground { + if !userConn.IsBackground || req.MsgData.ContentType == constant.SuperGroupUpdateNotification { resultCode := sendMsgBatchToUser(userConn, replyBytes.Bytes(), req, platform, v) if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) { tempT.OnlinePush = true