玩家等级优化

This commit is contained in:
zhaocy 2022-07-25 13:46:52 +08:00
parent e06b0d8d31
commit ef6f6efa69
16 changed files with 289 additions and 48 deletions

View File

@ -66,6 +66,8 @@ const (
EventUserLogin core.Event_Key = "Event_UserLogin" //登录事件
EventCreateUser core.Event_Key = "Event_CreateUser" //创建角色事件
EventUserOffline core.Event_Key = "Event_UserOffline" //用户离线事件
EventUserChanged core.Event_Key = "event_user_changed" //用户数据变化
)
const (

View File

@ -60,6 +60,8 @@ type (
QueryAttributeValue(uid string, attr string) (value int32)
//添加/减少属性值 第四个参数控制是否推送给前端
AddAttributeValue(session IUserSession, attr string, add int32, bPush bool) (code pb.ErrorCode)
//用户改变事件
EventUserChanged(session IUserSession)
}
//武器模块
IEquipment interface {

65
lego/sys/event/v2/app.go Normal file
View File

@ -0,0 +1,65 @@
package event_v2
import (
"go_dreamfactory/lego/core"
"sync"
)
// 服务容器
type App struct {
//inject.Graph
sync.RWMutex
events map[core.Event_Key][]Listener // 事件
}
// 容器的目的是为了创建事件之后,为事件注入观察者,所以为了方便,直接全部解耦
// 创建
// 新建一个App可以在其中注册事件
func NewApp() *App {
app := &App{}
app.events = make(map[core.Event_Key][]Listener)
return app
}
// 给容器绑定事件,传入 类型-> 观察者的绑定
// 可以使用反射,传入类型的字符串
// 否则bind时也可以放置包括通配符的
func (app *App) Bind(t core.Event_Key, listeners []Listener) {
for k := range listeners {
app.Listen(t, listeners[k])
}
}
// 监听[事件][监听器],单独绑定一个监听器
func (app *App) Listen(str core.Event_Key, listener Listener) {
app.Lock()
app.events[str] = append(app.events[str], listener)
app.Unlock()
}
// 分发事件,传入各种事件,如果是
func (app *App) Dispatch(key core.Event_Key, events ...interface{}) {
// 容器分发数据
for k := range events {
// 如果实现了 事件接口 IEvent则调用事件的观察者模式得到所有的
var observers []Listener
if _, ok := events[k].(IEvent); ok {
obs := events[k].(IEvent).Observers()
observers = append(observers, obs...) // 将事件中自行添加的观察者,放在所有观察者之后
}
if obs, exist := app.events[key]; exist {
observers = append(observers, obs...)
}
if len(observers) > 0 {
// 得到了所有的观察者这里通过pipeline来执行通过next来控制什么时候调用这个观察者
new(Pipeline).Send(events[k]).Through(observers).Then(func(context interface{}) {
})
}
}
}

View File

@ -0,0 +1,36 @@
package event_v2
// 事件接口
type IEvent interface {
Attach(listeners ...Listener) // 事件添加观察者
Observers() []Listener // 获取所有的观察者
//Detach(listener Listener)
DetachIndexOf(index int)
}
type Event struct {
listeners []Listener
}
func (e *Event) Attach(listeners ...Listener) {
e.listeners = append(e.listeners, listeners...)
}
//func (e *Event) Detach(listener Listener) {
// for k := range e.listeners {
// if listener == e.listeners[k] {
//
// }
// }
//}
// 移除某个监听器
func (e *Event) DetachIndexOf(index int) {
if len(e.listeners) > index && index > 0 {
e.listeners = append(e.listeners[:index], e.listeners[index+1:]...)
}
}
func (e *Event) Observers() []Listener {
return e.listeners
}

View File

@ -0,0 +1,5 @@
package event_v2
// 监听器接口
type Listener func(event interface{},next func(event interface{}))

View File

@ -0,0 +1,41 @@
package event_v2
type Pipeline struct {
send interface{} // 穿过管道的上下文
through []Listener // 中间件数组
current int // 当前执行到第几个中间件
}
func (p *Pipeline) Send(context interface{}) *Pipeline {
p.send = context
return p
}
func (p *Pipeline) Through(middlewares []Listener) *Pipeline {
p.through = middlewares
return p
}
func (p *Pipeline) Exec() {
if len(p.through) > p.current {
m := p.through[p.current]
p.current += 1
m(p.send, func(c interface{}) {
p.Exec()
})
}
}
// 这里是路由的最后一站
func (p *Pipeline) Then(then func(context interface{})) {
// 按照顺序执行
// 将then作为最后一站的中间件
var m Listener
m = func(c interface{}, next func(c interface{})) {
then(c)
next(c)
}
p.through = append(p.through, m)
p.Exec()
}

View File

@ -10,8 +10,9 @@ import (
)
const (
game_global = "game_global.json"
game_initial = "game_initial.json"
game_global = "game_global.json" //全局配置表
game_initial = "game_initial.json" //初始化表
game_playerlv = "game_playerlv.json" //玩家等级
)
///配置管理基础组件
@ -24,6 +25,7 @@ func (this *MCompConfigure) Init(service core.IService, module core.IModule, com
err = this.ModuleCompBase.Init(service, module, comp, options)
err = this.LoadConfigure(game_global, cfg.NewGame_global)
err = this.LoadConfigure(game_initial, cfg.NewGame_initial)
err = this.LoadConfigure(game_playerlv, cfg.NewGame_playerlv)
return
}
@ -50,7 +52,6 @@ func (this *MCompConfigure) GetConfigure(name string) (v interface{}, err error)
}
//全局配置
func (this *MCompConfigure) GetGlobalConf(key string) string {
if v, err := this.GetConfigure(game_initial); err != nil {
log.Errorf("get global conf err:%v", err)
@ -87,3 +88,36 @@ func (this *MCompConfigure) GetGlobalInitConf() (configure *cfg.Game_initial, er
}
return
}
// 主角等级经验配置列表
func (this *MCompConfigure) GetPlayerlvConfList() (list []*cfg.Game_playerlvData) {
if v, err := this.GetConfigure(game_playerlv); err != nil {
return
} else {
if configure, ok := v.(*cfg.Game_playerlv); !ok {
err = fmt.Errorf("%T no is *cfg.Game_playerlv", v)
return
} else {
if configure != nil {
list = configure.GetDataList()
}
}
}
return
}
func (this *MCompConfigure) GetPlayerlvConf(lv int32) (data *cfg.Game_playerlvData) {
if v, err := this.GetConfigure(game_playerlv); err != nil {
return
} else {
if configure, ok := v.(*cfg.Game_playerlv); !ok {
err = fmt.Errorf("%T no is *cfg.Game_playerlv", v)
return
} else {
if configure != nil {
data = configure.GetDataMap()[lv]
}
}
}
return
}

View File

@ -16,7 +16,6 @@ func (this *apiComp) ActiveListCheck(session comm.IUserSession, req *pb.TaskActi
}
func (this *apiComp) ActiveList(session comm.IUserSession, req *pb.TaskActiveListReq) (code pb.ErrorCode, data proto.Message) {
// this.moduleTask.ModuleTask.SendToTask(session.GetUserId(), comm.TaskTypeGetHero, &pb.TaskParam{First: 5})
if code = this.ActiveListCheck(session, req); code != pb.ErrorCode_Success {
return
}
@ -27,12 +26,11 @@ func (this *apiComp) ActiveList(session comm.IUserSession, req *pb.TaskActiveLis
if err != nil {
code = pb.ErrorCode_SystemError
}
// utils.TraceFunc(session.GetUserId(), string(this.moduleTask.GetType()), TaskSubTypeActiveList, req, resp)
}()
resp.Active = this.moduleTask.modelTask.countActive(session.GetUserId(), comm.TaskTag(req.TaskTag))
//遍历活跃度奖励表
resp.List = this.moduleTask.modelTaskActive.getUserActiveList(session.GetUserId(), comm.TaskTag(req.TaskTag))
resp.List = this.moduleTask.modelTaskActive.getActiveListByTag(session.GetUserId(), comm.TaskTag(req.TaskTag))
return
}

View File

@ -28,7 +28,7 @@ func (this *apiComp) List(session comm.IUserSession, req *pb.TaskListReq) (code
// utils.TraceFunc(session.GetUserId(), string(this.moduleTask.GetType()), TaskSubTypeList, req, rsp)
}()
rsp.List = this.moduleTask.modelTask.getTaskList(session.GetUserId(), comm.TaskTag(req.TaskTag))
rsp.List = this.moduleTask.modelTask.getTaskListByTag(session.GetUserId(), comm.TaskTag(req.TaskTag))
return
}

View File

@ -27,7 +27,6 @@ func (this *apiComp) Receive(session comm.IUserSession, req *pb.TaskReceiveReq)
if err != nil {
code = pb.ErrorCode_SystemError
}
// utils.TraceFunc(session.GetUserId(), string(this.moduleTask.GetType()), TaskSubTypeReceive, req, resp)
}()
userTask := this.moduleTask.modelTask.getUserTask(session.GetUserId(), req.Id)
if userTask != nil {
@ -41,7 +40,7 @@ func (this *apiComp) Receive(session comm.IUserSession, req *pb.TaskReceiveReq)
code = pb.ErrorCode_TaskReceived
return
}
// 待领取的任务配置
conf, err := this.moduleTask.configure.getTaskById(userTask.TaskId)
if err != nil {
log.Errorf("get task config err:%v", err)
@ -63,6 +62,9 @@ func (this *apiComp) Receive(session comm.IUserSession, req *pb.TaskReceiveReq)
}
resp.TaskId = userTask.TaskId
// 监听玩家经验
this.moduleTask.ModuleUser.EventUserChanged(session)
}
return

View File

@ -46,8 +46,16 @@ func (this *ModelTaskActive) initActiveReward(uid string) {
}
}
func (this *ModelTaskActive) getActiveList(uid string) (list []*pb.DBTaskActive) {
if err := this.GetList(uid, &list); err != nil {
log.Errorf("getActiveList err:%v", err)
return list
}
return
}
//获取玩家活跃度列表
func (this *ModelTaskActive) getUserActiveList(uid string, taskTag comm.TaskTag) (list []*pb.DBTaskActive) {
func (this *ModelTaskActive) getActiveListByTag(uid string, taskTag comm.TaskTag) (list []*pb.DBTaskActive) {
al := []*pb.DBTaskActive{}
if err := this.GetList(uid, &al); err != nil {
log.Errorf("getUserActiveList err:%v", err)
@ -65,7 +73,7 @@ func (this *ModelTaskActive) getUserActiveList(uid string, taskTag comm.TaskTag)
//获取玩家活跃记录 id 唯一ID
func (this *ModelTaskActive) getUserActive(uid, id string, taskTag comm.TaskTag) *pb.DBTaskActive {
record := this.getUserActiveList(uid, taskTag)
record := this.getActiveListByTag(uid, taskTag)
for _, v := range record {
if v.Id == id {
return v
@ -112,14 +120,12 @@ func (this *ModelTaskActive) receiveHandle(uid, id string, conf *cfg.Game_active
}
//清空任务
func (this *ModelTaskActive) clearTask(uid string, taskTag comm.TaskTag) error {
data := this.getUserActiveList(uid, taskTag)
func (this *ModelTaskActive) clearTask(uid string) {
data := this.getActiveList(uid)
for _, v := range data {
if err := this.moduleTask.modelTaskActive.DelListlds(uid, v.Id); err != nil {
log.Errorf("uid: %v taskTag:%v err:%v", uid, taskTag, err)
return err
log.Errorf("uid: %v err:%v", uid, err)
return
}
}
return nil
}

View File

@ -26,8 +26,16 @@ func (this *ModelTask) Init(service core.IService, module core.IModule, comp cor
return
}
func (this *ModelTask) getTaskList(uid string) (list []*pb.DBTask) {
if err := this.GetList(uid, &list); err != nil {
log.Errorf("getTaskList err %v", err)
return
}
return
}
//获取玩家任务列表
func (this *ModelTask) getTaskList(uid string, taskTag comm.TaskTag) (newlist []*pb.DBTask) {
func (this *ModelTask) getTaskListByTag(uid string, taskTag comm.TaskTag) (newlist []*pb.DBTask) {
list := []*pb.DBTask{}
if err := this.GetList(uid, &list); err != nil {
log.Errorf("getTaskList err %v", err)
@ -46,7 +54,7 @@ func (this *ModelTask) getTaskList(uid string, taskTag comm.TaskTag) (newlist []
func (this *ModelTask) getTaskById(uid string, taskId int32) (newlist []*pb.DBTask) {
list := []*pb.DBTask{}
if err := this.GetList(uid, &list); err != nil {
log.Errorf("getTaskList err %v", err)
log.Errorf("getTaskById err %v", err)
return
}
@ -104,7 +112,7 @@ func (this *ModelTask) getUnFinishTasks(uid string, taskId int32) (list []*pb.DB
//活跃度统计
func (this *ModelTask) countActive(uid string, taskTag comm.TaskTag) (total int32) {
taskList := this.getTaskList(uid, taskTag)
taskList := this.getTaskListByTag(uid, taskTag)
for _, v := range taskList {
if v.Status == 1 {
total += v.Active
@ -134,21 +142,20 @@ func (this *ModelTask) modifyUserTask(uid string, taskId string, data map[string
}
//清空任务
func (this *ModelTask) clearTask(uid string, taskTag comm.TaskTag) error {
taskList := this.getTaskList(uid, taskTag)
func (this *ModelTask) clearTask(uid string) {
taskList := this.getTaskList(uid)
for _, v := range taskList {
if err := this.moduleTask.modelTask.DelListlds(uid, v.Id); err != nil {
log.Errorf("uid: %v taskTag:%v err:%v", uid, taskTag, err)
return err
log.Errorf("uid: %v err:%v", uid, err)
return
}
}
return nil
}
//进入卡牌攻略
func (this *ModelTask) inStrategy(uid string, heroCfgId int32) (taskIds []int32, err error) {
//检查此英雄攻略是否完成
taskList := this.getTaskList(uid, comm.TASK_STRATEGY)
taskList := this.getTaskListByTag(uid, comm.TASK_STRATEGY)
allFinished := true
for _, v := range taskList {
conf, err := this.moduleTask.configure.getTaskById(v.TaskId)
@ -197,13 +204,13 @@ func (this *ModelTask) UpHeroStar(uid string, taskId int32, tp *pb.TaskParam) *p
func (this *ModelTask) UpHeroLevel(uid string, taskId int32, tp *pb.TaskParam) *pb.DBTask {
if task, ok := this.checkTask(uid, taskId); ok {
var progress int32
// 任务完成
if tp.Second >= task.Progress {
progress = 0
//修改玩家任务状态和进度
update := map[string]interface{}{
"progress": progress,
"status": 1,
}
update["status"] = 1
if err := this.modifyUserTask(task.Uid, task.Id, update); err != nil {
log.Errorf("err %v", err)
return nil
@ -212,6 +219,7 @@ func (this *ModelTask) UpHeroLevel(uid string, taskId int32, tp *pb.TaskParam) *
task.Status = 1
return task
} else {
// 任务未完成
progress = task.Progress - tp.Second
if progress <= 0 {
progress = 0

View File

@ -56,18 +56,10 @@ func (this *ModuleTask) InitTaskAll(uid string) {
}
//重置任务
func (this *ModuleTask) ResetTask(uid string, taskTag comm.TaskTag) {
if err := this.modelTask.clearTask(uid, taskTag); err != nil {
log.Errorf("uid:%v tag:%v ResetTask err:%v", uid, taskTag, err)
return
}
func (this *ModuleTask) ResetTask(uid string) {
this.modelTask.clearTask(uid)
this.modelTaskActive.clearTask(uid)
this.InitTaskAll(uid)
if err := this.modelTaskActive.clearTask(uid, taskTag); err != nil {
log.Errorf("uid:%v tag:%v ResetTaskActive err:%v", uid, taskTag, err)
return
}
// this.modelTaskActive.initActiveRewardByTag(uid, taskTag)
}
//任务处理
@ -96,13 +88,8 @@ func (this *ModuleTask) CreateTaskForStrategy(uid string, heroCfgId int32) {
// 清理任务数据
func (this *ModuleTask) CleanData(uid string) {
this.modelTask.clearTask(uid, comm.TASK_DAILY)
this.modelTask.clearTask(uid, comm.TASK_WEEKLY)
this.modelTask.clearTask(uid, comm.TASK_ACHIEVE)
this.modelTask.clearTask(uid, comm.TASK_STRATEGY)
this.modelTaskActive.clearTask(uid, comm.TASK_DAILY)
this.modelTaskActive.clearTask(uid, comm.TASK_WEEKLY)
this.modelTask.clearTask(uid)
this.modelTaskActive.clearTask(uid)
}
//任务处理器注册

View File

@ -2,7 +2,9 @@ package user
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
event_v2 "go_dreamfactory/lego/sys/event/v2"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
@ -21,11 +23,17 @@ const ( //Redis
type ModelUser struct {
modules.MCompModel
moduleUser *User
eventApp *event_v2.App
}
func (this *ModelUser) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
err = this.MCompModel.Init(service, module, comp, options)
this.TableName = string(TableUser)
this.moduleUser = module.(*User)
this.eventApp = event_v2.NewApp()
this.eventApp.Listen(comm.EventUserChanged, this.ChangeExp)
this.eventApp.Listen(comm.EventUserChanged, this.ChangeLevel)
return
}
@ -125,7 +133,39 @@ func (this *ModelUser) modifyName(uid string, newName string) (code pb.ErrorCode
return
}
//
func(this *ModelUser) UpLevel(){
// change exp
func (this *ModelUser) ChangeExp(event interface{}, next func(event interface{})) {
ul := event.(*UserListen)
// TODO
next(ul)
}
//change level
func (this *ModelUser) ChangeLevel(event interface{}, next func(event interface{})) {
ul := event.(*UserListen)
curLv := ul.lv
curLvConf := this.moduleUser.configure.GetPlayerlvConf(curLv)
nextLvConf := this.moduleUser.configure.GetPlayerlvConf(curLv + 1)
if curLvConf.Exp == 0 || nextLvConf == nil { //最大等级
next(ul)
return
}
if ul.exp > curLvConf.Exp && ul.exp <= nextLvConf.Exp {
ul.lv++
// 更新等级
update := map[string]interface{}{
"lv": ul.lv,
}
this.moduleUser.modelUser.Change(ul.session.GetUserId(), update)
}
}
//玩家信息监听
type UserListen struct {
event_v2.Event
session comm.IUserSession
exp int32
lv int32
}

View File

@ -172,3 +172,14 @@ func (this *User) GetUserRecordData(uid string, typeValue int32, parmare int32)
//pb.DBUserRecord
return
}
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
}
this.modelUser.eventApp.Dispatch(comm.EventUserChanged, ul)
}

View File

@ -25,7 +25,11 @@ func (Game_monsterData) GetTypeId() int {
func NewGame_monsterData(_buf map[string]interface{}) (_v *Game_monsterData, err error) {
_v = &Game_monsterData{}
{ var _ok_ bool; var _tempNum_ float64; if _tempNum_, _ok_ = _buf["monster_id"].(float64); !_ok_ { err = errors.New("monster_id error"); return }; _v.MonsterId = int32(_tempNum_) }
<<<<<<< HEAD
{ var _ok_ bool; if _v.HeroId, _ok_ = _buf["hero_id"].(string); !_ok_ { err = errors.New("hero_id error"); return } }
=======
{ var _ok_ bool; var _tempNum_ float64; if _tempNum_, _ok_ = _buf["hero_id"].(float64); !_ok_ { err = errors.New("hero_id error"); return }; _v.HeroId = int32(_tempNum_) }
>>>>>>> bb00032 (玩家等级优化)
{var _ok_ bool; var __json_text__ map[string]interface{}; if __json_text__, _ok_ = _buf["name"].(map[string]interface{}) ; !_ok_ { err = errors.New("_v.Name error"); return }; { var _ok_ bool; if _, _ok_ = __json_text__["key"].(string); !_ok_ { err = errors.New("key error"); return } }; { var _ok_ bool; if _v.Name, _ok_ = __json_text__["text"].(string); !_ok_ { err = errors.New("text error"); return } } }
{ var _ok_ bool; var _tempNum_ float64; if _tempNum_, _ok_ = _buf["star"].(float64); !_ok_ { err = errors.New("star error"); return }; _v.Star = int32(_tempNum_) }
{ var _ok_ bool; if _v.Equip, _ok_ = _buf["equip"].(string); !_ok_ { err = errors.New("equip error"); return } }