222 lines
5.5 KiB
Go
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)
|
|
}
|