def startFactory(self): self.FPSInit(getFrameTime, 60) self.recvcount, self.sendcount, self.initedTime = 0, 0, time.time() self.clientCount = 0 self.dispgroup = {} self.dispgroup["effectObjs"] = GameObjectGroup().initialize( gameObj=self, spriteClass=SpriteObj, teamcolor=(0x7F, 0x7F, 0x7F) ) self.dispgroup["objplayers"] = [] self.statObjN = Statistics() self.statCmpN = Statistics() self.statGState = Statistics() self.gameState = toGzJson(self.makeState()) task.LoopingCall(self.printStat).start(1.0) task.LoopingCall(self.FPSRun).start(1.0 / 60) log.msg("Factory inited")
def run(self): self.profile = ProfileMixin(g_profile) self.profile.begin() self.recvcount, self.sendcount = 0, 0 Log.critical('GameLogicServer initing pid:%s', self.pid) self.FPSInit(getFrameTime, 60) self.dispgroup = {} self.dispgroup['effectObjs'] = GameObjectGroup().initialize( gameObj=self, spriteClass=SpriteObj, teamcolor=(0x7f, 0x7f, 0x7f)) self.dispgroup['objplayers'] = [] self.statObjN = Statistics() self.statCmpN = Statistics() self.statGState = Statistics() self.clients = {} # clientid : team info self.gameState = toGzJson({ 'cmd': 'gameState', 'frameinfo': {k: v for k, v in self.frameinfo.iteritems() if k in ['thisFrameTime']}, 'objplayers': [og.serialize() for og in self.dispgroup['objplayers']], 'effectObjs': self.dispgroup['effectObjs'].serialize() }) self.quit = False self.registerRepeatFn(self.prfps, 1) self.r2c = {} self.w2c = {} for c in self.channels: self.r2c[c.reader] = c self.w2c[c.writer] = c Log.info('GameLogicServer inited') for ch in self.channels: ch.writeTo(((0, 0), None)) # run server # main loop self.recvlist = [self.toMainCh.reader] + [ c.reader for c in self.channels] self.sendlist = [] while not self.quit: self.sendlist = [o.writer for o in self.channels if o.canSend()] inputready, outputready, exceptready = select.select( self.recvlist, self.sendlist, [], 0) if len(inputready) == 0 and len(outputready) == 0: self.FPSRun() self.FPSYield() for i in inputready: if i == self.toMainCh.reader: self.quit = True break else: if i in self.r2c: clientid, packet = self.r2c[i].readFrom() cmdDict = fromGzJson(packet) self.do1ClientCmd(self.r2c[i], clientid, cmdDict) else: Log.critical('invalid reader %s', i) for o in outputready: if o in self.w2c: self.w2c[o].writeFromQueue() else: Log.critical('invalid writer %s', i) for ch in self.channels: ch.writeTo(((0, -1), None)) # quit server Log.info('end doGame') self.prfps(0) self.profile.end()
class GameLogicServer(multiprocessing.Process, ShootingGameMixin, FPSMixin): def prfps(self, repeatinfo): self.diaplayScore() Log.critical('objs: %s', self.statObjN) Log.critical('cmps: %s', self.statCmpN) Log.critical('gamestatelen: %s', self.statGState) Log.critical('fps: %s', self.frameinfo.stat) Log.critical('clients %s ', len(self.clients)) Log.critical('main channel %s ', self.toMainCh.getStatInfo()) for c in self.channels: Log.critical('channel %s ', c.getStatInfo()) def diaplayScore(self): teamscore = {} for j in self.dispgroup['objplayers']: if j.teamname in teamscore: teamscore[j.teamname]['teamscore'] += j.statistic['teamscore'] teamscore[j.teamname]['member'] += 1 teamscore[j.teamname]['objcount'] += len(j) else: teamscore[j.teamname] = dict( teamscore=j.statistic['teamscore'], color=j.teamcolor, ai=j.__class__.__name__, member=1, objcount=len(j) ) Log.info("{:12} {:15} {:>16} {:>8} {:>8} {:8}".format( 'teamname', 'color', 'AI type', 'member', 'score', 'objcount' )) sortedinfo = sorted( teamscore.keys(), key=lambda x: -teamscore[x]['teamscore']) for j in sortedinfo: Log.info("{:12} {:15} {:>16} {:8} {:8.4f} {:8}".format( j, teamscore[j]['color'], teamscore[j]['ai'], teamscore[j]['member'], teamscore[j]['teamscore'], teamscore[j]['objcount'] )) def getChannel(self): return self.forMainCh def doScore(self, resultdict): for src, targets in resultdict.iteritems(): src.enabled = False if src.objtype != 'bounceball': self.dispgroup['effectObjs'].addSpriteExplosionEffect(src) else: # 충돌한 것이 bounceball 이면 src.group.addBallExplosionEffect( self.dispgroup['effectObjs'], src.group, src) srcLostScore = src.getDelScore(math.sqrt(src.level)) src.group.statistic["teamscore"] -= srcLostScore uplevel = srcLostScore * 2 / len(targets) for target in targets: if target.objtype != 'bounceball': if target.group and target.group.hasBounceBall(): oldlevel = target.group[0].level target.group[0].level += uplevel inclevel = int( target.group[0].level) - int(oldlevel) for i in xrange(inclevel): target.group.statistic[ 'act']['supershield'] += 1 target.group.AddSuperShield( target=target.group[0], expireFn=self.dispgroup[ 'effectObjs'].addSpriteExplosionEffect ) if target.objtype not in ['bounceball', 'supershield', 'shield']: target.group.statistic["teamscore"] += uplevel return def makeState(self): savelist = { 'cmd': 'gameState', 'frameinfo': {k: v for k, v in self.frameinfo.iteritems() if k in ['thisFrameTime']}, 'objplayers': [og.serialize() for og in self.dispgroup['objplayers']], 'effectObjs': self.dispgroup['effectObjs'].serialize() } return savelist def saveState(self): try: savelist = toGzJson(self.makeState()) self.gameState = savelist except zlib.error: Log.exception('zlib compress fail') return 0 except ValueError: Log.exception('encode fail') return 0 return len(savelist) def make1TeamCustom(self, teamname, aiclass, spriteClass, teamcolor, servermove): o = aiclass().initialize( teamcolor=teamcolor, teamname=teamname, effectObjs=self.dispgroup['effectObjs'], servermove=servermove, gameObj=self, spriteClass=spriteClass ) o.makeMember() return o def __init__(self, servertype, channels): multiprocessing.Process.__init__(self) self.serverType = servertype self.channels = channels self.toMainCh, self.forMainCh = makeChannel() def run(self): self.profile = ProfileMixin(g_profile) self.profile.begin() self.recvcount, self.sendcount = 0, 0 Log.critical('GameLogicServer initing pid:%s', self.pid) self.FPSInit(getFrameTime, 60) self.dispgroup = {} self.dispgroup['effectObjs'] = GameObjectGroup().initialize( gameObj=self, spriteClass=SpriteObj, teamcolor=(0x7f, 0x7f, 0x7f)) self.dispgroup['objplayers'] = [] self.statObjN = Statistics() self.statCmpN = Statistics() self.statGState = Statistics() self.clients = {} # clientid : team info self.gameState = toGzJson({ 'cmd': 'gameState', 'frameinfo': {k: v for k, v in self.frameinfo.iteritems() if k in ['thisFrameTime']}, 'objplayers': [og.serialize() for og in self.dispgroup['objplayers']], 'effectObjs': self.dispgroup['effectObjs'].serialize() }) self.quit = False self.registerRepeatFn(self.prfps, 1) self.r2c = {} self.w2c = {} for c in self.channels: self.r2c[c.reader] = c self.w2c[c.writer] = c Log.info('GameLogicServer inited') for ch in self.channels: ch.writeTo(((0, 0), None)) # run server # main loop self.recvlist = [self.toMainCh.reader] + [ c.reader for c in self.channels] self.sendlist = [] while not self.quit: self.sendlist = [o.writer for o in self.channels if o.canSend()] inputready, outputready, exceptready = select.select( self.recvlist, self.sendlist, [], 0) if len(inputready) == 0 and len(outputready) == 0: self.FPSRun() self.FPSYield() for i in inputready: if i == self.toMainCh.reader: self.quit = True break else: if i in self.r2c: clientid, packet = self.r2c[i].readFrom() cmdDict = fromGzJson(packet) self.do1ClientCmd(self.r2c[i], clientid, cmdDict) else: Log.critical('invalid reader %s', i) for o in outputready: if o in self.w2c: self.w2c[o].writeFromQueue() else: Log.critical('invalid writer %s', i) for ch in self.channels: ch.writeTo(((0, -1), None)) # quit server Log.info('end doGame') self.prfps(0) self.profile.end() def do1ClientCmd(self, ch, clientid, cmdDict): teaminfo = self.clients.get(clientid) if teaminfo is None: self.clients[clientid] = {} teaminfo = self.clients[clientid] cmd = cmdDict.get('cmd') if cmd == 'makeTeam': tn = cmdDict.get('teamname') o = self.make1TeamCustom( teamname=tn, aiclass=GameObjectGroup, teamcolor=cmdDict.get('teamcolor'), servermove=False, spriteClass=SpriteObj ) self.dispgroup['objplayers'].append(o) teaminfo['teamid'] = o.ID teaminfo['teamname'] = tn ch.sendQueue.put((clientid, toGzJsonParams( cmd='teamInfo', teamname=tn, teamid=o.ID))) Log.debug('Join team %s %s', clientid, teaminfo) elif cmd == 'del': Log.debug('Leave team %s', teaminfo) try: self.delTeamByID(teaminfo['teamid']) except KeyError: pass del self.clients[clientid] elif cmd == 'reqState': ch.sendQueue.put((clientid, self.gameState)) elif cmd == 'act': ch.sendQueue.put((clientid, toGzJsonParams(cmd='actACK'))) actions = cmdDict.get('actions') tid = cmdDict['teamid'] thisTeam = self.getTeamByID(tid) if thisTeam.servermove: Log.error('invalid client team %s', thisTeam) return actionjson = cmdDict['actions'] actions = self.deserializeActions(actionjson) enemyTeamList = self.getEnemyTeamList(thisTeam) thisTeam.prepareActions( enemyTeamList, self.frameinfo.lastFPS, self.thistick ) thisTeam.applyActions(actions) else: Log.warn('unknown cmd %s', cmdDict) def FPSMain(self): self.thistick = self.frameinfo.thisFrameTime objcount = sum([len(a) for a in self.dispgroup['objplayers']]) self.statObjN.update(objcount) # 그룹내의 team 들을 automove 한다. for thisTeam in self.dispgroup['objplayers']: thisTeam.AutoMoveByTime(self.thistick) # make collision dictionary resultdict, cmpcount = self.makeCollisionDict() self.statCmpN.update(cmpcount) # do score self.doScore(resultdict) # 결과에 따라 삭제한다. for aa in self.dispgroup['objplayers']: aa.RemoveDisabled() self.dispgroup['effectObjs'].AutoMoveByTime( self.thistick).RemoveDisabled() self.statGState.update(self.saveState())
class GameLogicServer(ShootingGameMixin, FPSMixin, protocol.Factory): protocol = GameLogicProtocol def printStat(self): self.diaplayScore() log.msg("objs: ", self.statObjN) log.msg("cmps: ", self.statCmpN) log.msg("gamestatelen: ", self.statGState) log.msg("fps: ", self.frameinfo.stat) log.msg(self.getStatInfo()) self.recvcount, self.sendcount, self.initedTime = 0, 0, time.time() def diaplayScore(self): teamscore = {} for j in self.dispgroup["objplayers"]: if j.teamname in teamscore: teamscore[j.teamname]["teamscore"] += j.statistic["teamscore"] teamscore[j.teamname]["member"] += 1 teamscore[j.teamname]["objcount"] += len(j) else: teamscore[j.teamname] = dict( teamscore=j.statistic["teamscore"], color=j.teamcolor, ai=j.__class__.__name__, member=1, objcount=len(j), ) log.msg( "{:12} {:15} {:>16} {:>8} {:>8} {:8}".format("teamname", "color", "AI type", "member", "score", "objcount") ) sortedinfo = sorted(teamscore.keys(), key=lambda x: -teamscore[x]["teamscore"]) for j in sortedinfo: log.msg( "{:12} {:15} {:>16} {:8} {:8.4f} {:8}".format( j, teamscore[j]["color"], teamscore[j]["ai"], teamscore[j]["member"], teamscore[j]["teamscore"], teamscore[j]["objcount"], ) ) def getStatInfo(self): t = time.time() - self.initedTime return "clients:{} recv:{} {}/s send:{} {}/s".format( self.clientCount, self.recvcount, self.recvcount / t, self.sendcount, self.sendcount / t ) def doScore(self, resultdict): for src, targets in resultdict.iteritems(): src.enabled = False if src.objtype != "bounceball": self.dispgroup["effectObjs"].addSpriteExplosionEffect(src) else: # 충돌한 것이 bounceball 이면 src.group.addBallExplosionEffect(self.dispgroup["effectObjs"], src.group, src) srcLostScore = src.getDelScore(math.sqrt(src.level)) src.group.statistic["teamscore"] -= srcLostScore uplevel = srcLostScore * 2 / len(targets) for target in targets: if target.objtype != "bounceball": if target.group and target.group.hasBounceBall(): oldlevel = target.group[0].level target.group[0].level += uplevel inclevel = int(target.group[0].level) - int(oldlevel) for i in xrange(inclevel): target.group.statistic["act"]["supershield"] += 1 target.group.AddSuperShield( target=target.group[0], expireFn=self.dispgroup["effectObjs"].addSpriteExplosionEffect, ) if target.objtype not in ["bounceball", "supershield", "shield"]: target.group.statistic["teamscore"] += uplevel return def makeState(self): savelist = { "cmd": "gameState", "frameinfo": {"thisFrameTime": time.time()}, "objplayers": [og.serialize() for og in self.dispgroup["objplayers"]], "effectObjs": self.dispgroup["effectObjs"].serialize(), } return savelist def saveState(self): try: savelist = toGzJson(self.makeState()) self.gameState = savelist except zlib.error: log.msg("zlib compress fail") return 0 except ValueError: log.msg("encode fail") return 0 return len(savelist) def make1TeamCustom(self, teamname, aiclass, spriteClass, teamcolor, servermove): o = aiclass().initialize( teamcolor=teamcolor, teamname=teamname, effectObjs=self.dispgroup["effectObjs"], servermove=servermove, gameObj=self, spriteClass=spriteClass, ) o.makeMember() return o def startFactory(self): self.FPSInit(getFrameTime, 60) self.recvcount, self.sendcount, self.initedTime = 0, 0, time.time() self.clientCount = 0 self.dispgroup = {} self.dispgroup["effectObjs"] = GameObjectGroup().initialize( gameObj=self, spriteClass=SpriteObj, teamcolor=(0x7F, 0x7F, 0x7F) ) self.dispgroup["objplayers"] = [] self.statObjN = Statistics() self.statCmpN = Statistics() self.statGState = Statistics() self.gameState = toGzJson(self.makeState()) task.LoopingCall(self.printStat).start(1.0) task.LoopingCall(self.FPSRun).start(1.0 / 60) log.msg("Factory inited") def do1ClientCmd(self, clinentprotocol, cmdDict): cmd = cmdDict.get("cmd") if cmd == "makeTeam": tn = cmdDict.get("teamname") o = self.make1TeamCustom( teamname=tn, aiclass=GameObjectGroup, teamcolor=cmdDict.get("teamcolor"), servermove=False, spriteClass=SpriteObj, ) self.dispgroup["objplayers"].append(o) clinentprotocol.sendString(toGzJsonParams(cmd="teamInfo", teamname=tn, teamid=o.ID)) elif cmd == "del": try: self.delTeamByID(cmdDict["teamid"]) except KeyError: pass elif cmd == "reqState": clinentprotocol.sendString(self.gameState) elif cmd == "act": clinentprotocol.sendString(toGzJsonParams(cmd="actACK")) actions = cmdDict.get("actions") tid = cmdDict["teamid"] thisTeam = self.getTeamByID(tid) if thisTeam.servermove: log.msg("invalid client team ", thisTeam) return actionjson = cmdDict["actions"] actions = self.deserializeActions(actionjson) enemyTeamList = self.getEnemyTeamList(thisTeam) thisTeam.prepareActions(enemyTeamList, self.frameinfo.lastFPS, self.thistick) thisTeam.applyActions(actions) else: log.msg("unknown cmd ", cmdDict) def FPSMain(self): self.thistick = self.frameinfo.thisFrameTime objcount = sum([len(a) for a in self.dispgroup["objplayers"]]) self.statObjN.update(objcount) # 그룹내의 team 들을 automove 한다. for thisTeam in self.dispgroup["objplayers"]: thisTeam.AutoMoveByTime(self.thistick) # make collision dictionary resultdict, cmpcount = self.makeCollisionDict() self.statCmpN.update(cmpcount) # do score self.doScore(resultdict) # 결과에 따라 삭제한다. for aa in self.dispgroup["objplayers"]: aa.RemoveDisabled() self.dispgroup["effectObjs"].AutoMoveByTime(self.thistick).RemoveDisabled() self.statGState.update(self.saveState())