diff --git a/Gopkg.lock b/Gopkg.lock index 7f62b59e..3948b2f3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -155,8 +155,8 @@ [[projects]] name = "github.com/xiaonanln/go-aoi" packages = ["."] - revision = "ee6580829802975e3e60ef5c0711a44bcc8b481e" - version = "v0.0.2" + revision = "2762bd19865793964f81523c610fe87550122d16" + version = "v0.1.0" [[projects]] name = "github.com/xiaonanln/go-trie-tst" @@ -165,10 +165,10 @@ version = "v0.4" [[projects]] - branch = "master" name = "github.com/xiaonanln/go-xnsyncutil" packages = ["xnsyncutil"] revision = "f004c49229c858b2b4479993d3ce2adc408828fc" + version = "v0.0.5" [[projects]] name = "github.com/xiaonanln/goTimer" @@ -209,26 +209,26 @@ [[projects]] branch = "master" name = "golang.org/x/crypto" - packages = ["blowfish","cast5","pbkdf2","salsa20","salsa20/salsa","tea","twofish","xtea"] - revision = "5ba7f63082460102a45837dbd1827e10f9479ac0" + packages = ["blowfish","cast5","internal/subtle","pbkdf2","salsa20","salsa20/salsa","tea","twofish","xtea"] + revision = "027cca12c2d63e3d62b670d901e8a2c95854feec" [[projects]] branch = "master" name = "golang.org/x/net" packages = ["bpf","context","internal/iana","internal/socket","ipv4","websocket"] - revision = "61147c48b25b599e5b561d2e9c4f3e1ef489ca41" + revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix","windows"] - revision = "3b87a42e500a6dc65dae1a55d0b641295971163e" + revision = "6c888cc515d3ed83fc103cf1d84468aad274b0a7" [[projects]] name = "google.golang.org/appengine" packages = [".","datastore","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api"] - revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a" - version = "v1.0.0" + revision = "b1f26356af11148e710935ed1ac8a7f5702c7612" + version = "v1.1.0" [[projects]] name = "gopkg.in/eapache/queue.v1" @@ -245,6 +245,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "bfe91a1aafba53b2221b9a4c47c5682648bf11ae2f2fa7d9680dbeb91c7e77f0" + inputs-digest = "310a69e8e725a247d66d715f574e85e5f55713ffaec788657ab59a2e165ff069" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 96b932b7..a893b9d3 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -77,10 +77,6 @@ [[constraint]] name = "gopkg.in/mgo.v2" -[[constraint]] - name = "github.com/xiaonanln/go-aoi" - version = "^0.0.2" - [[constraint]] name = "github.com/chasex/redis-go-cluster" branch = "master" diff --git a/components/dispatcher/DispatcherService.go b/components/dispatcher/DispatcherService.go index af9621a6..564d50c9 100644 --- a/components/dispatcher/DispatcherService.go +++ b/components/dispatcher/DispatcherService.go @@ -23,20 +23,12 @@ import ( "github.com/xiaonanln/goworld/engine/proto" ) -type callQueueItem struct { - packet *netutil.Packet -} - type entityDispatchInfo struct { gameid uint16 blockUntilTime time.Time pendingPacketQueue []*netutil.Packet } -func newEntityDispatchInfo() *entityDispatchInfo { - return &entityDispatchInfo{} -} - func (edi *entityDispatchInfo) blockRPC(d time.Duration) { t := time.Now().Add(d) if edi.blockUntilTime.Before(t) { @@ -573,23 +565,6 @@ func (service *DispatcherService) cleanupEntitiesOfGame(gameid uint16) { } } - //// for all services whose entity is cleaned, notify all games that the service is down - //undeclaredServices := common.StringSet{} - //for serviceName, serviceEids := range service.srvdisRegisterMap { - // var serviceRemoveEids []common.EntityID - // for serviceEid := range serviceEids { - // if cleanEids.Contains(serviceEid) { // this service entity is down, tell other games - // undeclaredServices.Add(serviceName) - // serviceRemoveEids = append(serviceRemoveEids, serviceEid) - // service.handleServiceDown(gameid, serviceName, serviceEid) - // } - // } - // - // for _, eid := range serviceRemoveEids { - // serviceEids.Del(eid) - // } - //} - for eid := range cleanEids { service.cleanupEntityInfo(eid) } @@ -616,17 +591,6 @@ func (service *DispatcherService) handleNotifyDestroyEntity(dcp *dispatcherClien func (service *DispatcherService) cleanupEntityInfo(entityID common.EntityID) { service.delEntityDispatchInfo(entityID) - //if services, ok := service.entityIDToServices[entityID]; ok { - // for serviceName := range services { - // serviceEids := service.srvdisRegisterMap[serviceName] - // serviceEids.Del(entityID) - // if len(serviceEids) == 0 { - // delete(service.srvdisRegisterMap, serviceName) - // } - // } - // delete(service.entityIDToServices, entityID) - // gwlog.Warnf("%s: entity %s is cleaned up, undeclared servies %v", service, entityID, services.ToList()) - //} } func (service *DispatcherService) handleNotifyClientConnected(dcp *dispatcherClientProxy, pkt *netutil.Packet) { diff --git a/components/gate/GateService.go b/components/gate/GateService.go index 789bebd0..7c82c76b 100644 --- a/components/gate/GateService.go +++ b/components/gate/GateService.go @@ -271,6 +271,7 @@ func (gs *GateService) handleDispatcherClientPacket(msgtype proto.MsgType, packe } } else { // client already disconnected, but the game service seems not knowing it, so tell it + // fixme: uncomment bellow line, it is just for test dispatchercluster.SelectByGateID(gateid).SendNotifyClientDisconnected(clientid) } } else if msgtype == proto.MT_SYNC_POSITION_YAW_ON_CLIENTS { diff --git a/engine/entity/Entity.go b/engine/entity/Entity.go index 117d55b7..fcdc606f 100644 --- a/engine/entity/Entity.go +++ b/engine/entity/Entity.go @@ -307,11 +307,17 @@ func (e *Entity) OnLeaveAOI(otherAoi *aoi.AOI) { // Interests and Uninterest among entities func (e *Entity) interest(other *Entity) { + if e == other || e.Neighbors.Contains(other) { + gwlog.Panicf("interest multiple times: %s & %s", e, other) + } e.Neighbors.Add(other) e.client.sendCreateEntity(other, false) } func (e *Entity) uninterest(other *Entity) { + if e == other || !e.Neighbors.Contains(other) { + gwlog.Panicf("not interested yet: %s & %s", e, other) + } e.Neighbors.Del(other) e.client.sendDestroyEntity(other) } @@ -933,6 +939,7 @@ func (e *Entity) sendListAttrChangeToClients(la *ListAttr, index int, val interf flag := la.flag if flag&afAllClient != 0 { + // TODO: only pack 1 packet, do not marshal multiple times path := la.getPathFromOwner() e.client.sendNotifyListAttrChange(e.ID, path, uint32(index), val) for neighbor := range e.Neighbors { diff --git a/engine/entity/Space.go b/engine/entity/Space.go index d1f2bb0d..5e5e5e6c 100644 --- a/engine/entity/Space.go +++ b/engine/entity/Space.go @@ -102,7 +102,8 @@ func (space *Space) EnableAOI() { } space.Attrs.SetBool(_SPACE_ENABLE_AOI_KEY, true) - space.aoiMgr = aoi.NewXZListAOICalculator() + space.aoiMgr = aoi.NewXZListAOIManager() + //space.aoiMgr = aoi.NewTowerAOIManager(-500, 500, -500, 500, 10) } //func (space *Space) UseTowerAOI(minX, maxX, minY, maxY Coord, towerRange Coord) { diff --git a/engine/gwlog/gwlog.go b/engine/gwlog/gwlog.go index 9b988923..ac0e0075 100644 --- a/engine/gwlog/gwlog.go +++ b/engine/gwlog/gwlog.go @@ -26,20 +26,6 @@ var ( PanicLevel Level = Level(zap.PanicLevel) // FatalLevel level FatalLevel Level = Level(zap.FatalLevel) - - //// Debugf logs formatted debug message - //Debugf logFormatFunc - //// Infof logs formatted info message - //Infof logFormatFunc - //// Warnf logs formatted warn message - //Warnf logFormatFunc - //// Errorf logs formatted error message - //Errorf logFormatFunc - //Panicf logFormatFunc - //Fatalf logFormatFunc - //Error func(args ...interface{}) - //Fatal func(args ...interface{}) - //Panic func(args ...interface{}) ) type logFormatFunc func(format string, args ...interface{}) @@ -162,6 +148,7 @@ func Panicf(format string, args ...interface{}) { } func Fatalf(format string, args ...interface{}) { + debug.PrintStack() sugar.With(zap.Time("ts", time.Now())).Fatalf(format, args...) } diff --git a/examples/test_client/ClientBot.go b/examples/test_client/ClientBot.go index 28ae27c0..8b01697a 100644 --- a/examples/test_client/ClientBot.go +++ b/examples/test_client/ClientBot.go @@ -222,13 +222,15 @@ func (bot *ClientBot) handlePacket(msgtype proto.MsgType, packet *netutil.Packet defer func() { err := recover() if err != nil { - gwlog.Fatalf("handle packet faild: %v", err) + gwlog.TraceError("handle packet faild: %v", err) } }() bot.Lock() defer bot.Unlock() + //gwlog.Infof("client handle packet: msgtype=%v, payload=%v", msgtype, packet.Payload()) + if msgtype >= proto.MT_REDIRECT_TO_GATEPROXY_MSG_TYPE_START && msgtype <= proto.MT_REDIRECT_TO_GATEPROXY_MSG_TYPE_STOP { _ = packet.ReadUint16() _ = packet.ReadClientID() // TODO: strip these two fields ? seems a little difficult, maybe later. @@ -261,9 +263,7 @@ func (bot *ClientBot) handlePacket(msgtype proto.MsgType, packet *netutil.Packet index := packet.ReadUint32() var val interface{} packet.ReadData(&val) - if !quiet { - gwlog.Debugf("Entity %s Attribute %v: set [%d]=%v", entityID, path, index, val) - } + //gwlog.Infof("Entity %s Attribute %v: set [%d]=%v", entityID, path, index, val) bot.applyListAttrChange(entityID, path, int(index), val) } else if msgtype == proto.MT_NOTIFY_LIST_ATTR_APPEND_ON_CLIENT { entityID := packet.ReadEntityID() @@ -271,17 +271,13 @@ func (bot *ClientBot) handlePacket(msgtype proto.MsgType, packet *netutil.Packet packet.ReadData(&path) var val interface{} packet.ReadData(&val) - if !quiet { - gwlog.Debugf("Entity %s Attribute %v: append %v", entityID, path, val) - } + //gwlog.Infof("Entity %s Attribute %v: append %v", entityID, path, val) bot.applyListAttrAppend(entityID, path, val) } else if msgtype == proto.MT_NOTIFY_LIST_ATTR_POP_ON_CLIENT { entityID := packet.ReadEntityID() var path []interface{} packet.ReadData(&path) - if !quiet { - gwlog.Debugf("Entity %s Attribute %v: pop", entityID, path) - } + //gwlog.Infof("Entity %s Attribute %v: pop", entityID, path) bot.applyListAttrPop(entityID, path) } else if msgtype == proto.MT_CREATE_ENTITY_ON_CLIENT { isPlayer := packet.ReadBool() @@ -417,7 +413,6 @@ func (bot *ClientBot) applyListAttrPop(entityID common.EntityID, path []interfac } entity := bot.entities[entityID] entity.applyListAttrPop(path) - } func (bot *ClientBot) createEntity(typeName string, entityID common.EntityID, isPlayer bool, clientData map[string]interface{}, x, y, z entity.Coord, yaw entity.Yaw) { diff --git a/examples/test_client/ClientEntity.go b/examples/test_client/ClientEntity.go index b7fb4ca1..89a8a95b 100644 --- a/examples/test_client/ClientEntity.go +++ b/examples/test_client/ClientEntity.go @@ -165,12 +165,12 @@ type _Something struct { var ( _DO_THINGS = []*_Something{ {"DoEnterRandomSpace", 20, time.Minute}, - {"DoEnterRandomNilSpace", 10, time.Minute}, + //{"DoEnterRandomNilSpace", 10, time.Minute}, //{"DoSendMail", 5, time.Minute}, //{"DoGetMails", 10, time.Minute}, - {"DoSayInWorldChannel", 5, time.Minute}, - {"DoSayInProfChannel", 5, time.Minute}, - {"DoTestListField", 10, time.Minute}, + //{"DoSayInWorldChannel", 5, time.Minute}, + //{"DoSayInProfChannel", 5, time.Minute}, + {"DoTestListField", 20, time.Minute}, //{"DoTestPublish", 1, time.Minute}, } ) @@ -384,30 +384,40 @@ func (e *clientEntity) applyMapAttrDel(path []interface{}, key string) { } func (e *clientEntity) applyListAttrChange(path []interface{}, index int, val interface{}) { - gwlog.Debugf("applyListAttrChange: path=%v, index=%v, val=%v", path, index, val) _attr, _, _ := e.findAttrByPath(path) attr := _attr.([]interface{}) + //gwlog.Infof("%s applyListAttrChange: path=%v, index=%v, val=%v, attr=%#v", e, path, index, val, attr) + if index >= len(attr) { + gwlog.Panicf("%s: ListAttr change error: list size is %d, index = %d, path=%s, attr=%#v", e, len(attr), index, path, attr) + return + } attr[index] = val e.onAttrChange(path, "") } func (e *clientEntity) applyListAttrAppend(path []interface{}, val interface{}) { - gwlog.Debugf("applyListAttrAppend: path=%v, val=%v, attrs=%v", path, val, e.Attrs) _attr, parent, pkey := e.findAttrByPath(path) attr := _attr.([]interface{}) + //gwlog.Infof("%s applyListAttrAppend: path=%v, val=%v, attr=%#v", e, path, val, attr) if parentmap, ok := parent.(map[string]interface{}); ok { parentmap[pkey.(string)] = append(attr, val) } else if parentlist, ok := parent.([]interface{}); ok { parentlist[pkey.(int64)] = append(attr, val) + } else { + gwlog.Panicf("parent type is %T", parent) } e.onAttrChange(path, "") } func (e *clientEntity) applyListAttrPop(path []interface{}) { - gwlog.Debugf("applyListAttrPop: path=%v", path) _attr, parent, pkey := e.findAttrByPath(path) attr := _attr.([]interface{}) + //gwlog.Infof("%s applyListAttrPop: path=%v, attr=%#v", e, path, attr) + if len(attr) == 0 { + gwlog.Panicf("%s: ListAttr pop error: list is empty: path=%s, attr=%#v", e, path, attr) + return + } if parentmap, ok := parent.(map[string]interface{}); ok { parentmap[pkey.(string)] = attr[:len(attr)-1]