Skip to content

Commit

Permalink
Merge pull request #64 from xiaonanln/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
xiaonanln committed Feb 11, 2018
2 parents 9ed139f + b4b00d8 commit 9bcf260
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 79 deletions.
33 changes: 20 additions & 13 deletions components/dispatcher/DispatcherService.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ func (service *DispatcherService) messageLoop() {
service.handleDoSomethingOnSpecifiedClient(dcp, pkt)
} else if msgtype == proto.MT_CALL_ENTITY_METHOD_FROM_CLIENT {
service.handleCallEntityMethodFromClient(dcp, pkt)
} else if msgtype == proto.MT_QUERY_SPACE_GAMEID_FOR_MIGRATE {
service.handleQuerySpaceGameIDForMigrate(dcp, pkt)
} else if msgtype == proto.MT_MIGRATE_REQUEST {
service.handleMigrateRequest(dcp, pkt)
} else if msgtype == proto.MT_REAL_MIGRATE {
Expand Down Expand Up @@ -616,28 +618,33 @@ func (service *DispatcherService) handleCallFilteredClientProxies(dcp *dispatche
service.broadcastToGateClients(pkt)
}

func (service *DispatcherService) handleMigrateRequest(dcp *dispatcherClientProxy, pkt *netutil.Packet) {
entityID := pkt.ReadEntityID()
spaceID := pkt.ReadEntityID()
func (service *DispatcherService) handleQuerySpaceGameIDForMigrate(dcp *dispatcherClientProxy, pkt *netutil.Packet) {
spaceid := pkt.ReadEntityID()
if consts.DEBUG_PACKETS {
gwlog.Debugf("Entity %s is migrating to space %s", entityID, spaceID)
gwlog.Debugf("%s.handleQuerySpaceGameIDForMigrate: spaceid=%s", service, spaceid)
}

// mark the entity as migrating

spaceDispatchInfo := service.entityDispatchInfos[spaceID]
var spaceLoc uint16
spaceDispatchInfo := service.entityDispatchInfos[spaceid]
var gameid uint16
if spaceDispatchInfo != nil {
spaceLoc = spaceDispatchInfo.gameid
gameid = spaceDispatchInfo.gameid
}
pkt.AppendUint16(gameid)
// send the packet back
dcp.SendPacket(pkt)
}

pkt.AppendUint16(spaceLoc) // append the space game location to the packet
func (service *DispatcherService) handleMigrateRequest(dcp *dispatcherClientProxy, pkt *netutil.Packet) {
entityID := pkt.ReadEntityID()
spaceID := pkt.ReadEntityID()
spaceGameID := pkt.ReadUint16()

if spaceLoc > 0 { // almost true
entityDispatchInfo := service.setEntityDispatcherInfoForWrite(entityID)
entityDispatchInfo.blockRPC(consts.DISPATCHER_MIGRATE_TIMEOUT)
if consts.DEBUG_PACKETS {
gwlog.Debugf("Entity %s is migrating to space %s @ game%d", entityID, spaceID, spaceGameID)
}

entityDispatchInfo := service.setEntityDispatcherInfoForWrite(entityID)
entityDispatchInfo.blockRPC(consts.DISPATCHER_MIGRATE_TIMEOUT)
dcp.SendPacket(pkt)
}

Expand Down
63 changes: 36 additions & 27 deletions components/game/GameService.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const (
rsFreezed
)

type _GameService struct {
type GameService struct {
config *config.GameConfig
id uint16
gameDelegate IGameDelegate
Expand All @@ -50,8 +50,8 @@ type _GameService struct {
//collectEntitySycnInfosReply chan interface{}
}

func newGameService(gameid uint16, delegate IGameDelegate) *_GameService {
return &_GameService{
func newGameService(gameid uint16, delegate IGameDelegate) *GameService {
return &GameService{
id: gameid,
gameDelegate: delegate,
//registeredServices: map[string]entity.EntityIDSet{},
Expand All @@ -65,7 +65,7 @@ func newGameService(gameid uint16, delegate IGameDelegate) *_GameService {
}
}

func (gs *_GameService) run(restore bool) {
func (gs *GameService) run(restore bool) {
gs.runState.Store(rsRunning)

if !restore {
Expand All @@ -82,7 +82,7 @@ func (gs *_GameService) run(restore bool) {
gwutils.RepeatUntilPanicless(gs.serveRoutine)
}

func (gs *_GameService) serveRoutine() {
func (gs *GameService) serveRoutine() {
cfg := config.GetGame(gameid)
gs.config = cfg
gs.positionSyncInterval = time.Millisecond * time.Duration(cfg.PositionSyncIntervalMS)
Expand Down Expand Up @@ -112,7 +112,9 @@ func (gs *_GameService) serveRoutine() {
method := pkt.ReadVarStr()
args := pkt.ReadArgs()
gs.HandleCallEntityMethod(eid, method, args, "")
} else if msgtype == proto.MT_MIGRATE_REQUEST { // migrate request sent to dispatcher is sent back
} else if msgtype == proto.MT_QUERY_SPACE_GAMEID_FOR_MIGRATE_ACK {
gs.HandleQuerySpaceGameIDForMigrateAck(pkt)
} else if msgtype == proto.MT_MIGRATE_REQUEST_ACK {
gs.HandleMigrateRequestAck(pkt)
} else if msgtype == proto.MT_REAL_MIGRATE {
gs.HandleRealMigrate(pkt)
Expand Down Expand Up @@ -186,12 +188,12 @@ func (gs *_GameService) serveRoutine() {
}
}

func (gs *_GameService) waitPostsComplete() {
func (gs *GameService) waitPostsComplete() {
gwlog.Infof("waiting for posts to complete ...")
post.Tick() // just tick is Ok, tick will consume all posts
}

func (gs *_GameService) doTerminate() {
func (gs *GameService) doTerminate() {
// wait for all posts to complete
gs.waitPostsComplete()
// wait for all async to clear
Expand All @@ -211,7 +213,7 @@ func (gs *_GameService) doTerminate() {

var freezePacker = netutil.MessagePackMsgPacker{}

func (gs *_GameService) doFreeze() {
func (gs *GameService) doFreeze() {
// wait for all posts to complete
st := time.Now()
gs.waitPostsComplete()
Expand Down Expand Up @@ -266,7 +268,7 @@ func freezeFilename(gameid uint16) string {
return fmt.Sprintf("game%d_freezed.dat", gameid)
}

func (gs *_GameService) doRestore() error {
func (gs *GameService) doRestore() error {
t0 := time.Now()
freezeFilename := freezeFilename(gameid)
data, err := ioutil.ReadFile(freezeFilename)
Expand All @@ -286,51 +288,51 @@ func (gs *_GameService) doRestore() error {
return err
}

func (gs *_GameService) String() string {
return fmt.Sprintf("_GameService<%d>", gs.id)
func (gs *GameService) String() string {
return fmt.Sprintf("GameService<%d>", gs.id)
}

func (gs *_GameService) HandleCreateEntityAnywhere(entityid common.EntityID, typeName string, data map[string]interface{}) {
func (gs *GameService) HandleCreateEntityAnywhere(entityid common.EntityID, typeName string, data map[string]interface{}) {
if consts.DEBUG_PACKETS {
gwlog.Debugf("%s.handleCreateEntityAnywhere: %s, typeName=%s, data=%v", gs, entityid, typeName, data)
}
entity.OnCreateEntityAnywhere(entityid, typeName, data)
}

func (gs *_GameService) HandleLoadEntityAnywhere(typeName string, entityID common.EntityID) {
func (gs *GameService) HandleLoadEntityAnywhere(typeName string, entityID common.EntityID) {
if consts.DEBUG_PACKETS {
gwlog.Debugf("%s.handleLoadEntityAnywhere: typeName=%s, entityID=%s", gs, typeName, entityID)
}
entity.LoadEntityLocally(typeName, entityID)
}

func (gs *_GameService) HandleDeclareService(entityID common.EntityID, serviceName string) {
func (gs *GameService) HandleDeclareService(entityID common.EntityID, serviceName string) {
// tell the entity that it is registered successfully
if consts.DEBUG_PACKETS {
gwlog.Debugf("%s.handleDeclareService: %s declares %s", gs, entityID, serviceName)
}
entity.OnDeclareService(serviceName, entityID)
}

func (gs *_GameService) HandleUndeclareService(entityID common.EntityID, serviceName string) {
func (gs *GameService) HandleUndeclareService(entityID common.EntityID, serviceName string) {
// tell the entity that it is registered successfully
if consts.DEBUG_PACKETS {
gwlog.Debugf("%s.HandleUndeclareService: %s undeclares %s", gs, entityID, serviceName)
}
entity.OnUndeclareService(serviceName, entityID)
}

func (gs *_GameService) HandleNotifyAllGamesConnected() {
func (gs *GameService) HandleNotifyAllGamesConnected() {
// all games are connected
gwlog.Infof("All games connected.")
gs.gameDelegate.OnGameReady()
}

func (gs *_GameService) HandleGateDisconnected(gateid uint16) {
func (gs *GameService) HandleGateDisconnected(gateid uint16) {
entity.OnGateDisconnected(gateid)
}

func (gs *_GameService) HandleStartFreezeGameAck(dispid uint16) {
func (gs *GameService) HandleStartFreezeGameAck(dispid uint16) {
gwlog.Infof("Start freeze game ACK of dispatcher %d is received, checking ...", dispid)
gs.dispatcherStartFreezeAcks[dispid-1] = true
for _, acked := range gs.dispatcherStartFreezeAcks {
Expand All @@ -342,7 +344,7 @@ func (gs *_GameService) HandleStartFreezeGameAck(dispid uint16) {
gs.runState.Store(rsFreezing)
}

func (gs *_GameService) HandleSyncPositionYawFromClient(pkt *netutil.Packet) {
func (gs *GameService) HandleSyncPositionYawFromClient(pkt *netutil.Packet) {
//gwlog.Infof("handleSyncPositionYawFromClient: payload %d", len(pkt.UnreadPayload()))
payload := pkt.UnreadPayload()
payloadLen := len(payload)
Expand All @@ -356,14 +358,14 @@ func (gs *_GameService) HandleSyncPositionYawFromClient(pkt *netutil.Packet) {
}
}

func (gs *_GameService) HandleCallEntityMethod(entityID common.EntityID, method string, args [][]byte, clientid common.ClientID) {
func (gs *GameService) HandleCallEntityMethod(entityID common.EntityID, method string, args [][]byte, clientid common.ClientID) {
if consts.DEBUG_PACKETS {
gwlog.Debugf("%s.handleCallEntityMethod: %s.%s(%v)", gs, entityID, method, args)
}
entity.OnCall(entityID, method, args, clientid)
}

func (gs *_GameService) HandleNotifyClientConnected(clientid common.ClientID, gateid uint16) {
func (gs *GameService) HandleNotifyClientConnected(clientid common.ClientID, gateid uint16) {
client := entity.MakeGameClient(clientid, gateid)
if consts.DEBUG_PACKETS {
gwlog.Debugf("%s.handleNotifyClientConnected: %s", gs, client)
Expand All @@ -373,15 +375,22 @@ func (gs *_GameService) HandleNotifyClientConnected(clientid common.ClientID, ga
entity.CreateEntityLocally(gs.config.BootEntity, nil, client)
}

func (gs *_GameService) HandleNotifyClientDisconnected(clientid common.ClientID) {
func (gs *GameService) HandleNotifyClientDisconnected(clientid common.ClientID) {
if consts.DEBUG_CLIENTS {
gwlog.Debugf("%s.handleNotifyClientDisconnected: %s", gs, clientid)
}
// find the owner of the client, and notify lose client
entity.OnClientDisconnected(clientid)
}

func (gs *_GameService) HandleMigrateRequestAck(pkt *netutil.Packet) {
func (gs *GameService) HandleQuerySpaceGameIDForMigrateAck(pkt *netutil.Packet) {
spaceid := pkt.ReadEntityID()
entityid := pkt.ReadEntityID()
gameid := pkt.ReadUint16()
entity.OnQuerySpaceGameIDForMigrateAck(entityid, spaceid, gameid)
}

func (gs *GameService) HandleMigrateRequestAck(pkt *netutil.Packet) {
eid := pkt.ReadEntityID()
spaceid := pkt.ReadEntityID()
spaceLoc := pkt.ReadUint16()
Expand All @@ -393,7 +402,7 @@ func (gs *_GameService) HandleMigrateRequestAck(pkt *netutil.Packet) {
entity.OnMigrateRequestAck(eid, spaceid, spaceLoc)
}

func (gs *_GameService) HandleRealMigrate(pkt *netutil.Packet) {
func (gs *GameService) HandleRealMigrate(pkt *netutil.Packet) {
eid := pkt.ReadEntityID()
_ = pkt.ReadUint16() // targetGame is not userful

Expand All @@ -420,11 +429,11 @@ func (gs *_GameService) HandleRealMigrate(pkt *netutil.Packet) {
entity.OnRealMigrate(eid, spaceID, x, y, z, typeName, migrateData, timerData, clientid, clientsrv)
}

func (gs *_GameService) terminate() {
func (gs *GameService) terminate() {
gs.runState.Store(rsTerminating)
}

func (gs *_GameService) startFreeze() {
func (gs *GameService) startFreeze() {
dispatcherNum := len(config.GetDispatcherIDs())
gs.dispatcherStartFreezeAcks = make([]bool, dispatcherNum)
dispatchercluster.SendStartFreezeGame(gameid)
Expand Down
9 changes: 8 additions & 1 deletion components/game/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var (
logLevel string
restore bool
runInDaemonMode bool
gameService *_GameService
gameService *GameService
signalChan = make(chan os.Signal, 1)
gameDispatcherClientDelegate = &dispatcherClientDelegate{}
)
Expand Down Expand Up @@ -91,20 +91,27 @@ func Run(delegate IGameDelegate) {
}
binutil.SetupGWLog(fmt.Sprintf("game%d", gameid), logLevel, gameConfig.LogFile, gameConfig.LogStderr)

gwlog.Infof("Initializing storage ...")
storage.Initialize()
gwlog.Infof("Initializing KVDB ...")
kvdb.Initialize()
gwlog.Infof("Initializing crontab ...")
crontab.Initialize()

gwlog.Infof("Setup http server ...")
binutil.SetupHTTPServer(gameConfig.HTTPIp, gameConfig.HTTPPort, nil)

entity.SetSaveInterval(gameConfig.SaveInterval)

gwlog.Infof("Start game service ...")
gameService = newGameService(gameid, delegate)

gwlog.Infof("Start dispatchercluster ...")
dispatchercluster.Initialize(gameid, dispatcherclient.GameDispatcherClientType, restore, &dispatcherClientDelegate{})

setupSignals()

gwlog.Infof("Game service start running ...")
gameService.run(restore)
}

Expand Down
2 changes: 1 addition & 1 deletion engine/consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "time"

// Optimizations
const (
OPTIMIZE_LOCAL_ENTITIES = true // should be true for performance, set to false for testing
OPTIMIZE_LOCAL_SPACE_ENTERING = true // should be true for performance, set to false for testing only
)

// Tunable Options
Expand Down
4 changes: 2 additions & 2 deletions engine/dispatchercluster/dispatchercluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ func SendSetClientFilterProp(gateid uint16, clientid common.ClientID, key, val s
return SelectByGateID(gateid).SendSetClientFilterProp(gateid, clientid, key, val)
}

func SendMigrateRequest(spaceID common.EntityID, entityID common.EntityID) error {
return SelectByEntityID(entityID).SendMigrateRequest(spaceID, entityID)
func SendMigrateRequest(entityID common.EntityID, spaceID common.EntityID, spaceGameID uint16) error {
return SelectByEntityID(entityID).SendMigrateRequest(entityID, spaceID, spaceGameID)
}

func SendRealMigrate(eid common.EntityID, targetGame uint16, targetSpace common.EntityID, x, y, z float32,
Expand Down
Loading

0 comments on commit 9bcf260

Please sign in to comment.