game.go 2.95 KB
package service

import (
	"math/rand"
	_ "net/http/pprof"
	"pro2d/cmd/gameserver/action"
	"pro2d/common"
	"pro2d/common/components"
	"pro2d/common/db/mongoproxy"
	"pro2d/common/db/redisproxy"
	"pro2d/common/logger"
	"pro2d/models"
	"time"
)

type GameServer struct {
	components.IServer
}

func NewGameServer() (*GameServer, error) {
	sconf := common.GlobalSconf
	s := &GameServer{}

	options := []components.ServerOption{
		components.WithPlugin(components.NewPlugin(sconf.PluginPath)),

		components.WithConnCbk(s.OnConnection),
		components.WithMsgCbk(s.OnMessage),
		components.WithCloseCbk(s.OnClose),
		components.WithTimerCbk(s.OnTimer),
	}
	//加密
	if sconf.Encipher {
		options = append(options, components.WithSplitter(components.NewPBSplitter(components.NewAesEncipher())))
		logger.Debug("open encipher aes...")
	} else {
		options = append(options, components.WithSplitter(components.NewPBSplitter(nil)))
	}

	//设置逻辑处理的handler
	iserver := components.NewServer(sconf.Port, options...)
	iserver.SetActions(action.GetActionMap())
	s.IServer = iserver

	//mgo init
	err := mongoproxy.ConnectMongo(sconf.MongoConf, sconf.ID)
	if err != nil {
		return nil, err
	}

	//redis init
	if err = redisproxy.ConnectRedis(sconf.RedisConf.DB, sconf.RedisConf.Auth, sconf.RedisConf.Address); err != nil {
		return nil, err
	}

	//Etcd 初始化
	//err = etcd.NewEtcdClient(common.GlobalConf.Etcd)
	//if err != nil {
	//	return nil, err
	//}
	//etcd.PutWithLeasePrefix(sconf.Name, fmt.Sprintf("%d", sconf.ID), fmt.Sprintf("%s:%d", sconf.IP, sconf.Port), 5)

	//设置服务器ID & game
	models.NewDBSeed(sconf.ID).InitServerDatabase(models.GameModels())
	models.DBSeedS().InitAutoIncreUidTable(models.GameModels())

	return s, nil
}

func (s *GameServer) Timeout() {
	//每秒中保存一下自增ID
	models.DBSeedS().SaveAutoincrementTimer(models.GameModels())

	components.TimeOut(1*time.Second, s.Timeout)
}

func (s *GameServer) Start() error {
	//设置随机种子
	rand.Seed(time.Now().Unix())

	//启动定时器
	s.Timeout()

	return s.IServer.Start()
}

func (s *GameServer) Stop() {
	s.IServer.Stop()

	mongoproxy.CloseMongo()
	redisproxy.CloseRedis()
}

func (s *GameServer) OnConnection(conn components.IConnection) {
	agent := NewAgent(s)
	agent.OnConnection(conn)
	s.GetConnManage().AddConn(conn.GetID(), agent)
}

func (s *GameServer) OnMessage(msg components.IMessage) {
	agent := s.GetConnManage().GetConn(msg.GetSID())
	if agent == nil {
		return
	}
	err := agent.(*Agent).OnMessage(msg)
	if err != nil {
		logger.Error("%d, onmessage err: %s", agent.GetID(), err.Error())
		s.OnClose(agent)
	}
}

func (s *GameServer) OnTimer(conn components.IConnection) {
	agent := s.GetConnManage().GetConn(conn.GetID())
	if agent == nil {
		return
	}
	agent.(*Agent).OnTimer()
}

func (s *GameServer) OnClose(conn components.IConnection) {
	connID := conn.GetID()
	agent := s.GetConnManage().GetConn(connID)
	if agent == nil {
		return
	}
	agent.(*Agent).OnClose()
	s.GetConnManage().DelConn(connID)
}