ecs/servers/game/logic/manager_server.go
2025-07-16 10:05:22 +08:00

222 lines
5.5 KiB
Go

package logic
import (
"fmt"
"github.com/oylshe1314/framework/client/db"
"github.com/oylshe1314/framework/config"
"github.com/oylshe1314/framework/errors"
"github.com/oylshe1314/framework/server"
"github.com/oylshe1314/framework/util"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"time"
)
const TableServer string = "server"
func TableServerKey(name string, appId uint32) string {
return fmt.Sprint(name, "_", appId)
}
type ServerInfo struct {
Key string `bson:"_id"`
Name string `bson:"name"`
AppId uint32 `bson:"app_id"`
CreateTime int64 `bson:"create_time"`
Creations uint32 `bson:"creations"`
MaxOnline uint32 `bson:"max_online"`
MaxOnlineTime int64 `bson:"max_online_time"`
}
type AreaConfig struct {
Id uint32 `json:"id"` //服务器ID
Platform uint32 `json:"platform"` //平台
Channel uint32 `json:"channel"` //渠道
Area string `json:"area"` //大区
Name string `json:"name"` //名称
}
type ServerConfig struct {
DataDir string `json:"dataDir"`
MaxRoles int `json:"maxRoles"`
OpenTime string `json:"openTime"`
AreaConfig *AreaConfig `json:"areaConfig"`
}
type ServerManager struct {
manager
closed bool
mongoClient db.MongoClient
eventManager *EventManager
info *ServerInfo
config *ServerConfig
dirty bool //数据是否有更新
creations uint32 //服务器总创建人数
online uint32 //当前在线人数
maxOnline uint32 //历史最大在线人数
maxOnlineTime int64 //历史最大在线时间人数
}
func NewServerManager(svr server.Server, mongoClient db.MongoClient, config *ServerConfig, eventManager *EventManager) *ServerManager {
return &ServerManager{
manager: manager{
server: svr,
},
mongoClient: mongoClient,
config: config,
eventManager: eventManager,
}
}
func (this *ServerManager) Init() error {
if this.mongoClient == nil {
return errors.Error("'mongoClient' is nil")
}
if this.eventManager == nil {
return errors.Error("'eventManager' is nil")
}
var err = this.initData()
if err != nil {
return err
}
this.run()
return nil
}
func (this *ServerManager) initData() error {
var info = &ServerInfo{Key: TableServerKey(this.server.Name(), this.server.AppId())}
var err = this.mongoClient.Collection(TableServer).FindOne(this.mongoClient.Context(), bson.M{"_id": info.Key}).Decode(info)
if err != nil {
if !errors.Is(err, mongo.ErrNoDocuments) {
return err
}
info.Name = this.server.Name()
info.AppId = this.server.AppId()
info.CreateTime = util.NowUnix()
info.Creations = 0
info.MaxOnline = 0
info.MaxOnlineTime = 0
_, err = this.mongoClient.Collection(TableServer).InsertOne(this.mongoClient.Context(), info)
if err != nil {
return err
}
//TODO 其他数据库初始化操作
// 创建玩家昵称索引
//_, err = this.mongoClient.Collection(TablePlayer).Indexes().CreateOne(this.mongoClient.Context(), mongo.IndexModel{Keys: bson.M{"role.name": 1}})
//if err != nil {
// return err
//}
}
this.info = info
return nil
}
func (this *ServerManager) Close() error {
this.closed = true
return nil
}
func (this *ServerManager) saveData() {
var set = bson.M{}
if this.creations != this.info.Creations {
this.info.Creations = this.creations
set["creations"] = this.info.Creations
}
if this.maxOnline != this.info.MaxOnline {
this.info.MaxOnline = this.maxOnline
set["max_online"] = this.info.MaxOnline
}
if this.maxOnlineTime != this.info.MaxOnlineTime {
this.info.MaxOnlineTime = this.maxOnlineTime
set["max_online_time"] = this.info.MaxOnlineTime
}
if len(set) > 0 {
go func(set bson.M) {
_, err := this.mongoClient.Collection(TableServer).UpdateByID(this.mongoClient.Context(), this.info.Key, bson.M{"$set": set})
if err != nil {
this.Logger().Error("Save server data error, ", err)
}
}(set)
}
}
func (this *ServerManager) run() {
go func() {
var rt = 60 - util.NowUnix()%60
if rt > 0 {
time.Sleep(time.Second * time.Duration(rt))
}
var ticker = time.NewTicker(time.Minute)
defer ticker.Stop()
for {
if this.closed {
return
}
if this.dirty {
this.dirty = false
this.saveData()
//this.eventManager.ServerOnline(LogTypeServerOnline, this.server.AppId(), this.creations, this.online, this.offline, this.maxOnline, this.maxOnlineTime)
}
_, ok := <-ticker.C
if !ok {
return
}
}
}()
}
func (this *ServerManager) Info() *ServerInfo { return this.info }
func (this *ServerManager) Config() *ServerConfig { return this.config }
func (this *ServerManager) Creations() uint32 { return this.creations }
func (this *ServerManager) MaxOnline() uint32 { return this.maxOnline }
func (this *ServerManager) MaxOnlineTime() int64 { return this.maxOnlineTime }
func (this *ServerManager) AddCreations(value uint32) {
this.creations += value
this.dirty = true
}
func (this *ServerManager) AddOnline(value uint32) {
this.online += value
if this.online > this.maxOnline {
this.maxOnline = this.online
this.maxOnlineTime = util.NowUnix()
}
this.dirty = true
}
func (this *ServerManager) ReduceOnline(value uint32) {
if this.online > 0 {
this.online -= value
this.dirty = true
}
}
func (this *ServerManager) Online() uint32 {
return this.online
}
func (this *ServerManager) Reload() error {
configServer, ok := this.server.(config.Server)
if !ok {
return errors.Error("unsupported data reload")
}
return configServer.Load(this.config.DataDir)
}