game_sync/worldsrv/privatescene.go

277 lines
7.2 KiB
Go

package main
import (
"container/list"
"fmt"
"mongo.games.com/game/common"
"mongo.games.com/game/model"
"mongo.games.com/game/proto"
hall_proto "mongo.games.com/game/protocol/gamehall"
"mongo.games.com/goserver/core/basic"
"mongo.games.com/goserver/core/task"
"strconv"
"time"
)
const (
PrivateSceneState_Deleting = iota //删除中
PrivateSceneState_Deleted //已删除
)
var PrivateSceneMgrSington = &PrivateSceneMgr{
pps: make(map[int32]*PlayerPrivateScene),
}
type PlayerPrivateScene struct {
snid int32 // 玩家id
creatorName string //创建人昵称
platform string // 平台名称
channel string // 渠道名称
promoter string // 推广员
packageTag string // 推广包标识
scenes map[int]*Scene
logsByDay map[int]*list.List
dupLog map[string]struct{}
loaded bool
}
func (pps *PlayerPrivateScene) AddScene(s *Scene) {
pps.scenes[s.sceneId] = s
}
func (pps *PlayerPrivateScene) GetScene(sceneId int) *Scene {
if s, exist := pps.scenes[sceneId]; exist {
return s
}
return nil
}
func (pps *PlayerPrivateScene) GetCount() int {
return len(pps.scenes)
}
func (pps *PlayerPrivateScene) CanDelete() bool {
return !pps.loaded && len(pps.scenes) == 0
}
func (pps *PlayerPrivateScene) OnPlayerLogin(p *Player) {
}
func (pps *PlayerPrivateScene) OnPlayerLogout(p *Player) {
pps.logsByDay = nil
pps.loaded = false
}
func (pps *PlayerPrivateScene) OnCreateScene(p *Player, s *Scene) {
pps.scenes[s.sceneId] = s
}
func (pps *PlayerPrivateScene) LoadLogs(p *Player, yyyymmdd int32) {
if !pps.loaded {
var logs []*model.PrivateSceneLog
var err error
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
logs, err = model.GetPrivateSceneLogBySnId(p.Platform, p.SnId, model.GameParamData.PrivateSceneLogLimit)
return nil
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
if err == nil {
pps.loaded = true
pps.TidyLog(logs)
pps.SendLogs(p, yyyymmdd)
}
}), "GetPrivateSceneLogBySnId").Start()
} else {
pps.SendLogs(p, yyyymmdd)
}
}
func (pps *PlayerPrivateScene) TidyLog(logs []*model.PrivateSceneLog) {
if pps.logsByDay == nil {
pps.logsByDay = make(map[int]*list.List)
}
for _, log := range logs {
if _, exist := pps.dupLog[log.LogId.Hex()]; exist {
continue
}
y, m, d := log.CreateTime.Date()
day := y*10000 + int(m)*100 + d
if lst, exist := pps.logsByDay[day]; exist {
lst.PushBack(log)
} else {
lst = list.New()
pps.logsByDay[day] = lst
lst.PushBack(log)
}
}
pps.dupLog = nil
}
func (pps *PlayerPrivateScene) SendLogs(p *Player, yyyymmdd int32) {
pack := &hall_proto.SCGetPrivateRoomHistory{
QueryTime: proto.Int32(yyyymmdd),
}
if logs, exist := pps.logsByDay[int(yyyymmdd)]; exist {
for e := logs.Front(); e != nil; e = e.Next() {
if log, ok := e.Value.(*model.PrivateSceneLog); ok {
data := &hall_proto.PrivateRoomHistory{
GameFreeId: proto.Int32(log.GameFreeId),
RoomId: proto.Int32(log.SceneId),
CreateTime: proto.Int32(int32(log.CreateTime.Unix())),
DestroyTime: proto.Int32(int32(log.DestroyTime.Unix())),
CreateFee: proto.Int32(log.CreateFee),
}
pack.Datas = append(pack.Datas, data)
}
}
}
proto.SetDefaults(pack)
p.SendToClient(int(hall_proto.GameHallPacketID_PACKET_SC_GETPRIVATEROOMHISTORY), pack)
}
func (pps *PlayerPrivateScene) PushLog(log *model.PrivateSceneLog) {
if log == nil {
return
}
y, m, d := log.CreateTime.Date()
day := y*10000 + int(m)*100 + d
if lst, exist := pps.logsByDay[day]; exist {
lst.PushFront(log)
} else {
lst = list.New()
pps.logsByDay[day] = lst
lst.PushFront(log)
}
if !pps.loaded {
pps.dupLog[log.LogId.Hex()] = struct{}{}
}
}
func (pps *PlayerPrivateScene) SendPrivateScenes(p *Player) {
pack := &hall_proto.SCGetPrivateRoomList{}
for sceneid, s := range pps.scenes {
data := &hall_proto.PrivateRoomInfo{
GameFreeId: proto.Int32(s.dbGameFree.GetId()),
RoomId: proto.Int(sceneid),
CurrRound: proto.Int32(s.currRound),
MaxRound: proto.Int32(s.totalRound),
CurrNum: proto.Int(len(s.players)),
MaxPlayer: proto.Int(s.playerNum),
CreateTs: proto.Int32(int32(s.createTime.Unix())),
}
pack.Datas = append(pack.Datas, data)
}
proto.SetDefaults(pack)
p.SendToClient(int(hall_proto.GameHallPacketID_PACKET_SC_GETPRIVATEROOMLIST), pack)
}
type PrivateSceneMgr struct {
pps map[int32]*PlayerPrivateScene
}
func (psm *PrivateSceneMgr) GetOrCreatePlayerPrivateScene(p *Player) *PlayerPrivateScene {
snid := p.SnId
if pps, exist := psm.pps[snid]; exist {
return pps
}
pps := &PlayerPrivateScene{
snid: snid,
creatorName: p.Name,
platform: p.Platform,
channel: p.Channel,
promoter: strconv.Itoa(int(p.PromoterTree)),
packageTag: p.PackageID,
scenes: make(map[int]*Scene),
logsByDay: make(map[int]*list.List),
dupLog: make(map[string]struct{}),
}
psm.pps[snid] = pps
return pps
}
func (psm *PrivateSceneMgr) GetPlayerPrivateScene(snid int32) *PlayerPrivateScene {
if pps, exist := psm.pps[snid]; exist {
return pps
}
return nil
}
func (psm *PrivateSceneMgr) OnDestroyScene(scene *Scene) {
if scene == nil {
return
}
if !scene.IsPrivateScene() {
return
}
pps := psm.GetPlayerPrivateScene(scene.creator)
if pps != nil {
if pps.GetScene(scene.sceneId) == scene {
delete(pps.scenes, scene.sceneId)
var tax int32
var returnCoin int32
p := PlayerMgrSington.GetPlayerBySnId(scene.creator)
if scene.currRound == 0 && !scene.starting && scene.createFee > 0 { //未开始
if scene.manualDelete && time.Now().Sub(scene.createTime) < time.Second*time.Duration(model.GameParamData.PrivateSceneFreeDistroySec) { //低于指定时间,要扣除部分费用
tax = scene.createFee * int32(model.GameParamData.PrivateSceneDestroyTax) / 100
returnCoin = scene.createFee - tax
} else {
returnCoin = scene.createFee
}
if returnCoin > 0 {
if p != nil {
var remark string
if tax > 0 {
remark = fmt.Sprintf("提前解散扣除费用%.02f", float32(tax)/100.0)
}
p.AddCoin(int64(returnCoin), 0, common.GainWay_PrivateSceneReturn, "", remark)
} else {
//TODO 发送邮件
//sendClubMail_ClubCreateRoomRefund(scene.creator, scene.limitPlatform.Name, int32(scene.sceneId), int64(tax), int64(returnCoin))
}
}
}
if p != nil {
pack := &hall_proto.SCDestroyPrivateRoom{
OpRetCode: hall_proto.OpResultCode_Game_OPRC_Sucess_Game,
RoomId: proto.Int(scene.sceneId),
State: proto.Int(PrivateSceneState_Deleted),
}
proto.SetDefaults(pack)
p.SendToClient(int(hall_proto.GameHallPacketID_PACKET_SC_DESTROYPRIVATEROOM), pack)
}
//写log
log := model.NewPrivateSceneLog()
if log != nil {
log.SnId = pps.snid
log.Platform = pps.platform
log.Channel = pps.channel
log.Promoter = pps.promoter
log.GameFreeId = scene.dbGameFree.GetId()
log.SceneId = int32(scene.sceneId)
log.CreateTime = scene.createTime
log.DestroyTime = time.Now()
if returnCoin > 0 {
log.CreateFee = tax
} else {
log.CreateFee = scene.createFee
}
//PrivateSceneLogChannelSington.Write(log)
pps.PushLog(log)
}
if pps.CanDelete() && p == nil {
delete(psm.pps, scene.creator)
}
}
}
}