Merge remote-tracking branch 'origin/errcode' into errcode

This commit is contained in:
withchao 2023-02-20 17:44:28 +08:00
commit 5bb42593ba
14 changed files with 291 additions and 342 deletions

View File

@ -1,27 +1,11 @@
package main package main
import ( import (
rpcConversation "Open_IM/internal/rpc/conversation" "Open_IM/internal/rpc/conversation"
"Open_IM/internal/startrpc"
"Open_IM/pkg/common/config" "Open_IM/pkg/common/config"
"Open_IM/pkg/common/constant"
prome "Open_IM/pkg/common/prome"
"flag"
"fmt"
) )
func main() { func main() {
defaultPorts := config.Config.RpcPort.OpenImConversationPort startrpc.Start(config.Config.RpcPort.OpenImConversationPort, config.Config.RpcRegisterName.OpenImConversationName, config.Config.Prometheus.ConversationPrometheusPort, conversation.Start)
rpcPort := flag.Int("port", defaultPorts[0], "RpcConversation default listen port 11300")
prometheusPort := flag.Int("prometheus_port", config.Config.Prometheus.ConversationPrometheusPort[0], "conversationPrometheusPort default listen port")
flag.Parse()
fmt.Println("start conversation rpc server, port: ", *rpcPort, ", OpenIM version: ", constant.CurrentVersion, "\n")
rpcServer := rpcConversation.NewRpcConversationServer(*rpcPort)
go func() {
err := prome.StartPromeSrv(*prometheusPort)
if err != nil {
panic(err)
}
}()
rpcServer.Run()
} }

View File

@ -2,6 +2,7 @@ package check
import ( import (
"Open_IM/pkg/common/config" "Open_IM/pkg/common/config"
"Open_IM/pkg/common/constant"
discoveryRegistry "Open_IM/pkg/discoveryregistry" discoveryRegistry "Open_IM/pkg/discoveryregistry"
"Open_IM/pkg/proto/friend" "Open_IM/pkg/proto/friend"
sdkws "Open_IM/pkg/proto/sdkws" sdkws "Open_IM/pkg/proto/sdkws"
@ -37,5 +38,38 @@ func (f *FriendChecker) getConn() (*grpc.ClientConn, error) {
// possibleFriendUserID是否在userID的好友中 // possibleFriendUserID是否在userID的好友中
func (f *FriendChecker) IsFriend(ctx context.Context, possibleFriendUserID, userID string) (bool, error) { func (f *FriendChecker) IsFriend(ctx context.Context, possibleFriendUserID, userID string) (bool, error) {
return false, nil cc, err := f.getConn()
if err != nil {
return false, err
}
resp, err := friend.NewFriendClient(cc).IsFriend(ctx, &friend.IsFriendReq{UserID1: userID, UserID2: possibleFriendUserID})
if err != nil {
return false, err
}
return resp.InUser1Friends, nil
}
func (f *FriendChecker) GetAllPageFriends(ctx context.Context, ownerUserID string) (resp []*sdkws.FriendInfo, err error) {
cc, err := f.getConn()
if err != nil {
return nil, err
}
page := int32(0)
req := friend.GetPaginationFriendsReq{UserID: ownerUserID}
for {
req.Pagination = &sdkws.RequestPagination{PageNumber: page, ShowNumber: constant.ShowNumber}
tmp, err := friend.NewFriendClient(cc).GetPaginationFriends(ctx, &req)
if err != nil {
return nil, err
}
if len(tmp.FriendsInfo) == 0 {
if tmp.Total == int32(len(resp)) {
return resp, nil
}
return nil, constant.ErrData.Wrap("total != resp, but result is nil")
}
resp = append(resp, tmp.FriendsInfo...)
page++
}
} }

View File

@ -2,132 +2,41 @@ package conversation
import ( import (
"Open_IM/internal/common/check" "Open_IM/internal/common/check"
chat "Open_IM/internal/rpc/msg"
"Open_IM/pkg/common/constant" "Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db/cache" "Open_IM/pkg/common/db/cache"
"Open_IM/pkg/common/db/controller" "Open_IM/pkg/common/db/controller"
"Open_IM/pkg/common/db/relation" "Open_IM/pkg/common/db/relation"
tableRelation "Open_IM/pkg/common/db/table/relation" tableRelation "Open_IM/pkg/common/db/table/relation"
"github.com/OpenIMSDK/openKeeper"
"Open_IM/pkg/common/log" "Open_IM/internal/common/notification"
promePkg "Open_IM/pkg/common/prome"
pbConversation "Open_IM/pkg/proto/conversation" pbConversation "Open_IM/pkg/proto/conversation"
"Open_IM/pkg/utils" "Open_IM/pkg/utils"
"context" "context"
"github.com/dtm-labs/rockscache"
"net"
"strconv"
"strings"
grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"Open_IM/pkg/common/config"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
type conversationServer struct { type conversationServer struct {
rpcPort int groupChecker *check.GroupChecker
rpcRegisterName string
etcdSchema string
etcdAddr []string
groupChecker *check.GroupChecker
controller.ConversationInterface controller.ConversationInterface
notify *notification.Check
} }
func NewConversationServer(port int) *conversationServer { func Start(client *openKeeper.ZkClient, server *grpc.Server) error {
log.NewPrivateLog(constant.LogFileName) db, err := relation.NewGormDB()
c := conversationServer{
rpcPort: port,
rpcRegisterName: config.Config.RpcRegisterName.OpenImConversationName,
etcdSchema: config.Config.Etcd.EtcdSchema,
etcdAddr: config.Config.Etcd.EtcdAddr,
groupChecker: check.NewGroupChecker(),
}
var cDB relation.Conversation
var cCache cache.ConversationCache
//mysql init
var mysql relation.Mysql
err := mysql.InitConn().AutoMigrateModel(&tableRelation.ConversationModel{})
if err != nil { if err != nil {
panic("db init err:" + err.Error()) return err
} }
if mysql.GormConn() != nil { if err := db.AutoMigrate(&tableRelation.ConversationModel{}); err != nil {
//get gorm model return err
cDB = relation.NewConversationGorm(mysql.GormConn())
} else {
panic("db init err:" + "conn is nil")
} }
//redis init pbConversation.RegisterConversationServer(server, &conversationServer{
var redis cache.RedisClient groupChecker: check.NewGroupChecker(client),
redis.InitRedis() ConversationInterface: controller.NewConversationController(controller.NewConversationDataBase(controller.NewConversationGorm(db), cache.NewConversationRedis(nil))),
rcClient := rockscache.NewClient(redis.GetClient(), rockscache.Options{
RandomExpireAdjustment: 0.2,
DisableCacheRead: false,
DisableCacheDelete: false,
StrongConsistency: true,
}) })
cCache = cache.NewConversationRedis(rcClient) controller.NewConversationDataBase()
controller.NewConversationController()
database := controller.NewConversationDataBase(cDB, cCache) return nil
c.ConversationInterface = controller.NewConversationController(database)
return &c
}
func (c *conversationServer) Run() {
log.NewInfo("0", "rpc conversation start...")
listenIP := ""
if config.Config.ListenIP == "" {
listenIP = "0.0.0.0"
} else {
listenIP = config.Config.ListenIP
}
address := listenIP + ":" + strconv.Itoa(c.rpcPort)
listener, err := net.Listen("tcp", address)
if err != nil {
panic("listening err:" + err.Error() + c.rpcRegisterName)
}
log.NewInfo("0", "listen network success, ", address, listener)
//grpc server
var grpcOpts []grpc.ServerOption
if config.Config.Prometheus.Enable {
promePkg.NewGrpcRequestCounter()
promePkg.NewGrpcRequestFailedCounter()
promePkg.NewGrpcRequestSuccessCounter()
grpcOpts = append(grpcOpts, []grpc.ServerOption{
// grpc.UnaryInterceptor(promePkg.UnaryServerInterceptorProme),
grpc.StreamInterceptor(grpcPrometheus.StreamServerInterceptor),
grpc.UnaryInterceptor(grpcPrometheus.UnaryServerInterceptor),
}...)
}
srv := grpc.NewServer(grpcOpts...)
defer srv.GracefulStop()
//service registers with etcd
pbConversation.RegisterConversationServer(srv, c)
rpcRegisterIP := config.Config.RpcRegisterIP
if config.Config.RpcRegisterIP == "" {
rpcRegisterIP, err = utils.GetLocalIP()
if err != nil {
log.Error("", "GetLocalIP failed ", err.Error())
}
}
log.NewInfo("", "rpcRegisterIP", rpcRegisterIP)
err = rpc.RegisterEtcd(c.etcdSchema, strings.Join(c.etcdAddr, ","), rpcRegisterIP, c.rpcPort, c.rpcRegisterName, 10, "")
if err != nil {
log.NewError("0", "RegisterEtcd failed ", err.Error(),
c.etcdSchema, strings.Join(c.etcdAddr, ","), rpcRegisterIP, c.rpcPort, c.rpcRegisterName)
panic(utils.Wrap(err, "register conversation module rpc to etcd err"))
}
log.NewInfo("0", "RegisterConversationServer ok ", c.etcdSchema, strings.Join(c.etcdAddr, ","), rpcRegisterIP, c.rpcPort, c.rpcRegisterName)
err = srv.Serve(listener)
if err != nil {
log.NewError("0", "Serve failed ", err.Error())
return
}
log.NewInfo("0", "rpc conversation ok")
} }
func (c *conversationServer) GetConversation(ctx context.Context, req *pbConversation.GetConversationReq) (*pbConversation.GetConversationResp, error) { func (c *conversationServer) GetConversation(ctx context.Context, req *pbConversation.GetConversationReq) (*pbConversation.GetConversationResp, error) {
@ -179,7 +88,7 @@ func (c *conversationServer) BatchSetConversations(ctx context.Context, req *pbC
if err != nil { if err != nil {
return nil, err return nil, err
} }
chat.ConversationChangeNotification(ctx, req.OwnerUserID) c.notify.ConversationChangeNotification(ctx, req.OwnerUserID)
return resp, nil return resp, nil
} }
@ -196,7 +105,7 @@ func (c *conversationServer) ModifyConversationField(ctx context.Context, req *p
var err error var err error
isSyncConversation := true isSyncConversation := true
if req.Conversation.ConversationType == constant.GroupChatType { if req.Conversation.ConversationType == constant.GroupChatType {
groupInfo, err := c.groupChecker.GetGroupInfo(req.Conversation.GroupID) groupInfo, err := c.groupChecker.GetGroupInfo(ctx, req.Conversation.GroupID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -213,7 +122,7 @@ func (c *conversationServer) ModifyConversationField(ctx context.Context, req *p
if err != nil { if err != nil {
return nil, err return nil, err
} }
chat.ConversationSetPrivateNotification(ctx, req.Conversation.OwnerUserID, req.Conversation.UserID, req.Conversation.IsPrivateChat) c.notify.ConversationSetPrivateNotification(ctx, req.Conversation.OwnerUserID, req.Conversation.UserID, req.Conversation.IsPrivateChat)
return resp, nil return resp, nil
} }
//haveUserID, err := c.ConversationInterface.GetUserIDExistConversation(ctx, req.UserIDList, req.Conversation.ConversationID) //haveUserID, err := c.ConversationInterface.GetUserIDExistConversation(ctx, req.UserIDList, req.Conversation.ConversationID)
@ -247,11 +156,11 @@ func (c *conversationServer) ModifyConversationField(ctx context.Context, req *p
if isSyncConversation { if isSyncConversation {
for _, v := range req.UserIDList { for _, v := range req.UserIDList {
chat.ConversationChangeNotification(ctx, v) c.notify.ConversationChangeNotification(ctx, v)
} }
} else { } else {
for _, v := range req.UserIDList { for _, v := range req.UserIDList {
chat.ConversationUnreadChangeNotification(ctx, v, req.Conversation.ConversationID, req.Conversation.UpdateUnreadCountTime) c.notify.ConversationUnreadChangeNotification(ctx, v, req.Conversation.ConversationID, req.Conversation.UpdateUnreadCountTime)
} }
} }
return resp, nil return resp, nil

View File

@ -7,10 +7,10 @@ import (
"Open_IM/pkg/common/constant" "Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db/controller" "Open_IM/pkg/common/db/controller"
"Open_IM/pkg/common/db/relation" "Open_IM/pkg/common/db/relation"
relationTb "Open_IM/pkg/common/db/table/relation" tablerelation "Open_IM/pkg/common/db/table/relation"
"Open_IM/pkg/common/tokenverify" "Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/common/tracelog" "Open_IM/pkg/common/tracelog"
discoveryRegistry "Open_IM/pkg/discoveryregistry" registry "Open_IM/pkg/discoveryregistry"
pbfriend "Open_IM/pkg/proto/friend" pbfriend "Open_IM/pkg/proto/friend"
"Open_IM/pkg/utils" "Open_IM/pkg/utils"
"context" "context"
@ -23,7 +23,7 @@ type friendServer struct {
controller.BlackInterface controller.BlackInterface
notification *notification.Check notification *notification.Check
userCheck *check.UserCheck userCheck *check.UserCheck
RegisterCenter discoveryRegistry.SvcDiscoveryRegistry RegisterCenter registry.SvcDiscoveryRegistry
} }
func Start(client *openKeeper.ZkClient, server *grpc.Server) error { func Start(client *openKeeper.ZkClient, server *grpc.Server) error {
@ -31,7 +31,7 @@ func Start(client *openKeeper.ZkClient, server *grpc.Server) error {
if err != nil { if err != nil {
return err return err
} }
if err := mysql.AutoMigrate(&relationTb.FriendModel{}, &relationTb.FriendRequestModel{}, &relationTb.BlackModel{}); err != nil { if err := mysql.AutoMigrate(&tablerelation.FriendModel{}, &tablerelation.FriendRequestModel{}, &tablerelation.BlackModel{}); err != nil {
return err return err
} }
pbfriend.RegisterFriendServer(server, &friendServer{ pbfriend.RegisterFriendServer(server, &friendServer{
@ -102,7 +102,7 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.Res
if err := s.userCheck.Access(ctx, req.ToUserID); err != nil { if err := s.userCheck.Access(ctx, req.ToUserID); err != nil {
return nil, err return nil, err
} }
friendRequest := relationTb.FriendRequestModel{FromUserID: req.FromUserID, ToUserID: req.ToUserID, HandleMsg: req.HandleMsg, HandleResult: req.HandleResult} friendRequest := tablerelation.FriendRequestModel{FromUserID: req.FromUserID, ToUserID: req.ToUserID, HandleMsg: req.HandleMsg, HandleResult: req.HandleResult}
if req.HandleResult == constant.FriendResponseAgree { if req.HandleResult == constant.FriendResponseAgree {
err := s.AgreeFriendRequest(ctx, &friendRequest) err := s.AgreeFriendRequest(ctx, &friendRequest)
if err != nil { if err != nil {
@ -158,20 +158,21 @@ func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFri
// ok // ok
func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *pbfriend.GetDesignatedFriendsReq) (resp *pbfriend.GetDesignatedFriendsResp, err error) { func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *pbfriend.GetDesignatedFriendsReq) (resp *pbfriend.GetDesignatedFriendsResp, err error) {
resp = &pbfriend.GetDesignatedFriendsResp{} resp = &pbfriend.GetDesignatedFriendsResp{}
if err := s.userCheck.Access(ctx, req.UserID); err != nil {
return nil, err if utils.Duplicate(req.FriendUserIDs) {
return nil, constant.ErrArgs.Wrap("friend userID repeated")
} }
friends, total, err := s.FriendInterface.PageOwnerFriends(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) friends, err := s.FriendInterface.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp.FriendsInfo, err = (*convert.NewDBFriend(nil, s.RegisterCenter)).DB2PB(ctx, friends) if resp.FriendsInfo, err = (*convert.NewDBFriend(nil, s.RegisterCenter)).DB2PB(ctx, friends); err != nil {
if err != nil {
return nil, err return nil, err
} }
resp.Total = int32(total)
return resp, nil return resp, nil
} }
// ok 获取接收到的好友申请(即别人主动申请的) // ok 获取接收到的好友申请(即别人主动申请的)
@ -223,15 +224,17 @@ func (s *friendServer) IsFriend(ctx context.Context, req *pbfriend.IsFriendReq)
// ok // ok
func (s *friendServer) GetPaginationFriends(ctx context.Context, req *pbfriend.GetPaginationFriendsReq) (resp *pbfriend.GetPaginationFriendsResp, err error) { func (s *friendServer) GetPaginationFriends(ctx context.Context, req *pbfriend.GetPaginationFriendsReq) (resp *pbfriend.GetPaginationFriendsResp, err error) {
resp = &pbfriend.GetPaginationFriendsResp{} resp = &pbfriend.GetPaginationFriendsResp{}
if utils.Duplicate(req.FriendUserIDs) { if err := s.userCheck.Access(ctx, req.UserID); err != nil {
return nil, constant.ErrArgs.Wrap("friend userID repeated") return nil, err
} }
friends, err := s.FriendInterface.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs) friends, total, err := s.FriendInterface.PageOwnerFriends(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resp.FriendsInfo, err = (*convert.NewDBFriend(nil, s.RegisterCenter)).DB2PB(ctx, friends); err != nil { resp.FriendsInfo, err = (*convert.NewDBFriend(nil, s.RegisterCenter)).DB2PB(ctx, friends)
if err != nil {
return nil, err return nil, err
} }
resp.Total = int32(total)
return resp, nil return resp, nil
} }

View File

@ -10,7 +10,7 @@ import (
tablerelation "Open_IM/pkg/common/db/table/relation" tablerelation "Open_IM/pkg/common/db/table/relation"
"Open_IM/pkg/common/tokenverify" "Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/common/tracelog" "Open_IM/pkg/common/tracelog"
discoveryRegistry "Open_IM/pkg/discoveryregistry" registry "Open_IM/pkg/discoveryregistry"
"Open_IM/pkg/proto/sdkws" "Open_IM/pkg/proto/sdkws"
pbuser "Open_IM/pkg/proto/user" pbuser "Open_IM/pkg/proto/user"
"Open_IM/pkg/utils" "Open_IM/pkg/utils"
@ -24,7 +24,8 @@ type userServer struct {
notification *notification.Check notification *notification.Check
userCheck *check.UserCheck userCheck *check.UserCheck
ConversationChecker *check.ConversationChecker ConversationChecker *check.ConversationChecker
RegisterCenter discoveryRegistry.SvcDiscoveryRegistry RegisterCenter registry.SvcDiscoveryRegistry
friendCheck *check.FriendChecker
} }
func Start(client *openKeeper.ZkClient, server *grpc.Server) error { func Start(client *openKeeper.ZkClient, server *grpc.Server) error {
@ -58,10 +59,6 @@ func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuser.GetDesig
return resp, nil return resp, nil
} }
func (s *userServer) GetAllPageFriends(ctx context.Context, ownerUserID string) (resp []*sdkws.FriendInfo, err error) {
return
}
// ok // ok
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) { func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
resp = &pbuser.UpdateUserInfoResp{} resp = &pbuser.UpdateUserInfoResp{}
@ -69,14 +66,6 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
if err != nil { if err != nil {
return nil, err return nil, err
} }
//oldNickname := ""
//if req.UserInfo.Nickname != "" {
// u, err := s.FindWithError(ctx, []string{req.UserInfo.UserID})
// if err != nil {
// return nil, err
// }
// oldNickname = u[0].Nickname
//}
user, err := convert.NewPBUser(req.UserInfo).Convert() user, err := convert.NewPBUser(req.UserInfo).Convert()
if err != nil { if err != nil {
return nil, err return nil, err
@ -85,7 +74,7 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
if err != nil { if err != nil {
return nil, err return nil, err
} }
friends, err := s.GetAllPageFriends(ctx, req.UserInfo.UserID) friends, err := s.friendCheck.GetAllPageFriends(ctx, req.UserInfo.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -94,9 +83,7 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
s.notification.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, v.FriendUser.UserID, tracelog.GetOpUserID(ctx)) s.notification.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, v.FriendUser.UserID, tracelog.GetOpUserID(ctx))
} }
}() }()
s.notification.UserInfoUpdatedNotification(ctx, tracelog.GetOpUserID(ctx), req.UserInfo.UserID) s.notification.UserInfoUpdatedNotification(ctx, tracelog.GetOpUserID(ctx), req.UserInfo.UserID)
return resp, nil return resp, nil
} }
@ -184,3 +171,13 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
} }
return resp, nil return resp, nil
} }
func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.GetGlobalRecvMessageOptReq) (resp *pbuser.GetGlobalRecvMessageOptResp, err error) {
resp = &pbuser.GetGlobalRecvMessageOptResp{}
user, err := s.FindWithError(ctx, []string{req.UserID})
if err != nil {
return nil, err
}
resp.GlobalRecvMsgOpt = user[0].GlobalRecvMsgOpt
return resp, nil
}

View File

@ -315,10 +315,6 @@ func GroupIsBanPrivateChat(status int32) bool {
return true return true
} }
const (
TokenKicked = 1001
)
const BigVersion = "v2" const BigVersion = "v2"
const LogFileName = "OpenIM.log" const LogFileName = "OpenIM.log"

View File

@ -35,6 +35,8 @@ const (
sendMsgFailedFlag = "SEND_MSG_FAILED_FLAG:" sendMsgFailedFlag = "SEND_MSG_FAILED_FLAG:"
userBadgeUnreadCountSum = "USER_BADGE_UNREAD_COUNT_SUM:" userBadgeUnreadCountSum = "USER_BADGE_UNREAD_COUNT_SUM:"
exTypeKeyLocker = "EX_LOCK:" exTypeKeyLocker = "EX_LOCK:"
uidPidToken = "UID_PID_TOKEN_STATUS:"
) )
type Cache interface { type Cache interface {
@ -52,7 +54,9 @@ type Cache interface {
SetGroupMinSeq(ctx context.Context, groupID string, minSeq int64) error SetGroupMinSeq(ctx context.Context, groupID string, minSeq int64) error
AddTokenFlag(ctx context.Context, userID string, platformID int, token string, flag int) error AddTokenFlag(ctx context.Context, userID string, platformID int, token string, flag int) error
GetTokenMapByUidPid(ctx context.Context, userID, platformID string) (map[string]int, error)
GetTokensWithoutError(ctx context.Context, userID, platformID string) (map[string]int, error)
SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error
DeleteTokenByUidPid(ctx context.Context, userID string, platformID int, fields []string) error DeleteTokenByUidPid(ctx context.Context, userID string, platformID int, fields []string) error
GetMessageListBySeq(ctx context.Context, userID string, seqList []int64) (seqMsg []*sdkws.MsgData, failedSeqList []int64, err error) GetMessageListBySeq(ctx context.Context, userID string, seqList []int64) (seqMsg []*sdkws.MsgData, failedSeqList []int64, err error)
@ -209,11 +213,12 @@ func (r *RedisClient) SetGroupMinSeq(ctx context.Context, groupID string, minSeq
} }
// Store userid and platform class to redis // Store userid and platform class to redis
func (r *RedisClient) AddTokenFlag(ctx context.Context, userID string, platformID int, token string, flag int) error { func (r *RedisClient) AddTokenFlag(ctx context.Context, userID string, platform string, token string, flag int) error {
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platformID) key := uidPidToken + userID + ":" + platform
return r.rdb.HSet(context.Background(), key, token, flag).Err() return r.rdb.HSet(context.Background(), key, token, flag).Err()
} }
//key:userID+platform-> <token, flag>
func (r *RedisClient) GetTokenMapByUidPid(ctx context.Context, userID, platformID string) (map[string]int, error) { func (r *RedisClient) GetTokenMapByUidPid(ctx context.Context, userID, platformID string) (map[string]int, error) {
key := uidPidToken + userID + ":" + platformID key := uidPidToken + userID + ":" + platformID
m, err := r.rdb.HGetAll(context.Background(), key).Result() m, err := r.rdb.HGetAll(context.Background(), key).Result()
@ -223,8 +228,22 @@ func (r *RedisClient) GetTokenMapByUidPid(ctx context.Context, userID, platformI
} }
return mm, err return mm, err
} }
func (r *RedisClient) SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error {
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platformID) func (r *RedisClient) GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error) {
key := uidPidToken + userID + ":" + platform
m, err := r.rdb.HGetAll(context.Background(), key).Result()
if err != nil && err == redis.Nil {
return nil, nil
}
mm := make(map[string]int)
for k, v := range m {
mm[k] = utils.StringToInt(v)
}
return mm, utils.Wrap(err, "")
}
func (r *RedisClient) SetTokenMapByUidPid(ctx context.Context, userID string, platform string, m map[string]int) error {
key := uidPidToken + userID + ":" + platform
mm := make(map[string]interface{}) mm := make(map[string]interface{})
for k, v := range m { for k, v := range m {
mm[k] = v mm[k] = v
@ -232,8 +251,8 @@ func (r *RedisClient) SetTokenMapByUidPid(ctx context.Context, userID string, pl
return r.rdb.HSet(context.Background(), key, mm).Err() return r.rdb.HSet(context.Background(), key, mm).Err()
} }
func (r *RedisClient) DeleteTokenByUidPid(ctx context.Context, userID string, platformID int, fields []string) error { func (r *RedisClient) DeleteTokenByUidPid(ctx context.Context, userID string, platform string, fields []string) error {
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platformID) key := uidPidToken + userID + ":" + platform
return r.rdb.HDel(context.Background(), key, fields...).Err() return r.rdb.HDel(context.Background(), key, fields...).Err()
} }

View File

@ -5,14 +5,9 @@ import (
"Open_IM/pkg/common/tokenverify" "Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/utils" "Open_IM/pkg/utils"
"context" "context"
"github.com/go-redis/redis/v8"
"github.com/golang-jwt/jwt/v4" "github.com/golang-jwt/jwt/v4"
) )
const (
uidPidToken = "UID_PID_TOKEN_STATUS:"
)
type Token interface { type Token interface {
//结果为空 不返回错误 //结果为空 不返回错误
GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error) GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error)
@ -21,9 +16,9 @@ type Token interface {
} }
type TokenRedis struct { type TokenRedis struct {
RedisClient *RedisClient redisClient *RedisClient
AccessSecret string accessSecret string
AccessExpire int64 accessExpire int64
} }
func NewTokenRedis(redisClient *RedisClient, accessSecret string, accessExpire int64) *TokenRedis { func NewTokenRedis(redisClient *RedisClient, accessSecret string, accessExpire int64) *TokenRedis {
@ -32,21 +27,12 @@ func NewTokenRedis(redisClient *RedisClient, accessSecret string, accessExpire i
// 结果为空 不返回错误 // 结果为空 不返回错误
func (t *TokenRedis) GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error) { func (t *TokenRedis) GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error) {
key := uidPidToken + userID + ":" + platform return t.redisClient.GetTokensWithoutError(ctx, userID, platform)
m, err := t.RedisClient.GetClient().HGetAll(context.Background(), key).Result()
if err != nil && err == redis.Nil {
return nil, nil
}
mm := make(map[string]int)
for k, v := range m {
mm[k] = utils.StringToInt(v)
}
return mm, utils.Wrap(err, "")
} }
// 创建token // 创建token
func (t *TokenRedis) CreateToken(ctx context.Context, userID string, platform string) (string, error) { func (t *TokenRedis) CreateToken(ctx context.Context, userID string, platform string) (string, error) {
tokens, err := t.GetTokensWithoutError(ctx, userID, platform) tokens, err := t.redisClient.GetTokensWithoutError(ctx, userID, platform)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -58,18 +44,16 @@ func (t *TokenRedis) CreateToken(ctx context.Context, userID string, platform st
} }
} }
if len(deleteTokenKey) != 0 { if len(deleteTokenKey) != 0 {
key := uidPidToken + userID + ":" + platform err := t.redisClient.DeleteTokenByUidPid(ctx, userID, platform, deleteTokenKey)
err := t.RedisClient.GetClient().HDel(context.Background(), key, deleteTokenKey...).Err()
if err != nil { if err != nil {
return "", err return "", err
} }
} }
claims := tokenverify.BuildClaims(userID, platform, t.AccessExpire) claims := tokenverify.BuildClaims(userID, platform, t.accessExpire)
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(t.AccessSecret)) tokenString, err := token.SignedString([]byte(t.accessSecret))
if err != nil { if err != nil {
return "", utils.Wrap(err, "") return "", utils.Wrap(err, "")
} }
key := uidPidToken + userID + ":" + platform return tokenString, t.redisClient.AddTokenFlag(ctx, userID, platform, tokenString, constant.NormalToken)
return "", utils.Wrap(t.RedisClient.GetClient().HSet(context.Background(), key, tokenString, constant.NormalToken).Err(), "")
} }

View File

@ -9,7 +9,6 @@ import (
type AuthInterface interface { type AuthInterface interface {
//结果为空 不返回错误 //结果为空 不返回错误
GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error) GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error)
//创建token //创建token
CreateToken(ctx context.Context, userID string, platform string) (string, error) CreateToken(ctx context.Context, userID string, platform string) (string, error)
} }

View File

@ -94,17 +94,17 @@ var _ ConversationDataBaseInterface = (*ConversationDataBase)(nil)
type ConversationDataBase struct { type ConversationDataBase struct {
conversationDB relation.Conversation conversationDB relation.Conversation
cache cache.ConversationCache cache cache.ConversationCache
db *gorm.DB
} }
func (c ConversationDataBase) SetUsersConversationFiledTx(ctx context.Context, userIDList []string, conversation *relationTb.ConversationModel, filedMap map[string]interface{}) error { func (c ConversationDataBase) SetUsersConversationFiledTx(ctx context.Context, userIDList []string, conversation *relationTb.ConversationModel, filedMap map[string]interface{}) error {
return c.db.Transaction(func(tx *gorm.DB) error { fn := func(tx any) error {
haveUserID, err := c.conversationDB.FindUserID(ctx, userIDList, conversation.ConversationID, tx) temp := c.conversationDB.NewTx(tx)
haveUserID, err := temp.FindUserID(ctx, userIDList, conversation.ConversationID, tx)
if err != nil { if err != nil {
return err return err
} }
if len(haveUserID) > 0 { if len(haveUserID) > 0 {
err = c.conversationDB.UpdateByMap(ctx, haveUserID, conversation.ConversationID, filedMap, tx) err = temp.UpdateByMap(ctx, haveUserID, conversation.ConversationID, filedMap, tx)
if err != nil { if err != nil {
return err return err
} }
@ -119,7 +119,7 @@ func (c ConversationDataBase) SetUsersConversationFiledTx(ctx context.Context, u
temp.OwnerUserID = v temp.OwnerUserID = v
cList = append(cList, temp) cList = append(cList, temp)
} }
err = c.conversationDB.Create(ctx, cList) err = temp.Create(ctx, cList)
if err != nil { if err != nil {
return err return err
} }
@ -134,7 +134,9 @@ func (c ConversationDataBase) SetUsersConversationFiledTx(ctx context.Context, u
return err return err
} }
return nil return nil
}) }
return c.conversationDB.Transaction(fn)
} }
func NewConversationDataBase(db relation.Conversation, cache cache.ConversationCache) *ConversationDataBase { func NewConversationDataBase(db relation.Conversation, cache cache.ConversationCache) *ConversationDataBase {

View File

@ -18,6 +18,8 @@ type Conversation interface {
FindUserIDAllConversationID(ctx context.Context, userID string, tx ...any) ([]string, error) FindUserIDAllConversationID(ctx context.Context, userID string, tx ...any) ([]string, error)
Take(ctx context.Context, userID, conversationID string, tx ...any) (conversation *relation.ConversationModel, err error) Take(ctx context.Context, userID, conversationID string, tx ...any) (conversation *relation.ConversationModel, err error)
FindConversationID(ctx context.Context, userID string, conversationIDList []string, tx ...any) (existConversationID []string, err error) FindConversationID(ctx context.Context, userID string, conversationIDList []string, tx ...any) (existConversationID []string, err error)
Transaction(func(tx any) error) error
NewTx(tx any) Conversation
} }
type ConversationGorm struct { type ConversationGorm struct {
DB *gorm.DB DB *gorm.DB
@ -26,6 +28,15 @@ type ConversationGorm struct {
func NewConversationGorm(DB *gorm.DB) Conversation { func NewConversationGorm(DB *gorm.DB) Conversation {
return &ConversationGorm{DB: DB} return &ConversationGorm{DB: DB}
} }
func (c *ConversationGorm) Transaction(fn func(tx any) error) error {
return c.DB.Transaction(func(tx *gorm.DB) error {
return fn(tx)
})
}
func (c *ConversationGorm) NewTx(tx any) Conversation {
return &ConversationGorm{DB: tx.(*gorm.DB)}
}
func (c *ConversationGorm) Create(ctx context.Context, conversations []*relation.ConversationModel, tx ...any) (err error) { func (c *ConversationGorm) Create(ctx context.Context, conversations []*relation.ConversationModel, tx ...any) (err error) {
defer func() { defer func() {

View File

@ -30,8 +30,11 @@ message parseTokenResp{
} }
service Auth { service Auth {
//token
rpc userToken(userTokenReq) returns(userTokenResp); rpc userToken(userTokenReq) returns(userTokenResp);
//退
rpc forceLogout(forceLogoutReq) returns(forceLogoutResp); rpc forceLogout(forceLogoutReq) returns(forceLogoutResp);
//token
rpc parseToken(parseTokenReq)returns(parseTokenResp); rpc parseToken(parseTokenReq)returns(parseTokenResp);
} }

View File

@ -25,18 +25,18 @@ var _ = math.Inf
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type GetPaginationFriendsReq struct { type GetPaginationFriendsReq struct {
OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID" json:"ownerUserID,omitempty"` Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination" json:"pagination,omitempty"`
FriendUserIDs []string `protobuf:"bytes,2,rep,name=friendUserIDs" json:"friendUserIDs,omitempty"` UserID string `protobuf:"bytes,2,opt,name=userID" json:"userID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
func (m *GetPaginationFriendsReq) Reset() { *m = GetPaginationFriendsReq{} } func (m *GetPaginationFriendsReq) Reset() { *m = GetPaginationFriendsReq{} }
func (m *GetPaginationFriendsReq) String() string { return proto.CompactTextString(m) } func (m *GetPaginationFriendsReq) String() string { return proto.CompactTextString(m) }
func (*GetPaginationFriendsReq) ProtoMessage() {} func (*GetPaginationFriendsReq) ProtoMessage() {}
func (*GetPaginationFriendsReq) Descriptor() ([]byte, []int) { func (*GetPaginationFriendsReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{0} return fileDescriptor_friend_2a356ccaa517dcdd, []int{0}
} }
func (m *GetPaginationFriendsReq) XXX_Unmarshal(b []byte) error { func (m *GetPaginationFriendsReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationFriendsReq.Unmarshal(m, b) return xxx_messageInfo_GetPaginationFriendsReq.Unmarshal(m, b)
@ -56,22 +56,23 @@ func (m *GetPaginationFriendsReq) XXX_DiscardUnknown() {
var xxx_messageInfo_GetPaginationFriendsReq proto.InternalMessageInfo var xxx_messageInfo_GetPaginationFriendsReq proto.InternalMessageInfo
func (m *GetPaginationFriendsReq) GetOwnerUserID() string { func (m *GetPaginationFriendsReq) GetPagination() *sdkws.RequestPagination {
if m != nil { if m != nil {
return m.OwnerUserID return m.Pagination
}
return ""
}
func (m *GetPaginationFriendsReq) GetFriendUserIDs() []string {
if m != nil {
return m.FriendUserIDs
} }
return nil return nil
} }
func (m *GetPaginationFriendsReq) GetUserID() string {
if m != nil {
return m.UserID
}
return ""
}
type GetPaginationFriendsResp struct { type GetPaginationFriendsResp struct {
FriendsInfo []*sdkws.FriendInfo `protobuf:"bytes,1,rep,name=friendsInfo" json:"friendsInfo,omitempty"` FriendsInfo []*sdkws.FriendInfo `protobuf:"bytes,1,rep,name=FriendsInfo" json:"FriendsInfo,omitempty"`
Total int32 `protobuf:"varint,2,opt,name=total" json:"total,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -81,7 +82,7 @@ func (m *GetPaginationFriendsResp) Reset() { *m = GetPaginationFriendsRe
func (m *GetPaginationFriendsResp) String() string { return proto.CompactTextString(m) } func (m *GetPaginationFriendsResp) String() string { return proto.CompactTextString(m) }
func (*GetPaginationFriendsResp) ProtoMessage() {} func (*GetPaginationFriendsResp) ProtoMessage() {}
func (*GetPaginationFriendsResp) Descriptor() ([]byte, []int) { func (*GetPaginationFriendsResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{1} return fileDescriptor_friend_2a356ccaa517dcdd, []int{1}
} }
func (m *GetPaginationFriendsResp) XXX_Unmarshal(b []byte) error { func (m *GetPaginationFriendsResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationFriendsResp.Unmarshal(m, b) return xxx_messageInfo_GetPaginationFriendsResp.Unmarshal(m, b)
@ -108,6 +109,13 @@ func (m *GetPaginationFriendsResp) GetFriendsInfo() []*sdkws.FriendInfo {
return nil return nil
} }
func (m *GetPaginationFriendsResp) GetTotal() int32 {
if m != nil {
return m.Total
}
return 0
}
type ApplyToAddFriendReq struct { type ApplyToAddFriendReq struct {
FromUserID string `protobuf:"bytes,1,opt,name=fromUserID" json:"fromUserID,omitempty"` FromUserID string `protobuf:"bytes,1,opt,name=fromUserID" json:"fromUserID,omitempty"`
ToUserID string `protobuf:"bytes,2,opt,name=toUserID" json:"toUserID,omitempty"` ToUserID string `protobuf:"bytes,2,opt,name=toUserID" json:"toUserID,omitempty"`
@ -122,7 +130,7 @@ func (m *ApplyToAddFriendReq) Reset() { *m = ApplyToAddFriendReq{} }
func (m *ApplyToAddFriendReq) String() string { return proto.CompactTextString(m) } func (m *ApplyToAddFriendReq) String() string { return proto.CompactTextString(m) }
func (*ApplyToAddFriendReq) ProtoMessage() {} func (*ApplyToAddFriendReq) ProtoMessage() {}
func (*ApplyToAddFriendReq) Descriptor() ([]byte, []int) { func (*ApplyToAddFriendReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{2} return fileDescriptor_friend_2a356ccaa517dcdd, []int{2}
} }
func (m *ApplyToAddFriendReq) XXX_Unmarshal(b []byte) error { func (m *ApplyToAddFriendReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ApplyToAddFriendReq.Unmarshal(m, b) return xxx_messageInfo_ApplyToAddFriendReq.Unmarshal(m, b)
@ -180,7 +188,7 @@ func (m *ApplyToAddFriendResp) Reset() { *m = ApplyToAddFriendResp{} }
func (m *ApplyToAddFriendResp) String() string { return proto.CompactTextString(m) } func (m *ApplyToAddFriendResp) String() string { return proto.CompactTextString(m) }
func (*ApplyToAddFriendResp) ProtoMessage() {} func (*ApplyToAddFriendResp) ProtoMessage() {}
func (*ApplyToAddFriendResp) Descriptor() ([]byte, []int) { func (*ApplyToAddFriendResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{3} return fileDescriptor_friend_2a356ccaa517dcdd, []int{3}
} }
func (m *ApplyToAddFriendResp) XXX_Unmarshal(b []byte) error { func (m *ApplyToAddFriendResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ApplyToAddFriendResp.Unmarshal(m, b) return xxx_messageInfo_ApplyToAddFriendResp.Unmarshal(m, b)
@ -212,7 +220,7 @@ func (m *ImportFriendReq) Reset() { *m = ImportFriendReq{} }
func (m *ImportFriendReq) String() string { return proto.CompactTextString(m) } func (m *ImportFriendReq) String() string { return proto.CompactTextString(m) }
func (*ImportFriendReq) ProtoMessage() {} func (*ImportFriendReq) ProtoMessage() {}
func (*ImportFriendReq) Descriptor() ([]byte, []int) { func (*ImportFriendReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{4} return fileDescriptor_friend_2a356ccaa517dcdd, []int{4}
} }
func (m *ImportFriendReq) XXX_Unmarshal(b []byte) error { func (m *ImportFriendReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ImportFriendReq.Unmarshal(m, b) return xxx_messageInfo_ImportFriendReq.Unmarshal(m, b)
@ -256,7 +264,7 @@ func (m *ImportFriendResp) Reset() { *m = ImportFriendResp{} }
func (m *ImportFriendResp) String() string { return proto.CompactTextString(m) } func (m *ImportFriendResp) String() string { return proto.CompactTextString(m) }
func (*ImportFriendResp) ProtoMessage() {} func (*ImportFriendResp) ProtoMessage() {}
func (*ImportFriendResp) Descriptor() ([]byte, []int) { func (*ImportFriendResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{5} return fileDescriptor_friend_2a356ccaa517dcdd, []int{5}
} }
func (m *ImportFriendResp) XXX_Unmarshal(b []byte) error { func (m *ImportFriendResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ImportFriendResp.Unmarshal(m, b) return xxx_messageInfo_ImportFriendResp.Unmarshal(m, b)
@ -288,7 +296,7 @@ func (m *GetPaginationFriendsApplyToReq) Reset() { *m = GetPaginationFri
func (m *GetPaginationFriendsApplyToReq) String() string { return proto.CompactTextString(m) } func (m *GetPaginationFriendsApplyToReq) String() string { return proto.CompactTextString(m) }
func (*GetPaginationFriendsApplyToReq) ProtoMessage() {} func (*GetPaginationFriendsApplyToReq) ProtoMessage() {}
func (*GetPaginationFriendsApplyToReq) Descriptor() ([]byte, []int) { func (*GetPaginationFriendsApplyToReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{6} return fileDescriptor_friend_2a356ccaa517dcdd, []int{6}
} }
func (m *GetPaginationFriendsApplyToReq) XXX_Unmarshal(b []byte) error { func (m *GetPaginationFriendsApplyToReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationFriendsApplyToReq.Unmarshal(m, b) return xxx_messageInfo_GetPaginationFriendsApplyToReq.Unmarshal(m, b)
@ -334,7 +342,7 @@ func (m *GetPaginationFriendsApplyToResp) Reset() { *m = GetPaginationFr
func (m *GetPaginationFriendsApplyToResp) String() string { return proto.CompactTextString(m) } func (m *GetPaginationFriendsApplyToResp) String() string { return proto.CompactTextString(m) }
func (*GetPaginationFriendsApplyToResp) ProtoMessage() {} func (*GetPaginationFriendsApplyToResp) ProtoMessage() {}
func (*GetPaginationFriendsApplyToResp) Descriptor() ([]byte, []int) { func (*GetPaginationFriendsApplyToResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{7} return fileDescriptor_friend_2a356ccaa517dcdd, []int{7}
} }
func (m *GetPaginationFriendsApplyToResp) XXX_Unmarshal(b []byte) error { func (m *GetPaginationFriendsApplyToResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationFriendsApplyToResp.Unmarshal(m, b) return xxx_messageInfo_GetPaginationFriendsApplyToResp.Unmarshal(m, b)
@ -369,18 +377,18 @@ func (m *GetPaginationFriendsApplyToResp) GetTotal() int32 {
} }
type GetDesignatedFriendsReq struct { type GetDesignatedFriendsReq struct {
Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination" json:"pagination,omitempty"` OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID" json:"ownerUserID,omitempty"`
UserID string `protobuf:"bytes,2,opt,name=userID" json:"userID,omitempty"` FriendUserIDs []string `protobuf:"bytes,2,rep,name=friendUserIDs" json:"friendUserIDs,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
func (m *GetDesignatedFriendsReq) Reset() { *m = GetDesignatedFriendsReq{} } func (m *GetDesignatedFriendsReq) Reset() { *m = GetDesignatedFriendsReq{} }
func (m *GetDesignatedFriendsReq) String() string { return proto.CompactTextString(m) } func (m *GetDesignatedFriendsReq) String() string { return proto.CompactTextString(m) }
func (*GetDesignatedFriendsReq) ProtoMessage() {} func (*GetDesignatedFriendsReq) ProtoMessage() {}
func (*GetDesignatedFriendsReq) Descriptor() ([]byte, []int) { func (*GetDesignatedFriendsReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{8} return fileDescriptor_friend_2a356ccaa517dcdd, []int{8}
} }
func (m *GetDesignatedFriendsReq) XXX_Unmarshal(b []byte) error { func (m *GetDesignatedFriendsReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetDesignatedFriendsReq.Unmarshal(m, b) return xxx_messageInfo_GetDesignatedFriendsReq.Unmarshal(m, b)
@ -400,23 +408,22 @@ func (m *GetDesignatedFriendsReq) XXX_DiscardUnknown() {
var xxx_messageInfo_GetDesignatedFriendsReq proto.InternalMessageInfo var xxx_messageInfo_GetDesignatedFriendsReq proto.InternalMessageInfo
func (m *GetDesignatedFriendsReq) GetPagination() *sdkws.RequestPagination { func (m *GetDesignatedFriendsReq) GetOwnerUserID() string {
if m != nil { if m != nil {
return m.Pagination return m.OwnerUserID
}
return nil
}
func (m *GetDesignatedFriendsReq) GetUserID() string {
if m != nil {
return m.UserID
} }
return "" return ""
} }
func (m *GetDesignatedFriendsReq) GetFriendUserIDs() []string {
if m != nil {
return m.FriendUserIDs
}
return nil
}
type GetDesignatedFriendsResp struct { type GetDesignatedFriendsResp struct {
FriendsInfo []*sdkws.FriendInfo `protobuf:"bytes,1,rep,name=FriendsInfo" json:"FriendsInfo,omitempty"` FriendsInfo []*sdkws.FriendInfo `protobuf:"bytes,1,rep,name=friendsInfo" json:"friendsInfo,omitempty"`
Total int32 `protobuf:"varint,2,opt,name=total" json:"total,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -426,7 +433,7 @@ func (m *GetDesignatedFriendsResp) Reset() { *m = GetDesignatedFriendsRe
func (m *GetDesignatedFriendsResp) String() string { return proto.CompactTextString(m) } func (m *GetDesignatedFriendsResp) String() string { return proto.CompactTextString(m) }
func (*GetDesignatedFriendsResp) ProtoMessage() {} func (*GetDesignatedFriendsResp) ProtoMessage() {}
func (*GetDesignatedFriendsResp) Descriptor() ([]byte, []int) { func (*GetDesignatedFriendsResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{9} return fileDescriptor_friend_2a356ccaa517dcdd, []int{9}
} }
func (m *GetDesignatedFriendsResp) XXX_Unmarshal(b []byte) error { func (m *GetDesignatedFriendsResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetDesignatedFriendsResp.Unmarshal(m, b) return xxx_messageInfo_GetDesignatedFriendsResp.Unmarshal(m, b)
@ -453,13 +460,6 @@ func (m *GetDesignatedFriendsResp) GetFriendsInfo() []*sdkws.FriendInfo {
return nil return nil
} }
func (m *GetDesignatedFriendsResp) GetTotal() int32 {
if m != nil {
return m.Total
}
return 0
}
type AddBlackReq struct { type AddBlackReq struct {
OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID" json:"ownerUserID,omitempty"` OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID" json:"ownerUserID,omitempty"`
BlackUserID string `protobuf:"bytes,2,opt,name=blackUserID" json:"blackUserID,omitempty"` BlackUserID string `protobuf:"bytes,2,opt,name=blackUserID" json:"blackUserID,omitempty"`
@ -472,7 +472,7 @@ func (m *AddBlackReq) Reset() { *m = AddBlackReq{} }
func (m *AddBlackReq) String() string { return proto.CompactTextString(m) } func (m *AddBlackReq) String() string { return proto.CompactTextString(m) }
func (*AddBlackReq) ProtoMessage() {} func (*AddBlackReq) ProtoMessage() {}
func (*AddBlackReq) Descriptor() ([]byte, []int) { func (*AddBlackReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{10} return fileDescriptor_friend_2a356ccaa517dcdd, []int{10}
} }
func (m *AddBlackReq) XXX_Unmarshal(b []byte) error { func (m *AddBlackReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddBlackReq.Unmarshal(m, b) return xxx_messageInfo_AddBlackReq.Unmarshal(m, b)
@ -516,7 +516,7 @@ func (m *AddBlackResp) Reset() { *m = AddBlackResp{} }
func (m *AddBlackResp) String() string { return proto.CompactTextString(m) } func (m *AddBlackResp) String() string { return proto.CompactTextString(m) }
func (*AddBlackResp) ProtoMessage() {} func (*AddBlackResp) ProtoMessage() {}
func (*AddBlackResp) Descriptor() ([]byte, []int) { func (*AddBlackResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{11} return fileDescriptor_friend_2a356ccaa517dcdd, []int{11}
} }
func (m *AddBlackResp) XXX_Unmarshal(b []byte) error { func (m *AddBlackResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddBlackResp.Unmarshal(m, b) return xxx_messageInfo_AddBlackResp.Unmarshal(m, b)
@ -548,7 +548,7 @@ func (m *RemoveBlackReq) Reset() { *m = RemoveBlackReq{} }
func (m *RemoveBlackReq) String() string { return proto.CompactTextString(m) } func (m *RemoveBlackReq) String() string { return proto.CompactTextString(m) }
func (*RemoveBlackReq) ProtoMessage() {} func (*RemoveBlackReq) ProtoMessage() {}
func (*RemoveBlackReq) Descriptor() ([]byte, []int) { func (*RemoveBlackReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{12} return fileDescriptor_friend_2a356ccaa517dcdd, []int{12}
} }
func (m *RemoveBlackReq) XXX_Unmarshal(b []byte) error { func (m *RemoveBlackReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RemoveBlackReq.Unmarshal(m, b) return xxx_messageInfo_RemoveBlackReq.Unmarshal(m, b)
@ -592,7 +592,7 @@ func (m *RemoveBlackResp) Reset() { *m = RemoveBlackResp{} }
func (m *RemoveBlackResp) String() string { return proto.CompactTextString(m) } func (m *RemoveBlackResp) String() string { return proto.CompactTextString(m) }
func (*RemoveBlackResp) ProtoMessage() {} func (*RemoveBlackResp) ProtoMessage() {}
func (*RemoveBlackResp) Descriptor() ([]byte, []int) { func (*RemoveBlackResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{13} return fileDescriptor_friend_2a356ccaa517dcdd, []int{13}
} }
func (m *RemoveBlackResp) XXX_Unmarshal(b []byte) error { func (m *RemoveBlackResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RemoveBlackResp.Unmarshal(m, b) return xxx_messageInfo_RemoveBlackResp.Unmarshal(m, b)
@ -624,7 +624,7 @@ func (m *GetPaginationBlacksReq) Reset() { *m = GetPaginationBlacksReq{}
func (m *GetPaginationBlacksReq) String() string { return proto.CompactTextString(m) } func (m *GetPaginationBlacksReq) String() string { return proto.CompactTextString(m) }
func (*GetPaginationBlacksReq) ProtoMessage() {} func (*GetPaginationBlacksReq) ProtoMessage() {}
func (*GetPaginationBlacksReq) Descriptor() ([]byte, []int) { func (*GetPaginationBlacksReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{14} return fileDescriptor_friend_2a356ccaa517dcdd, []int{14}
} }
func (m *GetPaginationBlacksReq) XXX_Unmarshal(b []byte) error { func (m *GetPaginationBlacksReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationBlacksReq.Unmarshal(m, b) return xxx_messageInfo_GetPaginationBlacksReq.Unmarshal(m, b)
@ -670,7 +670,7 @@ func (m *GetPaginationBlacksResp) Reset() { *m = GetPaginationBlacksResp
func (m *GetPaginationBlacksResp) String() string { return proto.CompactTextString(m) } func (m *GetPaginationBlacksResp) String() string { return proto.CompactTextString(m) }
func (*GetPaginationBlacksResp) ProtoMessage() {} func (*GetPaginationBlacksResp) ProtoMessage() {}
func (*GetPaginationBlacksResp) Descriptor() ([]byte, []int) { func (*GetPaginationBlacksResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{15} return fileDescriptor_friend_2a356ccaa517dcdd, []int{15}
} }
func (m *GetPaginationBlacksResp) XXX_Unmarshal(b []byte) error { func (m *GetPaginationBlacksResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationBlacksResp.Unmarshal(m, b) return xxx_messageInfo_GetPaginationBlacksResp.Unmarshal(m, b)
@ -716,7 +716,7 @@ func (m *IsFriendReq) Reset() { *m = IsFriendReq{} }
func (m *IsFriendReq) String() string { return proto.CompactTextString(m) } func (m *IsFriendReq) String() string { return proto.CompactTextString(m) }
func (*IsFriendReq) ProtoMessage() {} func (*IsFriendReq) ProtoMessage() {}
func (*IsFriendReq) Descriptor() ([]byte, []int) { func (*IsFriendReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{16} return fileDescriptor_friend_2a356ccaa517dcdd, []int{16}
} }
func (m *IsFriendReq) XXX_Unmarshal(b []byte) error { func (m *IsFriendReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IsFriendReq.Unmarshal(m, b) return xxx_messageInfo_IsFriendReq.Unmarshal(m, b)
@ -762,7 +762,7 @@ func (m *IsFriendResp) Reset() { *m = IsFriendResp{} }
func (m *IsFriendResp) String() string { return proto.CompactTextString(m) } func (m *IsFriendResp) String() string { return proto.CompactTextString(m) }
func (*IsFriendResp) ProtoMessage() {} func (*IsFriendResp) ProtoMessage() {}
func (*IsFriendResp) Descriptor() ([]byte, []int) { func (*IsFriendResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{17} return fileDescriptor_friend_2a356ccaa517dcdd, []int{17}
} }
func (m *IsFriendResp) XXX_Unmarshal(b []byte) error { func (m *IsFriendResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IsFriendResp.Unmarshal(m, b) return xxx_messageInfo_IsFriendResp.Unmarshal(m, b)
@ -808,7 +808,7 @@ func (m *IsBlackReq) Reset() { *m = IsBlackReq{} }
func (m *IsBlackReq) String() string { return proto.CompactTextString(m) } func (m *IsBlackReq) String() string { return proto.CompactTextString(m) }
func (*IsBlackReq) ProtoMessage() {} func (*IsBlackReq) ProtoMessage() {}
func (*IsBlackReq) Descriptor() ([]byte, []int) { func (*IsBlackReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{18} return fileDescriptor_friend_2a356ccaa517dcdd, []int{18}
} }
func (m *IsBlackReq) XXX_Unmarshal(b []byte) error { func (m *IsBlackReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IsBlackReq.Unmarshal(m, b) return xxx_messageInfo_IsBlackReq.Unmarshal(m, b)
@ -854,7 +854,7 @@ func (m *IsBlackResp) Reset() { *m = IsBlackResp{} }
func (m *IsBlackResp) String() string { return proto.CompactTextString(m) } func (m *IsBlackResp) String() string { return proto.CompactTextString(m) }
func (*IsBlackResp) ProtoMessage() {} func (*IsBlackResp) ProtoMessage() {}
func (*IsBlackResp) Descriptor() ([]byte, []int) { func (*IsBlackResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{19} return fileDescriptor_friend_2a356ccaa517dcdd, []int{19}
} }
func (m *IsBlackResp) XXX_Unmarshal(b []byte) error { func (m *IsBlackResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IsBlackResp.Unmarshal(m, b) return xxx_messageInfo_IsBlackResp.Unmarshal(m, b)
@ -900,7 +900,7 @@ func (m *DeleteFriendReq) Reset() { *m = DeleteFriendReq{} }
func (m *DeleteFriendReq) String() string { return proto.CompactTextString(m) } func (m *DeleteFriendReq) String() string { return proto.CompactTextString(m) }
func (*DeleteFriendReq) ProtoMessage() {} func (*DeleteFriendReq) ProtoMessage() {}
func (*DeleteFriendReq) Descriptor() ([]byte, []int) { func (*DeleteFriendReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{20} return fileDescriptor_friend_2a356ccaa517dcdd, []int{20}
} }
func (m *DeleteFriendReq) XXX_Unmarshal(b []byte) error { func (m *DeleteFriendReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteFriendReq.Unmarshal(m, b) return xxx_messageInfo_DeleteFriendReq.Unmarshal(m, b)
@ -944,7 +944,7 @@ func (m *DeleteFriendResp) Reset() { *m = DeleteFriendResp{} }
func (m *DeleteFriendResp) String() string { return proto.CompactTextString(m) } func (m *DeleteFriendResp) String() string { return proto.CompactTextString(m) }
func (*DeleteFriendResp) ProtoMessage() {} func (*DeleteFriendResp) ProtoMessage() {}
func (*DeleteFriendResp) Descriptor() ([]byte, []int) { func (*DeleteFriendResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{21} return fileDescriptor_friend_2a356ccaa517dcdd, []int{21}
} }
func (m *DeleteFriendResp) XXX_Unmarshal(b []byte) error { func (m *DeleteFriendResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteFriendResp.Unmarshal(m, b) return xxx_messageInfo_DeleteFriendResp.Unmarshal(m, b)
@ -979,7 +979,7 @@ func (m *RespondFriendApplyReq) Reset() { *m = RespondFriendApplyReq{} }
func (m *RespondFriendApplyReq) String() string { return proto.CompactTextString(m) } func (m *RespondFriendApplyReq) String() string { return proto.CompactTextString(m) }
func (*RespondFriendApplyReq) ProtoMessage() {} func (*RespondFriendApplyReq) ProtoMessage() {}
func (*RespondFriendApplyReq) Descriptor() ([]byte, []int) { func (*RespondFriendApplyReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{22} return fileDescriptor_friend_2a356ccaa517dcdd, []int{22}
} }
func (m *RespondFriendApplyReq) XXX_Unmarshal(b []byte) error { func (m *RespondFriendApplyReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RespondFriendApplyReq.Unmarshal(m, b) return xxx_messageInfo_RespondFriendApplyReq.Unmarshal(m, b)
@ -1037,7 +1037,7 @@ func (m *RespondFriendApplyResp) Reset() { *m = RespondFriendApplyResp{}
func (m *RespondFriendApplyResp) String() string { return proto.CompactTextString(m) } func (m *RespondFriendApplyResp) String() string { return proto.CompactTextString(m) }
func (*RespondFriendApplyResp) ProtoMessage() {} func (*RespondFriendApplyResp) ProtoMessage() {}
func (*RespondFriendApplyResp) Descriptor() ([]byte, []int) { func (*RespondFriendApplyResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{23} return fileDescriptor_friend_2a356ccaa517dcdd, []int{23}
} }
func (m *RespondFriendApplyResp) XXX_Unmarshal(b []byte) error { func (m *RespondFriendApplyResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RespondFriendApplyResp.Unmarshal(m, b) return xxx_messageInfo_RespondFriendApplyResp.Unmarshal(m, b)
@ -1070,7 +1070,7 @@ func (m *SetFriendRemarkReq) Reset() { *m = SetFriendRemarkReq{} }
func (m *SetFriendRemarkReq) String() string { return proto.CompactTextString(m) } func (m *SetFriendRemarkReq) String() string { return proto.CompactTextString(m) }
func (*SetFriendRemarkReq) ProtoMessage() {} func (*SetFriendRemarkReq) ProtoMessage() {}
func (*SetFriendRemarkReq) Descriptor() ([]byte, []int) { func (*SetFriendRemarkReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{24} return fileDescriptor_friend_2a356ccaa517dcdd, []int{24}
} }
func (m *SetFriendRemarkReq) XXX_Unmarshal(b []byte) error { func (m *SetFriendRemarkReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SetFriendRemarkReq.Unmarshal(m, b) return xxx_messageInfo_SetFriendRemarkReq.Unmarshal(m, b)
@ -1121,7 +1121,7 @@ func (m *SetFriendRemarkResp) Reset() { *m = SetFriendRemarkResp{} }
func (m *SetFriendRemarkResp) String() string { return proto.CompactTextString(m) } func (m *SetFriendRemarkResp) String() string { return proto.CompactTextString(m) }
func (*SetFriendRemarkResp) ProtoMessage() {} func (*SetFriendRemarkResp) ProtoMessage() {}
func (*SetFriendRemarkResp) Descriptor() ([]byte, []int) { func (*SetFriendRemarkResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{25} return fileDescriptor_friend_2a356ccaa517dcdd, []int{25}
} }
func (m *SetFriendRemarkResp) XXX_Unmarshal(b []byte) error { func (m *SetFriendRemarkResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SetFriendRemarkResp.Unmarshal(m, b) return xxx_messageInfo_SetFriendRemarkResp.Unmarshal(m, b)
@ -1153,7 +1153,7 @@ func (m *GetPaginationFriendsApplyFromReq) Reset() { *m = GetPaginationF
func (m *GetPaginationFriendsApplyFromReq) String() string { return proto.CompactTextString(m) } func (m *GetPaginationFriendsApplyFromReq) String() string { return proto.CompactTextString(m) }
func (*GetPaginationFriendsApplyFromReq) ProtoMessage() {} func (*GetPaginationFriendsApplyFromReq) ProtoMessage() {}
func (*GetPaginationFriendsApplyFromReq) Descriptor() ([]byte, []int) { func (*GetPaginationFriendsApplyFromReq) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{26} return fileDescriptor_friend_2a356ccaa517dcdd, []int{26}
} }
func (m *GetPaginationFriendsApplyFromReq) XXX_Unmarshal(b []byte) error { func (m *GetPaginationFriendsApplyFromReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationFriendsApplyFromReq.Unmarshal(m, b) return xxx_messageInfo_GetPaginationFriendsApplyFromReq.Unmarshal(m, b)
@ -1199,7 +1199,7 @@ func (m *GetPaginationFriendsApplyFromResp) Reset() { *m = GetPagination
func (m *GetPaginationFriendsApplyFromResp) String() string { return proto.CompactTextString(m) } func (m *GetPaginationFriendsApplyFromResp) String() string { return proto.CompactTextString(m) }
func (*GetPaginationFriendsApplyFromResp) ProtoMessage() {} func (*GetPaginationFriendsApplyFromResp) ProtoMessage() {}
func (*GetPaginationFriendsApplyFromResp) Descriptor() ([]byte, []int) { func (*GetPaginationFriendsApplyFromResp) Descriptor() ([]byte, []int) {
return fileDescriptor_friend_80e3d7661e2d6b50, []int{27} return fileDescriptor_friend_2a356ccaa517dcdd, []int{27}
} }
func (m *GetPaginationFriendsApplyFromResp) XXX_Unmarshal(b []byte) error { func (m *GetPaginationFriendsApplyFromResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetPaginationFriendsApplyFromResp.Unmarshal(m, b) return xxx_messageInfo_GetPaginationFriendsApplyFromResp.Unmarshal(m, b)
@ -1793,68 +1793,68 @@ var _Friend_serviceDesc = grpc.ServiceDesc{
Metadata: "friend/friend.proto", Metadata: "friend/friend.proto",
} }
func init() { proto.RegisterFile("friend/friend.proto", fileDescriptor_friend_80e3d7661e2d6b50) } func init() { proto.RegisterFile("friend/friend.proto", fileDescriptor_friend_2a356ccaa517dcdd) }
var fileDescriptor_friend_80e3d7661e2d6b50 = []byte{ var fileDescriptor_friend_2a356ccaa517dcdd = []byte{
// 955 bytes of a gzipped FileDescriptorProto // 957 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xe1, 0x6e, 0xdb, 0x36, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xe1, 0x6e, 0xdb, 0x46,
0x10, 0x86, 0x9d, 0xc5, 0x4d, 0xce, 0xae, 0x93, 0x9e, 0x5d, 0x57, 0x50, 0xda, 0xc4, 0x25, 0x86, 0x0c, 0x86, 0x9d, 0x25, 0x4d, 0x68, 0xd7, 0x49, 0x69, 0xd7, 0x15, 0x94, 0x36, 0x71, 0x0f, 0x43,
0xd6, 0xfb, 0xd1, 0x18, 0x75, 0x31, 0x60, 0xc0, 0x86, 0x61, 0x09, 0x8a, 0x00, 0x19, 0x10, 0x74, 0xeb, 0xfd, 0x68, 0x8c, 0xba, 0x18, 0x30, 0x60, 0xc3, 0xb0, 0x04, 0x45, 0x81, 0x0c, 0x08, 0xba,
0x53, 0xbb, 0x0d, 0xd9, 0x8f, 0x0d, 0xea, 0x44, 0x7b, 0x9e, 0x6d, 0x89, 0xd1, 0x29, 0x75, 0xfb, 0xa9, 0xed, 0x86, 0xec, 0xc7, 0x06, 0x75, 0x3a, 0x7b, 0x9e, 0x6d, 0xe9, 0x22, 0x2a, 0x4d, 0xfb,
0x20, 0x7b, 0xb4, 0xbd, 0xcf, 0x20, 0x92, 0x92, 0x28, 0x59, 0x56, 0xdd, 0x2d, 0xf9, 0x65, 0xf0, 0x20, 0x7b, 0xb4, 0xbd, 0xcf, 0xa0, 0xbb, 0x93, 0xee, 0x24, 0xcb, 0xae, 0xbb, 0x26, 0xbf, 0x0c,
0xee, 0xe3, 0xdd, 0xf1, 0x78, 0xfe, 0x3e, 0x0a, 0x3a, 0xe3, 0x70, 0xca, 0x7d, 0x6f, 0xa8, 0x7e, 0x92, 0xdf, 0x91, 0x3c, 0x92, 0xfa, 0x78, 0x86, 0xf6, 0x28, 0x9e, 0xf0, 0x30, 0x18, 0xa8, 0x9f,
0x8e, 0x45, 0x18, 0x44, 0x01, 0x36, 0xd4, 0xca, 0x7e, 0xfa, 0x4a, 0x70, 0xff, 0xd9, 0xf9, 0xc5, 0x23, 0x11, 0x47, 0x49, 0x84, 0x5b, 0x4a, 0x72, 0x1f, 0xbf, 0x14, 0x3c, 0x7c, 0x72, 0x7a, 0xf6,
0xb3, 0xd7, 0x3c, 0x7c, 0xc7, 0xc3, 0xa1, 0x98, 0x4d, 0x86, 0x12, 0x31, 0x24, 0x6f, 0xb6, 0xa4, 0xe4, 0x15, 0x8f, 0xdf, 0xf1, 0x78, 0x20, 0xa6, 0xe3, 0x81, 0x44, 0x0c, 0x28, 0x98, 0x5e, 0xd1,
0xe1, 0x92, 0xd4, 0x06, 0xe6, 0xc2, 0x83, 0x09, 0x8f, 0x7e, 0x70, 0x27, 0x53, 0xdf, 0x8d, 0xa6, 0xe0, 0x8a, 0xd4, 0x01, 0x36, 0x85, 0x7b, 0x63, 0x9e, 0xfc, 0xe4, 0x8f, 0x27, 0xa1, 0x9f, 0x4c,
0x81, 0x7f, 0x26, 0xf7, 0x93, 0xc3, 0xaf, 0xb0, 0x0f, 0xcd, 0x60, 0xe9, 0xf3, 0xf0, 0x27, 0xe2, 0xa2, 0xf0, 0x85, 0x3c, 0x4f, 0x1e, 0xbf, 0xc0, 0x6f, 0x00, 0x44, 0xae, 0x77, 0x6a, 0xbd, 0x5a,
0xe1, 0xf9, 0x4b, 0xab, 0xd6, 0xaf, 0x0d, 0x76, 0x1d, 0xd3, 0x84, 0x9f, 0xc3, 0x5d, 0x95, 0x4f, 0xbf, 0x31, 0x74, 0x8e, 0xe4, 0xf9, 0x23, 0x8f, 0x5f, 0x5c, 0x72, 0xb2, 0xce, 0x79, 0x16, 0x16,
0xad, 0xc9, 0xaa, 0xf7, 0xb7, 0x06, 0xbb, 0x4e, 0xde, 0xc8, 0x5e, 0x81, 0x55, 0x9e, 0x82, 0x04, 0xbb, 0xb0, 0x75, 0x49, 0x3c, 0x3e, 0x7d, 0xee, 0xd4, 0x7b, 0xb5, 0xfe, 0x8e, 0xa7, 0x25, 0xc6,
0xbe, 0x80, 0xa6, 0x02, 0xd3, 0xb9, 0x3f, 0x0e, 0xac, 0x5a, 0x7f, 0x6b, 0xd0, 0x1c, 0xdd, 0x3b, 0xc1, 0xa9, 0x0e, 0x46, 0x02, 0x9f, 0x41, 0x43, 0x8b, 0xa7, 0xe1, 0x28, 0x72, 0x6a, 0xbd, 0x8d,
0x96, 0x45, 0x1e, 0x2b, 0x60, 0xec, 0x70, 0x4c, 0x14, 0xfb, 0x00, 0x1d, 0x57, 0x88, 0xf9, 0x87, 0x7e, 0x63, 0x78, 0x47, 0x87, 0x53, 0x96, 0xd4, 0xe0, 0xd9, 0x28, 0xec, 0xc0, 0x66, 0x12, 0x25,
0x37, 0xc1, 0x89, 0xe7, 0x29, 0x50, 0x5c, 0xef, 0x21, 0xc0, 0x38, 0x0c, 0x16, 0xb9, 0x72, 0x0d, 0xfe, 0x4c, 0xc6, 0xd9, 0xf4, 0x94, 0xc0, 0x3e, 0x40, 0xdb, 0x17, 0x62, 0xf6, 0xe1, 0x75, 0x74,
0x0b, 0xda, 0xb0, 0x13, 0x05, 0xda, 0x5b, 0x97, 0xde, 0x74, 0x8d, 0x3d, 0x68, 0x84, 0xfc, 0xea, 0x1c, 0x04, 0x0a, 0x9e, 0xde, 0xe7, 0x00, 0x60, 0x14, 0x47, 0xf3, 0x37, 0x2a, 0xb3, 0x9a, 0xcc,
0x82, 0x26, 0xd6, 0x96, 0xf4, 0xe8, 0x15, 0xb6, 0xa1, 0xce, 0xdf, 0x5b, 0x9f, 0x49, 0x5b, 0x9d, 0xcc, 0xd2, 0xa0, 0x0b, 0xdb, 0x49, 0xf4, 0xc6, 0xce, 0x3b, 0x97, 0xd3, 0x1b, 0xc5, 0xfc, 0xe2,
0xbf, 0x67, 0x3d, 0xe8, 0xae, 0xa6, 0x26, 0xc1, 0x2e, 0x61, 0x6f, 0xba, 0x10, 0x41, 0x18, 0x65, 0x8c, 0xc6, 0xce, 0x86, 0xba, 0x91, 0x92, 0xb0, 0x05, 0x75, 0xfe, 0xde, 0xf9, 0x42, 0xea, 0xea,
0xe5, 0xdc, 0x54, 0xfb, 0x10, 0xf6, 0xf3, 0xa1, 0x49, 0xb0, 0x10, 0x0e, 0xcb, 0x5a, 0x7a, 0xa2, 0xfc, 0x3d, 0xeb, 0x42, 0x67, 0x31, 0x34, 0x09, 0x76, 0x0e, 0xbb, 0x93, 0xb9, 0x88, 0xe2, 0xc4,
0x4a, 0x8b, 0xb3, 0xf7, 0xa0, 0x71, 0x6d, 0x26, 0xd6, 0x2b, 0xfc, 0x0a, 0x40, 0xa4, 0xdb, 0x64, 0xa4, 0xd3, 0x83, 0x46, 0x74, 0x15, 0xf2, 0xb8, 0x90, 0x8f, 0xad, 0xc2, 0x2f, 0xe1, 0xb6, 0x6a,
0x1b, 0x9a, 0x23, 0x4b, 0xf7, 0xdb, 0xe1, 0x57, 0xd7, 0x9c, 0x8c, 0xb0, 0x8e, 0x81, 0x65, 0xd7, 0xa7, 0x92, 0xc9, 0xa9, 0xf7, 0x36, 0xfa, 0x3b, 0x5e, 0x51, 0xc9, 0x10, 0xf6, 0x8a, 0xae, 0x49,
0x70, 0x54, 0x99, 0x93, 0x04, 0x7e, 0x03, 0xed, 0xf4, 0xfc, 0x71, 0x24, 0xd2, 0x17, 0xda, 0xcd, 0xb0, 0x18, 0x0e, 0xaa, 0x0a, 0x7d, 0xac, 0x52, 0x4b, 0xa3, 0x9b, 0x16, 0xd5, 0xec, 0x16, 0x95,
0x5d, 0xa8, 0x76, 0x3a, 0x05, 0x2c, 0x76, 0x61, 0x3b, 0x0a, 0x22, 0x77, 0x2e, 0xab, 0xda, 0x76, 0x9a, 0x5e, 0x5f, 0xbf, 0xe9, 0xec, 0x12, 0x0e, 0x57, 0xc6, 0x24, 0x81, 0xdf, 0x41, 0x2b, 0xbf,
0xd4, 0x82, 0xcd, 0xe4, 0x80, 0xbe, 0xe4, 0x34, 0x9d, 0xf8, 0x6e, 0xc4, 0x3d, 0x63, 0x40, 0xf3, 0x7f, 0xea, 0x89, 0x74, 0x9b, 0x3b, 0x85, 0x36, 0x6b, 0xa3, 0x57, 0xc2, 0x2e, 0x69, 0xb6, 0x2f,
0x67, 0xa9, 0x6d, 0x7e, 0x16, 0xa3, 0x3b, 0x75, 0xb3, 0x3b, 0x8c, 0xcb, 0x51, 0x2d, 0x49, 0xa6, 0x07, 0xf8, 0x39, 0xa7, 0xc9, 0x38, 0xf4, 0x13, 0x1e, 0x58, 0x03, 0x7c, 0x5d, 0x15, 0x7e, 0x29,
0x46, 0xf5, 0x6c, 0xa3, 0x51, 0x35, 0x50, 0x6b, 0xce, 0xf4, 0x23, 0x34, 0x5d, 0xcf, 0x3b, 0x9d, 0xc7, 0xb6, 0x22, 0x84, 0x1a, 0xdb, 0xd1, 0x5a, 0x63, 0x6b, 0xa1, 0xd8, 0xcf, 0xd0, 0xf0, 0x83,
0xbb, 0x7f, 0xcc, 0x36, 0x9b, 0x94, 0x3e, 0x34, 0xdf, 0xc6, 0xe8, 0xdc, 0xf4, 0x9a, 0x26, 0xd6, 0xe0, 0x64, 0xe6, 0xff, 0x39, 0x5d, 0x2f, 0xcf, 0x1e, 0x34, 0xde, 0xa6, 0xe8, 0xc2, 0x74, 0xda,
0x86, 0x56, 0x16, 0x92, 0x04, 0x7b, 0x03, 0xed, 0x90, 0x2f, 0x82, 0x77, 0xfc, 0x46, 0xb3, 0xdc, 0x2a, 0xd6, 0x82, 0xa6, 0x71, 0x49, 0x82, 0xbd, 0x86, 0x56, 0xcc, 0xe7, 0xd1, 0x3b, 0x7e, 0xad,
0x83, 0xbd, 0x5c, 0x54, 0x12, 0xec, 0x2f, 0xe8, 0xe5, 0xc6, 0x42, 0x7a, 0xe8, 0x76, 0x46, 0xf0, 0x51, 0xee, 0xc0, 0x6e, 0xc1, 0x2b, 0x09, 0xf6, 0x37, 0x74, 0x0b, 0x6d, 0x97, 0x16, 0xba, 0x99,
0xb2, 0x40, 0x56, 0x49, 0x2e, 0x12, 0x38, 0x80, 0x86, 0x2c, 0x34, 0x19, 0xb9, 0x7d, 0x1d, 0x50, 0x11, 0x3b, 0x2f, 0x91, 0x55, 0x16, 0x8b, 0x04, 0xf6, 0x61, 0x4b, 0x26, 0x9a, 0x8d, 0xd4, 0x9e,
0x42, 0xe4, 0xbd, 0x68, 0xff, 0x9a, 0x2b, 0x39, 0x81, 0xe6, 0x94, 0xb2, 0x3f, 0xaf, 0x05, 0x77, 0x76, 0x28, 0x21, 0xb2, 0x03, 0xda, 0xbe, 0x64, 0x8c, 0x8e, 0xa1, 0x31, 0x21, 0xf3, 0x71, 0x3a,
0x54, 0xb5, 0xcf, 0x75, 0xf1, 0xc9, 0x32, 0xf3, 0x8c, 0x74, 0x83, 0x92, 0x25, 0xfb, 0x0d, 0x5a, 0x70, 0x4b, 0x65, 0xfb, 0x54, 0x27, 0x9f, 0x89, 0xc6, 0x32, 0xd4, 0x05, 0xca, 0x44, 0xf6, 0x3b,
0x59, 0x08, 0x12, 0xf8, 0x04, 0xda, 0x53, 0x3f, 0x6e, 0xdc, 0x73, 0x3d, 0x11, 0x32, 0xd4, 0x8e, 0x34, 0x8d, 0x0b, 0x12, 0xf8, 0x08, 0x5a, 0x93, 0x30, 0x2d, 0xdc, 0x53, 0x3d, 0x30, 0xd2, 0xd5,
0x53, 0xb0, 0x66, 0xb8, 0x51, 0x82, 0xab, 0x9b, 0xb8, 0xc4, 0xca, 0xbe, 0x03, 0x98, 0x52, 0x7a, 0xb6, 0x57, 0xd2, 0x1a, 0xdc, 0x30, 0xc3, 0xd5, 0x6d, 0x5c, 0xa6, 0x65, 0x3f, 0x00, 0x4c, 0x28,
0x9d, 0xff, 0xa5, 0xc2, 0xcb, 0xf8, 0x90, 0xe9, 0xd5, 0xc5, 0xfc, 0xa3, 0x4b, 0x39, 0x4d, 0x5a, 0x6f, 0xe7, 0xff, 0xc9, 0xf0, 0x3c, 0xbd, 0x64, 0xde, 0xba, 0x74, 0xfa, 0x75, 0x2a, 0x27, 0x59,
0x17, 0xe7, 0xcd, 0x1b, 0x33, 0xd4, 0x48, 0xa3, 0xea, 0x26, 0x4a, 0x1b, 0xd9, 0x2f, 0xb0, 0xe7, 0xe9, 0xd2, 0xb8, 0x45, 0xa5, 0x41, 0x0d, 0x35, 0xaa, 0x6e, 0xa3, 0xb4, 0x92, 0xfd, 0x0a, 0xbb,
0xf1, 0x39, 0x8f, 0xf8, 0xa7, 0x10, 0x20, 0x83, 0x96, 0xc9, 0x75, 0xba, 0xdc, 0x9c, 0x2d, 0xa6, 0x01, 0x9f, 0xf1, 0x84, 0x7f, 0x0a, 0xc1, 0x31, 0x68, 0xda, 0x5f, 0x9a, 0x4e, 0xb7, 0xa0, 0x4b,
0xbf, 0x7c, 0x60, 0x12, 0xec, 0xef, 0x1a, 0xdc, 0x0f, 0x39, 0x89, 0xc0, 0xd7, 0xff, 0x50, 0x49, 0xe9, 0xad, 0xe8, 0x98, 0x04, 0xfb, 0xa7, 0x06, 0x77, 0x63, 0x4e, 0x22, 0x0a, 0xf5, 0xb7, 0x28,
0x42, 0xff, 0x57, 0x03, 0x18, 0xb4, 0xfe, 0x74, 0x7d, 0x6f, 0xce, 0x1d, 0x4e, 0xd7, 0xf3, 0x48, 0x49, 0xe6, 0x73, 0x39, 0x9e, 0x41, 0xf3, 0x2f, 0x3f, 0x0c, 0x66, 0xdc, 0xe3, 0x74, 0x39, 0x4b,
0x2a, 0xc1, 0xb6, 0x93, 0xb3, 0xe1, 0x43, 0xd8, 0x55, 0xeb, 0x58, 0x2a, 0x94, 0x2c, 0x64, 0x06, 0x24, 0xd3, 0x6f, 0x7a, 0x05, 0x1d, 0xde, 0x87, 0x1d, 0x25, 0xa7, 0xab, 0x40, 0xd1, 0xbe, 0x51,
0x66, 0x41, 0xaf, 0xac, 0x2c, 0x49, 0xd8, 0x48, 0x3c, 0x65, 0xf0, 0x85, 0x1b, 0xce, 0x6e, 0xac, 0x30, 0x07, 0xba, 0x55, 0x69, 0x49, 0x42, 0x46, 0xe2, 0x39, 0x43, 0xcf, 0xfd, 0x78, 0x7a, 0x6d,
0x43, 0x4a, 0xbb, 0xe2, 0x90, 0x99, 0x76, 0xc5, 0x2b, 0x76, 0x1f, 0x3a, 0x2b, 0x39, 0x49, 0xb0, 0x15, 0x52, 0xbb, 0x29, 0x75, 0x69, 0x76, 0x53, 0x2a, 0xb1, 0xbb, 0xd0, 0x5e, 0x88, 0x49, 0x82,
0x08, 0xfa, 0x6b, 0x79, 0xfc, 0x2c, 0x0c, 0x16, 0xb7, 0xf3, 0xd7, 0x5d, 0xc2, 0xe3, 0x8f, 0x64, 0x25, 0xd0, 0x5b, 0xca, 0xd3, 0x2f, 0xe2, 0x68, 0x7e, 0x33, 0x9f, 0xee, 0x15, 0x3c, 0xfc, 0x48,
0x55, 0xfa, 0x31, 0xfe, 0x04, 0xfd, 0x18, 0x6f, 0xa0, 0x1f, 0xa3, 0x7f, 0x76, 0x40, 0x3f, 0x8a, 0x54, 0xb5, 0x1f, 0x46, 0x9f, 0xb0, 0x1f, 0x46, 0x6b, 0xec, 0x87, 0xe1, 0xbf, 0xdb, 0xa0, 0x1f,
0xf0, 0x02, 0xf6, 0x8b, 0xe2, 0x8d, 0x07, 0xc7, 0xfa, 0xfd, 0x54, 0xf2, 0xa2, 0xb0, 0x1f, 0xae, 0x45, 0x78, 0x06, 0x7b, 0xe5, 0xe5, 0x8c, 0xfb, 0x47, 0xfa, 0xfd, 0x54, 0xf1, 0x62, 0x70, 0xef,
0x77, 0x92, 0x40, 0x1f, 0x0e, 0x2a, 0x04, 0x11, 0x9f, 0x24, 0x9b, 0xab, 0x95, 0xda, 0x7e, 0xba, 0x2f, 0x37, 0x92, 0xc0, 0x10, 0xf6, 0x57, 0x2c, 0x3c, 0x7c, 0x94, 0x1d, 0x5e, 0xbd, 0x89, 0xdd,
0x11, 0x8e, 0x04, 0x46, 0xf0, 0xa8, 0xb2, 0x85, 0x38, 0xf8, 0x68, 0x24, 0x7d, 0xbf, 0xf6, 0x17, 0xc7, 0x6b, 0xe1, 0x48, 0x60, 0x02, 0x0f, 0x56, 0x96, 0x10, 0xfb, 0x1f, 0xf5, 0xa4, 0xfb, 0xeb,
0x1b, 0x22, 0x49, 0xe0, 0x97, 0xb0, 0x93, 0x08, 0x0b, 0x76, 0xd2, 0x7e, 0x64, 0xea, 0x65, 0x77, 0x7e, 0xb5, 0x26, 0x92, 0x04, 0x7e, 0x0d, 0xdb, 0xd9, 0x62, 0xc1, 0x76, 0x5e, 0x0f, 0xb3, 0xbd,
0x57, 0x8d, 0x24, 0xf0, 0x5b, 0x68, 0x1a, 0x4a, 0x81, 0xbd, 0x04, 0x94, 0x17, 0x25, 0xfb, 0x41, 0xdc, 0xce, 0xa2, 0x92, 0x04, 0x7e, 0x0f, 0x0d, 0x6b, 0x53, 0x60, 0x37, 0x03, 0x15, 0x97, 0x92,
0xa9, 0x5d, 0xa5, 0x4d, 0xc8, 0x34, 0x4b, 0x6b, 0x30, 0x74, 0x96, 0x36, 0xc7, 0xb9, 0x23, 0xb8, 0x7b, 0xaf, 0x52, 0xaf, 0xc2, 0x66, 0x64, 0x6a, 0xc2, 0x5a, 0x0c, 0x6d, 0xc2, 0x16, 0x38, 0x77,
0xa3, 0x19, 0x0e, 0x31, 0x03, 0xa4, 0xe9, 0x3a, 0x2b, 0x36, 0x12, 0xf8, 0x33, 0x74, 0x4a, 0x54, 0x08, 0xb7, 0x34, 0xc3, 0x21, 0x1a, 0x40, 0x1e, 0xae, 0xbd, 0xa0, 0x23, 0x81, 0xbf, 0x40, 0xbb,
0x05, 0x0f, 0x4b, 0x7b, 0x94, 0xca, 0x9b, 0x7d, 0x54, 0xe9, 0x27, 0x81, 0x27, 0xd0, 0x32, 0x99, 0x62, 0xab, 0xe0, 0x41, 0x65, 0x8d, 0xf2, 0xf5, 0xe6, 0x1e, 0xae, 0xb4, 0x93, 0xc0, 0x63, 0x68,
0x0b, 0xd3, 0xb3, 0x16, 0x88, 0xd2, 0xb6, 0xca, 0x1d, 0x24, 0xf0, 0x35, 0xe0, 0x2a, 0xa1, 0xe0, 0xda, 0xcc, 0x85, 0xf9, 0x5d, 0x4b, 0x44, 0xe9, 0x3a, 0xd5, 0x06, 0x12, 0xf8, 0x0a, 0x70, 0x91,
0xa3, 0xac, 0x69, 0x25, 0x1c, 0x68, 0x1f, 0x56, 0xb9, 0x49, 0xe0, 0xf7, 0xb0, 0x57, 0xe0, 0x05, 0x50, 0xf0, 0x81, 0x29, 0x5a, 0x05, 0x07, 0xba, 0x07, 0xab, 0xcc, 0x24, 0xf0, 0x47, 0xd8, 0x2d,
0xb4, 0x93, 0x2d, 0xab, 0x24, 0x65, 0x1f, 0xac, 0xf5, 0x91, 0xc0, 0x53, 0xb8, 0x6b, 0x3e, 0x4e, 0xf1, 0x02, 0xba, 0xd9, 0x91, 0x45, 0x92, 0x72, 0xf7, 0x97, 0xda, 0x48, 0xe0, 0x09, 0xdc, 0xb6,
0x29, 0x3b, 0x64, 0xe1, 0x39, 0x9c, 0x1d, 0xb2, 0xf8, 0x98, 0xc5, 0x4b, 0xe8, 0x96, 0x3d, 0xba, 0x1f, 0x9f, 0x64, 0x2e, 0x59, 0x7a, 0xee, 0x9a, 0x4b, 0x96, 0x1f, 0xab, 0x78, 0x0e, 0x9d, 0xaa,
0xd0, 0x6c, 0x70, 0xd9, 0xfb, 0xcf, 0xee, 0x57, 0x03, 0xd2, 0xd0, 0x2b, 0x13, 0x8e, 0x47, 0x55, 0xe7, 0x15, 0xda, 0x05, 0xae, 0x7a, 0xdf, 0xb9, 0xbd, 0xd5, 0x80, 0xdc, 0xf5, 0xc2, 0x84, 0xe3,
0xf3, 0x5f, 0x0c, 0x5d, 0xfa, 0xe5, 0x72, 0xfa, 0xf8, 0xd7, 0xa3, 0xf8, 0x1b, 0xeb, 0xf7, 0xf3, 0xe1, 0xaa, 0xf9, 0x2f, 0xbb, 0xae, 0xfc, 0xbf, 0x72, 0xf2, 0xf0, 0xb7, 0xc3, 0xf4, 0x3f, 0xd6,
0x0b, 0xe3, 0xe3, 0x4a, 0x6d, 0xfa, 0x5a, 0xfd, 0xbc, 0x6d, 0x48, 0xe3, 0x8b, 0x7f, 0x03, 0x00, 0x1f, 0xa7, 0x67, 0xd6, 0x9f, 0x2b, 0x75, 0xe8, 0x5b, 0xf5, 0xf3, 0x76, 0x4b, 0x2a, 0x9f, 0xfd,
0x00, 0xff, 0xff, 0x0d, 0x30, 0x9d, 0x85, 0xaa, 0x0d, 0x00, 0x00, 0x17, 0x00, 0x00, 0xff, 0xff, 0x90, 0x2a, 0xf6, 0x16, 0xaa, 0x0d, 0x00, 0x00,
} }

View File

@ -4,11 +4,15 @@ option go_package = "Open_IM/pkg/proto/friend;friend";
package friend; package friend;
message getPaginationFriendsReq{ message getPaginationFriendsReq{
string ownerUserID = 1; sdkws.RequestPagination pagination = 1;
repeated string friendUserIDs = 2; string userID = 2;
} }
message getPaginationFriendsResp{ message getPaginationFriendsResp{
repeated sdkws.FriendInfo friendsInfo = 1; repeated sdkws.FriendInfo FriendsInfo = 1;
int32 total = 2;
} }
@ -43,12 +47,11 @@ message getPaginationFriendsApplyToResp{
message getDesignatedFriendsReq{ message getDesignatedFriendsReq{
sdkws.RequestPagination pagination = 1; string ownerUserID = 1;
string userID = 2; repeated string friendUserIDs = 2;
} }
message getDesignatedFriendsResp{ message getDesignatedFriendsResp{
repeated sdkws.FriendInfo FriendsInfo = 1; repeated sdkws.FriendInfo friendsInfo = 1;
int32 total = 2;
} }
@ -160,4 +163,9 @@ service friend{
rpc getDesignatedFriends(getDesignatedFriendsReq) returns(getDesignatedFriendsResp); rpc getDesignatedFriends(getDesignatedFriendsReq) returns(getDesignatedFriendsResp);
// id不存在也返回错误 // id不存在也返回错误
rpc getPaginationFriends(getPaginationFriendsReq) returns (getPaginationFriendsResp); rpc getPaginationFriends(getPaginationFriendsReq) returns (getPaginationFriendsResp);
} }