role.go 5.49 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
	Prop  *PropModel

	lastSaveTs int64
}

func RoleExistByUid(uid string) *RoleModel {
	data := &pb.Role{Uid: uid}

	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),
		Prop:    new(PropModel),
	}
	r.Load()
	r.LoadAll()
	return r
}

func NewRole(id string) *RoleModel {
	data := &pb.Role{Id: id}
	m := &RoleModel{
		ISchema: NewSchema(id, data),
		Role:    data,
		Heros:   make(SchemaMap),
		Teams:   make(SchemaMap),
	}
	return m
}

func (m *RoleModel) IncreByKey(key string, detal int64) int64 {
	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 + common.MaxCommNum
}

func (m *RoleModel) InitRole() {
	//init hero
	h1 := pb.Hero{
		Id:         fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("hero", 1)),
		RoleId:     m.Role.Id,
		Type:       1,
		Level:      1,
		ReinCount:  0,
		ReinPoint:  0,
		Equipments: "",
	}
	m.AddHero(&h1)

	h2 := h1
	h2.Id = fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("hero", 1))
	h2.Type = 2
	m.AddHero(&h2)

	h3 := h1
	h3.Id = fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("hero", 1))
	h3.Type = 3
	m.AddHero(&h3)

	h4 := h1
	h4.Id = fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("hero", 1))
	h4.Type = 4
	m.AddHero(&h4)

	//init team
	t1 := pb.Team{
		Id:      fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("team", 1)),
		RoleId:  m.Role.Id,
		HeroId1: h1.Id,
		HeroId2: h2.Id,
		HeroId3: h3.Id,
	}
	m.AddTeam(&t1)

	t2 := t1
	t2.Id = fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("team", 1))
	m.AddTeam(&t2)

	t3 := t1
	t3.Id = fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("team", 1))
	m.AddTeam(&t3)

	t4 := t1
	t4.Id = fmt.Sprintf("%s%d", m.Role.Id, m.IncreByKey("team", 1))
	m.AddTeam(&t4)
}

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) LoadAll() {
	m.LoadHero()
	m.LoadTeams()
}

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

func (m *RoleModel) UpdateProperties(conn components.IConnection, 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.UpdateRolePropertyRsp{
		Id:   ids,
		Role: role,
	}
	if rsp, err := proto.Marshal(update); err != nil {
		logger.Error("id %s, err:", m.Role.Id, err)
		return
	} else {
		if conn != nil && notify {
			conn.Send(0, uint32(pb.ProtoCode_UpdateRolePropertyRsp), 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) AddHero(hero *pb.Hero) {
	h := NewHero(hero)
	h.Create()
	m.Heros[hero.Id] = h
}

func (m *RoleModel) AddTeam(team *pb.Team) {
	t := NewTeam(team)
	t.Create()
	m.Teams[team.Id] = t
}

func (m *RoleModel) UpdateTeam(teams []*pb.Team) {
	for _, team := range teams {
		team.RoleId = m.Role.Id
		t := m.Teams[team.Id]
		if t != nil {
			t.UpdateSchema(team)
		}
	}
}

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}
	for _, mpObj := range mpObjs {
		for _, v := range mpObj {
			if v != nil {
				v.Update()
			}
		}
	}
}

func (m *RoleModel) IncrPropertyChan(conn components.IConnection, key string, val int64) {
	if conn != nil {
		conn.CustomChan() <- func() {
			m.IncrProperty(key, val)
		}
	} else {
		m.IncrProperty(key, val)
	}

}

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

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

}