role.go 6.08 KB
package models

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"pro2d/common"
	"pro2d/common/components"
	"pro2d/common/db/mongoproxy"
	"pro2d/common/logger"
	"pro2d/pb"
	"sync/atomic"
)

type RoleModel struct {
	components.ISchema
	Role       *pb.Role
	Heros      SchemaMap
	Teams      SchemaMap
	Equipments SchemaMap
	Prop       *PropModel
	Items      common.IMapString //背包

	lastSaveTs int64
}

func RoleExistByUid(uid string) *RoleModel {
	data := &pb.Role{Uid: uid, Incres: make(map[string]uint32)}

	if err := mongoproxy.FindOne(mongoproxy.GetCollName(data), mongoproxy.GetBsonM("uid", uid), data); err != nil {
		logger.Error("Role not exist err: %v", err)
		return nil
	}

	r := &RoleModel{
		ISchema:    NewSchema(data.Id, data),
		Role:       data,
		Heros:      make(SchemaMap),
		Teams:      make(SchemaMap),
		Equipments: make(SchemaMap),
		Prop:       new(PropModel),
		Items:      make(common.IMapString),
	}
	r.Load()
	r.LoadAll()
	return r
}

func NewRole(id string) *RoleModel {
	data := &pb.Role{Id: id, Incres: make(map[string]uint32)}
	m := &RoleModel{
		ISchema:    NewSchema(id, data),
		Role:       data,
		Heros:      make(SchemaMap),
		Teams:      make(SchemaMap),
		Equipments: make(SchemaMap),
		Prop:       new(PropModel),
		Items:      make(common.IMapString),
	}
	return m
}

func (m *RoleModel) IncreByKey(key string, detal uint32) uint32 {
	v, ok := m.Role.Incres[key]
	if !ok {
		v = detal
	} else {
		v += detal
	}
	m.Role.Incres[key] = v
	m.SetProperty("incres", m.Role.Incres)
	return v
}

func (m *RoleModel) IncreHearByKey(detal uint32) string {
	return fmt.Sprintf("%s%04d", m.Role.Id, m.IncreByKey("hero", detal))
}

func (m *RoleModel) IncreTeamByKey(detal uint32) string {
	return fmt.Sprintf("%s%02d", m.Role.Id, m.IncreByKey("team", detal))
}

func (m *RoleModel) IncreEquipByKey(detal uint32) string {
	return fmt.Sprintf("%s%04d", m.Role.Id, m.IncreByKey("equipment", detal))
}

func (m *RoleModel) InitRole() {
	//init hero
	h1 := pb.Hero{
		Id:        m.IncreHearByKey(1),
		RoleId:    m.Role.Id,
		Type:      1,
		Level:     1,
		ReinCount: 0,
		ReinPoint: 0,
	}
	m.AddHero(&h1)

	h2 := h1
	h2.Id = m.IncreHearByKey(1)
	h2.Type = 2
	m.AddHero(&h2)

	h3 := h1
	h3.Id = m.IncreHearByKey(1)
	h3.Type = 3
	m.AddHero(&h3)

	h4 := h1
	h4.Id = m.IncreHearByKey(1)
	h4.Type = 4
	m.AddHero(&h4)

	//init team
	t1 := pb.Team{
		Id:      m.IncreTeamByKey(1),
		RoleId:  m.Role.Id,
		HeroId1: h1.Id,
		HeroId2: h2.Id,
		HeroId3: h3.Id,
	}
	m.AddTeam(&t1)

	t2 := t1
	t2.Id = m.IncreTeamByKey(1)
	m.AddTeam(&t2)

	t3 := t1
	t3.Id = m.IncreTeamByKey(1)
	m.AddTeam(&t3)

	t4 := t1
	t4.Id = m.IncreTeamByKey(1)
	m.AddTeam(&t4)

	m.Update()
}

func (m *RoleModel) LoadHero() {
	heros := make([]*pb.Hero, 10)
	err := mongoproxy.FindMany("hero", "roleid", m.Role.Id, &heros)
	if err != nil {
		logger.Error(err)
		return
	}
	for _, hero := range heros {
		m.Heros[hero.Id] = NewHero(hero)
	}
}

func (m *RoleModel) LoadTeams() {
	teams := make([]*pb.Team, 4)
	err := mongoproxy.FindMany("team", "roleid", m.Role.Id, &teams)
	if err != nil {
		logger.Error(err)
		return
	}
	for _, team := range teams {
		m.Teams[team.Id] = NewTeam(team)
	}
}

//加载背包数据到内存
func (m *RoleModel) LoadItems() {
	m.Items = common.StringToMap(m.Role.Items)
}

func (m *RoleModel) LoadEquipments() {
	data := make([]*pb.Equipment, 10)
	err := mongoproxy.FindMany("equipment", "roleid", m.Role.Id, &data)
	if err != nil {
		logger.Error(err)
		return
	}
	for _, d := range data {
		m.Equipments[d.Id] = NewEquip(d)
	}
}

func (m *RoleModel) LoadAll() {
	m.LoadHero()
	m.LoadTeams()
	m.LoadItems()
	m.LoadEquipments()
}

func (m *RoleModel) UpdateProperty(key string, val interface{}, notify bool) {
	m.UpdateProperties(map[string]interface{}{key: val}, notify)
}

func (m *RoleModel) UpdateProperties(property map[string]interface{}, notify bool) {
	if len(property) < 1 {
		return
	}

	role := &pb.Role{}
	ids := m.ParseFields(role.ProtoReflect(), property)
	if len(ids) == 0 {
		logger.Error("ParseFields err, len is 0")
		return
	}

	update := &pb.RoleUpdatePropertyRsp{
		Id:   ids,
		Role: role,
	}
	if rsp, err := proto.Marshal(update); err != nil {
		logger.Error("id %s, err:", m.Role.Id, err)
		return
	} else {
		if m.GetConn() != nil && notify {
			m.GetConn().Send(0, uint32(pb.ProtoCode_RoleUpdatePropertyRsp), rsp)
		}
	}
}

func (m *RoleModel) GetAllHero() []*pb.Hero {
	var h []*pb.Hero
	for _, hero := range m.Heros {
		h = append(h, hero.(*HeroModel).Hero)
	}
	return h
}

func (m *RoleModel) GetAllTeam() []*pb.Team {
	var t []*pb.Team
	for _, team := range m.Teams {
		t = append(t, team.(*TeamModel).Team)
	}
	return t
}

func (m *RoleModel) GetEquipments() []*pb.Equipment {
	var equips []*pb.Equipment
	for _, e := range m.Equipments {
		equips = append(equips, e.(*EquipModel).Equip)
	}
	return equips
}

func (m *RoleModel) OnRecoverTimer(now int64) {
	m.SaveRoleData(now)
}

func (m *RoleModel) OnOfflineEvent() {
	// 设置最新的登录时间
	m.SaveRoleData(common.Timex())
}

func (m *RoleModel) SaveRoleData(now int64) {
	if now > 0 && now-m.lastSaveTs < common.SaveDataInterval {
		return
	}
	atomic.StoreInt64(&m.lastSaveTs, now)
	m.Update()

	tbObjs := []components.ISchema{}
	for _, tbObj := range tbObjs {
		if tbObj != nil {
			tbObj.Update()
		}
	}

	mpObjs := []SchemaMap{m.Heros, m.Teams, m.Equipments}
	for _, mpObj := range mpObjs {
		for _, v := range mpObj {
			if v != nil {
				v.Update()
			}
		}
	}
}

func (m *RoleModel) IncrPropertyChan(key string, val int64, notify bool) {
	if m.GetConn() != nil {
		m.GetConn().CustomChan() <- func() {
			incr := m.IncrProperty(key, val)
			m.UpdateProperty(key, incr, notify)
		}
	} else {
		m.IncrProperty(key, val)
	}

}

func (m *RoleModel) UpdatePropertyChan(key string, val interface{}, notify bool) {
	if m.GetConn() != nil {
		m.GetConn().CustomChan() <- func() {
			m.UpdateProperties(map[string]interface{}{key: val}, notify)
		}
	} else {
		m.UpdateProperties(map[string]interface{}{key: val}, notify)
	}
}

func (m *RoleModel) SaveRoleDataChan(now int64) {
	if m.GetConn() != nil {
		m.GetConn().CustomChan() <- func() {
			m.SaveRoleData(now)
		}
	} else {
		m.SaveRoleData(now)
	}

}