1166 lines
28 KiB
Go
1166 lines
28 KiB
Go
// package
|
|
// 用户
|
|
// 赵长远
|
|
package user
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
"go_dreamfactory/sys/db"
|
|
"go_dreamfactory/utils"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"go_dreamfactory/lego/base"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/sys/event"
|
|
"go_dreamfactory/lego/sys/log"
|
|
|
|
cfg "go_dreamfactory/sys/configure/structs"
|
|
|
|
"github.com/pkg/errors"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
)
|
|
|
|
const (
|
|
// 跨服玩家
|
|
Rpc_GetAllOnlineUser string = "Rpc_GetAllOnlineUser"
|
|
// 跨服用户
|
|
Rpc_GetCrossUser string = "Rpc_GetCrossUser"
|
|
// 跨服用户会话
|
|
Rpc_GetCrossUserSession string = "Rpc_GetCrossUserSession"
|
|
// 搜索用户
|
|
Rpc_QueryUser = "Rpc_QueryUser"
|
|
|
|
//创建公会
|
|
Rpc_CreateSociaty string = "Rpc_CreateSociaty"
|
|
)
|
|
|
|
var _ comm.IUser = (*User)(nil)
|
|
|
|
func NewModule() core.IModule {
|
|
m := new(User)
|
|
return m
|
|
}
|
|
|
|
type User struct {
|
|
modules.ModuleBase
|
|
api *apiComp
|
|
modelUser *ModelUser
|
|
modelSession *ModelSession
|
|
modelSetting *ModelSetting
|
|
modelExpand *ModelExpand
|
|
service base.IRPCXService
|
|
configure *configureComp
|
|
globalConf *cfg.GameGlobalData
|
|
modelSign *ModelSign // 签到
|
|
timerLock sync.Mutex
|
|
timerMap map[string]*time.Ticker
|
|
}
|
|
|
|
func (this *User) GetType() core.M_Modules {
|
|
return comm.ModuleUser
|
|
}
|
|
|
|
func (this *User) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
|
err = this.ModuleBase.Init(service, module, options)
|
|
this.service = service.(base.IRPCXService)
|
|
this.timerMap = make(map[string]*time.Ticker)
|
|
return
|
|
}
|
|
|
|
func (this *User) Start() (err error) {
|
|
err = this.ModuleBase.Start()
|
|
event.RegisterGO(comm.EventUserOffline, this.CleanSession)
|
|
this.service.RegisterFunctionName(Rpc_GetAllOnlineUser, this.RpcGetAllOnlineUser)
|
|
this.service.RegisterFunctionName(Rpc_GetCrossUser, this.RpcGetCrossUser)
|
|
this.service.RegisterFunctionName(Rpc_GetCrossUserSession, this.RpcGetCrossUserSession)
|
|
this.service.RegisterFunctionName(Rpc_QueryUser, this.RpcQueryUser)
|
|
//date 3.10
|
|
this.service.RegisterFunctionName(Rpc_CreateSociaty, this.RpcCreateSociaty)
|
|
this.globalConf = this.ModuleTools.GetGlobalConf()
|
|
if this.globalConf == nil {
|
|
err = errors.New("global config not found")
|
|
}
|
|
this.ResetSession()
|
|
return
|
|
}
|
|
|
|
func (this *User) OnInstallComp() {
|
|
this.ModuleBase.OnInstallComp()
|
|
this.api = this.RegisterComp(new(apiComp)).(*apiComp)
|
|
this.modelUser = this.RegisterComp(new(ModelUser)).(*ModelUser)
|
|
this.modelSession = this.RegisterComp(new(ModelSession)).(*ModelSession)
|
|
this.modelSetting = this.RegisterComp(new(ModelSetting)).(*ModelSetting)
|
|
this.modelExpand = this.RegisterComp(new(ModelExpand)).(*ModelExpand)
|
|
this.modelSign = this.RegisterComp(new(ModelSign)).(*ModelSign)
|
|
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
|
|
}
|
|
|
|
// 获取用户数据
|
|
func (this *User) GetUser(uid string) (user *pb.DBUser) {
|
|
var err error
|
|
if this.IsCross() {
|
|
user, err = this.getRemoteUser(uid)
|
|
if err != nil {
|
|
this.Errorf("查询远程玩家信息 tag:%v err:%v", this.service.GetTag(), err)
|
|
return nil
|
|
}
|
|
} else {
|
|
user = this.modelUser.GetUser(uid)
|
|
}
|
|
|
|
if user.Id == "" {
|
|
this.Errorf("查询玩家信息 uid:%v", uid)
|
|
return nil
|
|
}
|
|
return user
|
|
}
|
|
|
|
// 获取跨服用户数据
|
|
func (this *User) GetCrossUser(uid string) (*pb.DBUser, error) {
|
|
reply := &pb.DBUser{}
|
|
err := this.service.AcrossClusterRpcCall(context.Background(), this.GetCrossTag(),
|
|
comm.Service_Worker, Rpc_GetCrossUser, &pb.UIdReq{Uid: uid}, reply)
|
|
return reply, err
|
|
}
|
|
|
|
// 获取远程用户数据
|
|
func (this *User) getRemoteUser(uid string) (*pb.DBUser, error) {
|
|
reply := &pb.DBUser{}
|
|
if err := this.getUserFromRemoteDb(uid, reply); err != nil {
|
|
this.Errorln("getRemoteUser", err)
|
|
return nil, err
|
|
}
|
|
return reply, nil
|
|
}
|
|
|
|
// 获取用户会话
|
|
func (this *User) GetUserSession(uid string) *pb.CacheUser {
|
|
return this.modelSession.getUserSession(uid)
|
|
}
|
|
|
|
func (this *User) ResetSession() {
|
|
us, err := this.UserOnlineList()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, v := range us {
|
|
this.modelSession.DelListlds(comm.RDS_EMPTY, []string{v.Uid})
|
|
}
|
|
this.modelSession.Del(comm.RDS_EMPTY)
|
|
}
|
|
|
|
// 清除session
|
|
func (this *User) CleanSession(uid, sessionid string) {
|
|
this.stopTicker(uid)
|
|
if !this.IsCross() {
|
|
this.modelUser.updateOfflineTime(uid)
|
|
}
|
|
// sId := fmt.Sprintf("%s-%s", comm.RDS_EMPTY, session.GetUserId())
|
|
// this.modelSession.Del(sId, db.SetDBMgoLog(false))
|
|
// this.modelSession.DelListlds(comm.RDS_EMPTY, session.GetUserId())
|
|
//确保删除的会话是目标会话 不是就不要删除了
|
|
if user := this.modelSession.getUserSession(uid); user != nil && user.SessionId == sessionid {
|
|
this.modelSession.Del(uid, db.SetDBMgoLog(false))
|
|
this.modelSession.DelListlds(comm.RDS_EMPTY, []string{uid}, db.SetDBMgoLog(false))
|
|
}
|
|
this.modelUser.DelByUId(uid, db.SetDBMgoLog(false))
|
|
this.modelExpand.DelByUId(uid, db.SetDBMgoLog(false))
|
|
this.modelSetting.DelByUId(uid, db.SetDBMgoLog(false))
|
|
}
|
|
|
|
// 在线玩家列表
|
|
func (this *User) UserOnlineList() ([]*pb.CacheUser, error) {
|
|
var cache []*pb.CacheUser
|
|
if !this.IsCross() {
|
|
if err := this.modelSession.GetList(comm.RDS_EMPTY, &cache); err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
var err error
|
|
if cache, err = this.CrossUserOnlineList(); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return cache, nil
|
|
}
|
|
|
|
// 跨服玩家列表
|
|
func (this *User) CrossUserOnlineList() ([]*pb.CacheUser, error) {
|
|
conn, err := db.Local()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
model := db.NewDBModel(comm.TableSession, 0, conn)
|
|
var cache []*pb.CacheUser
|
|
if err := model.GetList(comm.RDS_EMPTY, &cache); err != nil {
|
|
return nil, err
|
|
}
|
|
this.Debug("在线玩家数FromDB", log.Field{Key: "count", Value: len(cache)})
|
|
return cache, nil
|
|
}
|
|
|
|
func (this *User) crossUser(uid string) (*pb.CacheUser, error) {
|
|
conn, err := db.Local()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
model := db.NewDBModel(comm.TableSession, 0, conn)
|
|
cache := &pb.CacheUser{}
|
|
if err := model.Get(uid, cache); err != nil {
|
|
return nil, err
|
|
}
|
|
return cache, nil
|
|
}
|
|
|
|
func (this *User) IsOnline(uid string) bool {
|
|
if this.IsCross() {
|
|
cache, err := this.crossUser(uid)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
if cache.Uid == "" {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// 跨服玩家会话
|
|
func (this *User) CrossUserSession(uid string) *pb.CacheUser {
|
|
cacheUser := &pb.CacheUser{}
|
|
err := this.service.AcrossClusterRpcCall(context.Background(), this.GetCrossTag(),
|
|
comm.Service_Worker, Rpc_GetCrossUserSession, &pb.UIdReq{Uid: uid}, cacheUser)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return cacheUser
|
|
}
|
|
|
|
// 跨服创建玩家公会 date 3.10
|
|
// Deprecated
|
|
func (this *User) CrossCreateSociaty(uid, sociatyName string) *pb.DBSociaty {
|
|
sociaty := &pb.DBSociaty{}
|
|
this.service.AcrossClusterRpcCall(context.Background(), this.GetCrossTag(),
|
|
comm.Service_Worker, Rpc_CreateSociaty, &pb.RPCGeneralReqA2{Param1: uid, Param2: sociatyName}, sociaty)
|
|
return sociaty
|
|
}
|
|
|
|
// date 3.10
|
|
// Deprecated
|
|
func (this *User) RpcCreateSociaty(ctx context.Context, req *pb.RPCGeneralReqA2, rsp *pb.DBSociaty) error {
|
|
conn, err := db.Local()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
model := db.NewDBModel(comm.TableSociaty, 0, conn)
|
|
|
|
sociaty := &pb.DBSociaty{}
|
|
_id := primitive.NewObjectID().Hex()
|
|
sociaty.Creater = req.Param1
|
|
sociaty.Name = req.Param2
|
|
sociaty.Icon = "wp_icon_10015"
|
|
sociaty.ApplyLv = 1
|
|
sociaty.Id = _id
|
|
sociaty.Ctime = configure.Now().Unix()
|
|
sociaty.Lv = 1 //默认1级
|
|
|
|
sociaty.Members = append(sociaty.Members, &pb.SociatyMember{
|
|
Uid: req.Param1,
|
|
Job: pb.SociatyJob_PRESIDENT,
|
|
Ctime: configure.Now().Unix(),
|
|
})
|
|
|
|
if err := model.AddList(comm.RDS_EMPTY, sociaty.Id, sociaty); err != nil {
|
|
if err != mongo.ErrNoDocuments {
|
|
return err
|
|
}
|
|
}
|
|
|
|
rsp.Id = sociaty.Id
|
|
return nil
|
|
}
|
|
|
|
// 跨服搜索用户
|
|
func (this *User) CrossSearchUser(nickName string) ([]*pb.DBUser, error) {
|
|
name := strings.TrimSpace(nickName)
|
|
if name == "" {
|
|
return nil, errors.New("search name is empty")
|
|
}
|
|
reply := &pb.UserDataListResp{}
|
|
err := this.service.AcrossClusterRpcCall(context.Background(), this.GetCrossTag(),
|
|
comm.Service_Worker, Rpc_QueryUser, &pb.NameReq{Name: name}, reply)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return reply.Users, nil
|
|
}
|
|
|
|
// 远程搜索用户
|
|
func (this *User) SearchRmoteUser(nickname string) ([]*pb.DBUser, error) {
|
|
reply := &pb.UserDataListResp{}
|
|
if err := this.queryUserFromRemoteDb(nickname, reply); err != nil {
|
|
return nil, err
|
|
}
|
|
return reply.Users, nil
|
|
}
|
|
|
|
// 查询用户属性值 例如 金币 经验
|
|
func (this *User) QueryAttributeValue(uid string, attr string) (value int64) {
|
|
var (
|
|
user *pb.DBUser
|
|
userEx *pb.DBUserExpand
|
|
err error
|
|
)
|
|
|
|
user = this.modelUser.GetUser(uid)
|
|
userEx, err = this.GetUserExpand(uid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if user == nil || userEx == nil {
|
|
return
|
|
}
|
|
switch attr {
|
|
case comm.ResGold:
|
|
return user.Gold
|
|
case comm.ResExp:
|
|
return user.Exp
|
|
case comm.VipExp:
|
|
return user.Vipexp
|
|
case comm.StarCoin:
|
|
return user.Starcoin
|
|
case comm.ResDiamond:
|
|
return user.Diamond
|
|
case comm.ResPs:
|
|
return int64(user.Ps)
|
|
case comm.SociatyCoin:
|
|
return int64(userEx.Guildcoin)
|
|
case comm.ArenaCoin:
|
|
return int64(userEx.Arenacoin)
|
|
case comm.ResFriend:
|
|
return int64(userEx.FriendPoint)
|
|
case comm.Moongold:
|
|
return int64(user.Moongold)
|
|
case comm.Talent1:
|
|
return int64(user.Talent1)
|
|
case comm.Talent2:
|
|
return int64(user.Talent2)
|
|
case comm.Talent3:
|
|
return int64(user.Talent3)
|
|
case comm.Talent4:
|
|
return int64(user.Talent4)
|
|
case comm.Merchantmoney:
|
|
return int64(user.Merchantmoney)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *User) change(session comm.IUserSession, attr string, add int32) (change *pb.UserResChangedPush, errdata *pb.ErrorData) {
|
|
if add == 0 {
|
|
log.Warn("attr no changed",
|
|
log.Field{Key: "uid", Value: session.GetUserId()},
|
|
log.Field{Key: "attr", Value: attr},
|
|
log.Field{Key: "add", Value: add},
|
|
)
|
|
return
|
|
}
|
|
|
|
uid := session.GetUserId()
|
|
var (
|
|
user *pb.DBUser
|
|
userEx *pb.DBUserExpand
|
|
err error
|
|
)
|
|
|
|
user = this.GetUser(uid)
|
|
userEx, err = this.GetUserExpand(uid)
|
|
if err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserExpandNull,
|
|
Title: pb.ErrorCode_UserExpandNull.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
|
|
if user == nil || userEx == nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserSessionNobeing,
|
|
Title: pb.ErrorCode_UserSessionNobeing.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
|
|
change = &pb.UserResChangedPush{
|
|
Gold: user.Gold,
|
|
Exp: user.Exp,
|
|
Vipexp: user.Vipexp,
|
|
Diamond: user.Diamond,
|
|
Friend: userEx.FriendPoint,
|
|
Starcoin: user.Starcoin,
|
|
Guildcoin: userEx.Guildcoin,
|
|
Arenacoin: userEx.Arenacoin,
|
|
Ps: user.Ps,
|
|
Moongold: user.Moongold,
|
|
Talent1: user.Talent1,
|
|
Talent2: user.Talent2,
|
|
Talent3: user.Talent3,
|
|
Talent4: user.Talent4,
|
|
Merchantmoney: user.Merchantmoney,
|
|
}
|
|
|
|
switch attr {
|
|
case comm.ResGold:
|
|
if add < 0 {
|
|
if user.Gold+int64(add) < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_GoldNoEnough,
|
|
Title: pb.ErrorCode_GoldNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
this.ModuleBuried.TriggerBuried(session.GetUserId(), comm.GetBuriedParam(comm.Rtype68, -(add)))
|
|
}
|
|
change.Gold += int64(add)
|
|
case comm.ResExp:
|
|
if add < 0 {
|
|
if user.Exp+int64(add) < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserExpNoEnough,
|
|
Title: pb.ErrorCode_UserExpNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Exp += int64(add)
|
|
case comm.VipExp:
|
|
if add < 0 {
|
|
if user.Vipexp+int64(add) < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserExpNoEnough,
|
|
Title: pb.ErrorCode_UserExpNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Vipexp += int64(add)
|
|
case comm.ResDiamond:
|
|
if add < 0 {
|
|
if user.Diamond+int64(add) < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DiamondNoEnough,
|
|
Title: pb.ErrorCode_DiamondNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Diamond += int64(add)
|
|
case comm.Moongold:
|
|
if add < 0 {
|
|
if user.Moongold+int32(add) < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserMoongoldNoEnough,
|
|
Title: pb.ErrorCode_UserMoongoldNoEnough.ToString(),
|
|
}
|
|
pb.ErrorCode_PayRenewTimeErr.Enum().Descriptor().ReservedNames()
|
|
}
|
|
}
|
|
change.Moongold += int32(add)
|
|
case comm.ResFriend:
|
|
if add < 0 {
|
|
if userEx.FriendPoint+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserFriendNoEnough,
|
|
Title: pb.ErrorCode_UserFriendNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Friend += add
|
|
case comm.StarCoin:
|
|
if add < 0 {
|
|
if user.Starcoin+int64(add) < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserStarCoinNoEnough,
|
|
Title: pb.ErrorCode_UserStarCoinNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Starcoin += int64(add)
|
|
case comm.SociatyCoin:
|
|
if add < 0 {
|
|
if userEx.Guildcoin+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserSociatyCoinNoEnough,
|
|
Title: pb.ErrorCode_UserSociatyCoinNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Guildcoin += add
|
|
case comm.ArenaCoin:
|
|
if add < 0 {
|
|
if userEx.Arenacoin+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserArenaCoinNoEnough,
|
|
Title: pb.ErrorCode_UserArenaCoinNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Arenacoin += add
|
|
case comm.ResPs:
|
|
ggd := this.ModuleTools.GetGlobalConf()
|
|
if ggd == nil {
|
|
return
|
|
}
|
|
if add < 0 {
|
|
if user.Ps+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserVitNoEnough,
|
|
Title: pb.ErrorCode_UserVitNoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
change.Ps += add
|
|
} else {
|
|
if change.Ps+add > ggd.PsUl {
|
|
change.Ps = ggd.PsUl
|
|
} else {
|
|
change.Ps += add
|
|
}
|
|
}
|
|
|
|
case comm.Talent1:
|
|
if add < 0 {
|
|
if user.Talent1+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserTalent1NoEnough,
|
|
Title: pb.ErrorCode_UserTalent1NoEnough.ToString(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
change.Talent1 += add
|
|
case comm.Talent2:
|
|
if add < 0 {
|
|
if user.Talent2+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserTalent2NoEnough,
|
|
Title: pb.ErrorCode_UserTalent2NoEnough.ToString(),
|
|
}
|
|
|
|
return
|
|
}
|
|
}
|
|
change.Talent2 += add
|
|
case comm.Talent3:
|
|
if add < 0 {
|
|
if user.Talent3+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserTalent3NoEnough,
|
|
Title: pb.ErrorCode_UserTalent3NoEnough.ToString(),
|
|
}
|
|
|
|
return
|
|
}
|
|
}
|
|
change.Talent3 += add
|
|
case comm.Talent4:
|
|
if add < 0 {
|
|
if user.Talent4+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserTalent4NoEnough,
|
|
Title: pb.ErrorCode_UserTalent4NoEnough.ToString(),
|
|
}
|
|
|
|
return
|
|
}
|
|
}
|
|
change.Talent4 += add
|
|
case comm.Merchantmoney:
|
|
if add < 0 {
|
|
if user.Merchantmoney+add < 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserMerchantNoEnough,
|
|
Title: pb.ErrorCode_UserMerchantNoEnough.ToString(),
|
|
}
|
|
|
|
return
|
|
}
|
|
}
|
|
change.Merchantmoney += add
|
|
default:
|
|
err = errors.New(fmt.Sprintf("%s no supported", attr))
|
|
return
|
|
}
|
|
|
|
//user
|
|
update := map[string]interface{}{
|
|
comm.ResGold: change.Gold,
|
|
comm.ResDiamond: change.Diamond,
|
|
comm.ResExp: change.Exp,
|
|
comm.VipExp: change.Vipexp,
|
|
comm.StarCoin: change.Starcoin,
|
|
comm.ResPs: change.Ps,
|
|
comm.Moongold: change.Moongold,
|
|
comm.Talent1: change.Talent1,
|
|
comm.Talent2: change.Talent2,
|
|
comm.Talent3: change.Talent3,
|
|
comm.Talent4: change.Talent4,
|
|
comm.Merchantmoney: change.Merchantmoney,
|
|
}
|
|
|
|
//user ex
|
|
updateEx := map[string]interface{}{
|
|
comm.ResFriend: change.Friend,
|
|
comm.SociatyCoin: change.Guildcoin,
|
|
comm.ArenaCoin: change.Arenacoin,
|
|
}
|
|
|
|
if err := this.modelUser.updateUserAttr(uid, update); err != nil {
|
|
this.Errorf("AddAttributeValue err:%v", err)
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Title: pb.ErrorCode_DBError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
}
|
|
|
|
if err := this.modelExpand.ChangeUserExpand(uid, updateEx); err != nil {
|
|
this.Errorf("AddAttributeValue ex err:%v", err)
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Title: pb.ErrorCode_DBError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 用户资源
|
|
func (this *User) AddAttributeValue(session comm.IUserSession, attr string, add int32, bPush bool) (errdata *pb.ErrorData) {
|
|
var _change *pb.UserResChangedPush
|
|
|
|
_change, errdata = this.change(session, attr, add)
|
|
if errdata != nil {
|
|
return
|
|
}
|
|
|
|
if _change == nil {
|
|
return
|
|
}
|
|
|
|
if bPush { //推送玩家账号信息变化消息
|
|
session.SendMsg(string(this.GetType()), "reschanged", _change)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 用户资源
|
|
func (this *User) AddAttributeValues(session comm.IUserSession, attrs map[string]int32, bPush bool) (errdata *pb.ErrorData) {
|
|
for key, add := range attrs {
|
|
var _change *pb.UserResChangedPush
|
|
_change, errdata = this.change(session, key, add)
|
|
if errdata != nil {
|
|
return
|
|
}
|
|
|
|
if _change == nil {
|
|
continue
|
|
}
|
|
|
|
if bPush { //推送玩家账号信息变化消息
|
|
session.SendMsg(string(this.GetType()), "reschanged", _change)
|
|
}
|
|
if key == comm.ResExp {
|
|
this.ModuleUser.EventUserChanged(session)
|
|
} else if key == comm.VipExp {
|
|
this.ModuleUser.EventUserVipChanged(session)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 用户事件变化
|
|
func (this *User) EventUserVipChanged(session comm.IUserSession) {
|
|
ul := new(UserListen)
|
|
user := this.GetUser(session.GetUserId())
|
|
if user != nil {
|
|
ul.session = session
|
|
ul.name = user.Name
|
|
ul.vipexp = user.Vipexp
|
|
ul.viplv = user.Vip
|
|
}
|
|
this.modelUser.EventApp.Dispatch(comm.EventUserVipChanged, ul)
|
|
}
|
|
|
|
// 用户事件变化
|
|
func (this *User) EventUserChanged(session comm.IUserSession) {
|
|
ul := new(UserListen)
|
|
user := this.GetUser(session.GetUserId())
|
|
if user != nil {
|
|
ul.session = session
|
|
ul.exp = user.Exp
|
|
ul.lv = user.Lv
|
|
ul.name = user.Name
|
|
ul.Gold = user.Gold
|
|
ul.vipexp = user.Vipexp
|
|
ul.Ps = user.Ps
|
|
ul.Diamond = user.Diamond
|
|
ul.Merchantmoney = user.Merchantmoney
|
|
ul.Talent1 = user.Talent1
|
|
ul.Talent2 = user.Talent2
|
|
ul.Talent3 = user.Talent3
|
|
ul.Talent4 = user.Talent4
|
|
}
|
|
this.modelUser.EventApp.Dispatch(comm.EventUserChanged, ul)
|
|
}
|
|
|
|
func (this *User) GetUserExpand(uid string) (result *pb.DBUserExpand, err error) {
|
|
return this.modelExpand.GetUserExpand(uid)
|
|
}
|
|
|
|
func (this *User) ChangeUserExpand(uid string, value map[string]interface{}) error {
|
|
return this.modelExpand.ChangeUserExpand(uid, value)
|
|
}
|
|
|
|
// 从远程库查询用户
|
|
func (this *User) getUserFromRemoteDb(uid string, rsp *pb.DBUser) error {
|
|
sid, _, ok := utils.UIdSplit(uid)
|
|
if !ok {
|
|
return fmt.Errorf("sid split err,uid: %v", uid)
|
|
}
|
|
conn, err := db.ServerDBConn(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
model := db.NewDBModel(comm.TableUser, 0, conn)
|
|
if err := model.Get(uid, rsp); err != nil {
|
|
this.Errorln("Get User:", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *User) getUserExpandFromRemoteDb(uid string, rsp *pb.DBUserExpand) error {
|
|
sid, _, ok := utils.UIdSplit(uid)
|
|
if !ok {
|
|
return errors.New("sid split error")
|
|
}
|
|
conn, err := db.ServerDBConn(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
model := db.NewDBModel(comm.TableUserExpand, 0, conn)
|
|
|
|
if err := model.Get(uid, rsp); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *User) changeUserExpandFromRemoteDb(uid string, data map[string]interface{}) error {
|
|
sid, _, ok := utils.UIdSplit(uid)
|
|
if !ok {
|
|
return errors.New("sid split error")
|
|
}
|
|
conn, err := db.ServerDBConn(sid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
model := db.NewDBModel(comm.TableUserExpand, 0, conn)
|
|
|
|
if err := model.Change(uid, data); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *User) queryUserFromRemoteDb(name string, reply *pb.UserDataListResp) error {
|
|
// 区服列表
|
|
for _, tag := range db.GetServerTags() {
|
|
conn, err := db.ServerDBConn(tag)
|
|
if err != nil {
|
|
return fmt.Errorf("db tag:%v err:%v", tag, err)
|
|
}
|
|
|
|
//查询用户
|
|
filter := bson.M{
|
|
"name": name,
|
|
}
|
|
sr := conn.Mgo.FindOne(comm.TableUser, filter)
|
|
user := &pb.DBUser{}
|
|
if err = sr.Decode(user); err != nil {
|
|
if err != mongo.ErrNoDocuments {
|
|
return err
|
|
}
|
|
}
|
|
if user.Uid != "" {
|
|
reply.Users = append(reply.Users, user)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *User) RpcGetAllOnlineUser(ctx context.Context, args *pb.EmptyReq, reply *pb.UserOnlineResp) error {
|
|
conn, err := db.Local()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
model := db.NewDBModel(comm.TableSession, 0, conn)
|
|
var cache []*pb.CacheUser
|
|
if err := model.GetList(comm.RDS_EMPTY, &cache); err != nil {
|
|
return err
|
|
}
|
|
reply.Users = cache
|
|
return nil
|
|
}
|
|
|
|
func (this *User) RpcGetCrossUser(ctx context.Context, req *pb.UIdReq, reply *pb.DBUser) error {
|
|
return this.getUserFromRemoteDb(req.Uid, reply)
|
|
}
|
|
|
|
func (this *User) RpcGetCrossUserSession(ctx context.Context, req *pb.UIdReq, reply *pb.CacheUser) error {
|
|
conn, err := db.Local()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
model := db.NewDBModel(comm.TableSession, 0, conn)
|
|
if err := model.GetListObj(comm.RDS_EMPTY, req.Uid, reply); err != nil {
|
|
if err != mongo.ErrNoDocuments {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *User) RpcQueryUser(ctx context.Context, req *pb.NameReq, reply *pb.UserDataListResp) error {
|
|
return this.queryUserFromRemoteDb(req.Name, reply)
|
|
}
|
|
|
|
func (this *User) CheckTujianHero(session comm.IUserSession, heros []string) []bool {
|
|
sz := make([]bool, len(heros))
|
|
index := 0
|
|
list := this.ModuleHero.GetHeroList(session.GetUserId())
|
|
for _, v1 := range heros {
|
|
for _, h := range list {
|
|
if v1 == h.HeroID {
|
|
sz[index] = true
|
|
index++
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return sz
|
|
}
|
|
|
|
func (this *User) BingoSetUserLv(session comm.IUserSession, lv int32) error {
|
|
if lv <= 0 {
|
|
return comm.NewCustomError(pb.ErrorCode_ReqParameterError)
|
|
}
|
|
update := map[string]interface{}{
|
|
"lv": lv,
|
|
"exp": 0,
|
|
}
|
|
if err := this.modelUser.Change(session.GetUserId(), update); err == nil {
|
|
if err := session.SendMsg(string(this.GetType()), UserSubTypeLvChangedPush,
|
|
&pb.UserLvChangedPush{Uid: session.GetUserId(), Exp: 0, Lv: lv}); err != nil {
|
|
this.Error("Bingo玩家等级变化 UserSubTypeLvChangedPush推送失败",
|
|
log.Field{Key: "uid", Value: session.GetUserId()},
|
|
log.Field{Key: "exp", Value: 0},
|
|
log.Field{Key: "lv", Value: lv},
|
|
)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// func (this *User) Update() {
|
|
// if this.IsCross() {
|
|
// return
|
|
// }
|
|
// cu, err := this.UserOnlineList()
|
|
// if err != nil {
|
|
// return
|
|
// }
|
|
|
|
// for _, v := range cu {
|
|
// if isession, ok := this.ModuleBase.GetUserSession(v.Uid); ok {
|
|
// //del session
|
|
// log.Debug("del session", log.Field{Key: "uid", Value: v.Uid}, log.Field{Key: "isLogin", Value: isession.IsLogin()})
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// 玩家体力恢复
|
|
func (this *User) RecoverUserPsStart(uid string) {
|
|
go func(uid string) {
|
|
timeSec := time.NewTicker(time.Second * 30)
|
|
this.timerLock.Lock()
|
|
this.timerMap[uid] = timeSec
|
|
this.timerLock.Unlock()
|
|
for {
|
|
select {
|
|
case <-timeSec.C:
|
|
this.recoverUserPs(uid)
|
|
}
|
|
}
|
|
}(uid)
|
|
}
|
|
|
|
// 停止计时
|
|
func (this *User) stopTicker(uid string) {
|
|
if t, ok := this.timerMap[uid]; ok {
|
|
if t != nil {
|
|
t.Stop()
|
|
delete(this.timerMap, uid)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 玩家体力恢复
|
|
func (this *User) recoverUserPs(uid string) {
|
|
if this.IsCross() {
|
|
return
|
|
}
|
|
|
|
u := this.GetUser(uid)
|
|
if u == nil {
|
|
return
|
|
}
|
|
ggd := this.ModuleTools.GetGlobalConf()
|
|
if ggd == nil {
|
|
return
|
|
}
|
|
|
|
var (
|
|
yu int32
|
|
add int32
|
|
changed int32
|
|
)
|
|
cur := time.Now().Unix()
|
|
if u.LastRecoverPsSec == 0 {
|
|
update := map[string]interface{}{
|
|
"lastRecoverPsSec": cur,
|
|
}
|
|
this.modelUser.Change(u.Uid, update)
|
|
return
|
|
} else {
|
|
diff := cur - u.LastRecoverPsSec
|
|
yu = int32(diff / int64(ggd.PsRecovery))
|
|
}
|
|
|
|
if yu > 0 {
|
|
pconf := this.configure.GetPlayerlvConf(u.Lv)
|
|
if pconf == nil {
|
|
return
|
|
}
|
|
if u.Ps < pconf.PsCeiling {
|
|
total := u.Ps + yu
|
|
if total > pconf.PsCeiling {
|
|
add = pconf.PsCeiling - u.Ps
|
|
changed = pconf.PsCeiling
|
|
} else {
|
|
add = yu
|
|
changed = total
|
|
}
|
|
} else {
|
|
add = 0
|
|
}
|
|
|
|
update := map[string]interface{}{
|
|
"lastRecoverPsSec": cur,
|
|
}
|
|
if add > 0 {
|
|
u.Ps += add
|
|
update["ps"] = u.Ps
|
|
}
|
|
if err := this.modelUser.Change(u.Uid, update); err == nil {
|
|
if changed > 0 {
|
|
if err := this.SendMsgToUser(string(this.GetType()), "pschanged",
|
|
&pb.UserPsChangedPush{Ps: changed}, u.Uid); err != nil {
|
|
this.Error("玩家体力变化 UserPsChangedPush推送失败",
|
|
log.Field{Key: "uid", Value: u.Uid},
|
|
log.Field{Key: comm.ResPs, Value: changed},
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *User) BingoSetUserVipLv(session comm.IUserSession, lv int32) (errdata *pb.ErrorData) {
|
|
if lv <= 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_ConfigNoFound,
|
|
Title: pb.ErrorCode_ConfigNoFound.ToString(),
|
|
}
|
|
return
|
|
}
|
|
update := map[string]interface{}{
|
|
"vip": lv,
|
|
"vipexp": 0,
|
|
}
|
|
// vip 等级校验
|
|
if conf := this.configure.GetVipConfigureData(lv); conf == nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_ConfigNoFound,
|
|
Title: pb.ErrorCode_ConfigNoFound.ToString(),
|
|
}
|
|
return
|
|
}
|
|
if err := this.modelUser.Change(session.GetUserId(), update); err == nil {
|
|
if err := session.SendMsg(string(this.GetType()), UserSubTypeVipChangedPush,
|
|
&pb.UserVipChangedPush{Uid: session.GetUserId(), VipExp: 0, VipLv: lv}); err != nil {
|
|
this.Error("Bingo玩家等级变化 UserVipChangedPush推送失败",
|
|
log.Field{Key: "uid", Value: session.GetUserId()},
|
|
log.Field{Key: "vipexp", Value: 0},
|
|
log.Field{Key: "viplv", Value: lv},
|
|
)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 添加用户皮肤数据
|
|
func (this *User) AddPer(session comm.IUserSession, pers map[string]int32, bPush bool) (errdata *pb.ErrorData) {
|
|
var (
|
|
err error
|
|
conf *cfg.GamePlayerInfor_overviewData
|
|
user *pb.DBUser
|
|
change map[string]interface{} = make(map[string]interface{})
|
|
adds []string = make([]string, 0)
|
|
iskeep bool
|
|
)
|
|
if user = this.GetUser(session.GetUserId()); user == nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserSessionNobeing,
|
|
Title: pb.ErrorCode_UserSessionNobeing.ToString(),
|
|
}
|
|
return
|
|
}
|
|
|
|
for k, _ := range pers {
|
|
iskeep = false
|
|
for _, v1 := range user.Skins {
|
|
if k == v1 {
|
|
iskeep = true
|
|
break
|
|
}
|
|
}
|
|
if !iskeep {
|
|
if user.CurSkin == "" || user.CurAction == "" || user.CurBg == "" {
|
|
if conf, err = this.configure.GetPlayerOverview(k, user.Gender); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_ConfigNoFound,
|
|
Title: pb.ErrorCode_ConfigNoFound.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
} else {
|
|
if user.CurSkin == "" && conf.Type == 1 {
|
|
user.CurSkin = k
|
|
user.Avatar = conf.Playerhead
|
|
change["curSkin"] = k
|
|
change["avatar"] = conf.Playerhead
|
|
}
|
|
if user.CurAction == "" && conf.Type == 2 {
|
|
user.CurAction = k
|
|
change["curAction"] = k
|
|
}
|
|
|
|
if user.CurBg == "" && conf.Type == 3 {
|
|
user.CurBg = k
|
|
change["curBg"] = k
|
|
}
|
|
}
|
|
}
|
|
adds = append(adds, k)
|
|
}
|
|
}
|
|
|
|
user.Skins = append(user.Skins, adds...)
|
|
change["skins"] = user.Skins
|
|
if err = this.modelUser.Change(session.GetUserId(), change); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Title: pb.ErrorCode_DBError.ToString(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
if bPush {
|
|
session.SendMsg(string(this.GetType()), "skinlist", &pb.UserSkinlistPush{
|
|
Skins: user.Skins,
|
|
CurSkin: user.CurSkin,
|
|
CurAction: user.CurAction,
|
|
CurBg: user.CurBg,
|
|
Avatar: user.Avatar,
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *User) SetUserCaravanLvChange(session comm.IUserSession, caravanlv int32) error {
|
|
|
|
update := map[string]interface{}{
|
|
"caravanlv": caravanlv,
|
|
}
|
|
return this.modelUser.Change(session.GetUserId(), update)
|
|
}
|
|
|
|
func (this *User) ConsumePsAddExp(session comm.IUserSession, ps int32) (addExp int32, errdata *pb.ErrorData) {
|
|
if ps <= 0 {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_ReqParameterError,
|
|
Title: pb.ErrorCode_ReqParameterError.ToString(),
|
|
}
|
|
return
|
|
}
|
|
|
|
ggd := this.ModuleTools.GetGlobalConf()
|
|
if ggd == nil {
|
|
return
|
|
}
|
|
//体力消耗,增加玩家经验
|
|
addExp = ps * ggd.FightPs
|
|
|
|
attrs := make(map[string]int32, 0)
|
|
attrs["exp"] = addExp
|
|
return addExp, this.AddAttributeValues(session, attrs, true)
|
|
}
|
|
|
|
// 剩余体力
|
|
func (this *User) RemainingPS(uid string) (ps int32) {
|
|
var (
|
|
user *pb.DBUser
|
|
)
|
|
|
|
if user = this.GetUser(uid); user == nil {
|
|
return
|
|
}
|
|
ggd := this.ModuleTools.GetGlobalConf()
|
|
if ggd == nil {
|
|
return
|
|
}
|
|
return ggd.PsUl - user.Ps
|
|
}
|