1 #-*- coding:utf-8 -*-2 3 #revisions:4 #2009.11.05 scott5 #1. created6 7 #2009.12.26 scott created8 9 #2010.1.26 scott10 #1. 增加远程文件比对的操作接口11 12 importsys,os13 sys.path.insert(0,'C:\Ice-3.3.1-VC90\python')14 sys.path.append('../lib')15 importtraceback,threading,time,struct,os,os.path,shutil,distutils.dir_util,array,base64,zlib,struct,binascii16 importcopy,socket,select,getopt17 importcodec,log,config18 19 importIce20 21 Ice.loadSlice('-I../idl -IC:\Ice-3.2.1\slice ../idl/sync.ice')22 fromgamesimport*23 24 DELIMITER='*'25 ##############################################################26 27 classsyncApp(Ice.Application):28 def__init__(self):29 self._conf=config.SimpleConfig()30 31 32 self._mtx_hosts=threading.Lock()33 self._game_hosts=[]34 35 self._gamelist=[]36 ################################37 38 39 definit_hosts(self):40 #初始化游戏客户机信息41 #try:42 #fp = open('../etc/hosts.list','r')43 #lines = fp.readlines()44 #fp.close()45 #for l in lines:46 #host,game = l.strip().split(',')47 #host = host.strip()48 #game = game.strip()49 #if len(host) == 0 or len(game)==0:50 #continue51 #self._game_hosts.append({'host':host,'game':game})52 #except:53 #print 'Error: read game host failed!'54 #return False55 returnTrue56 57 #初始化游戏目录58 definit_games(self):59 self._log=log.Logger(self.getPropertyValue('logfile','server.log'))60 self._errlog=log.Logger(self.getPropertyValue('errlogfile','error.log'))61 #names = self.getPropertyValue('games')62 #games=names.split(',')63 #for g in games:64 #g = g.strip()65 #if len(g) == 0:66 #continue67 #gi = gameInfoT()68 #gi.name = g69 #gi.path = self.getPropertyValue("%s.path"%g).strip().lower()70 #gi.dest_path = self.getPropertyValue("%s.dest_path"%g).strip().lower()71 #gi.launch_app = self.getPropertyValue("%s.launch.app"%g)72 #gi.launch_params = self.getPropertyValue("%s.launch.params"%g)73 #self._gamelist.append(gi)74 75 defgetLogger(self):76 returnself._log77 78 defgetErrLogger(self):79 returnself._errlog80 81 defgetGameList(self):82 returnself._gamelist83 84 #return host info ,else none85 defget_gamehost(self):86 host=None87 self._mtx_hosts.acquire()88 iflen(self._game_hosts):89 host=self._game_hosts.pop(0)90 self._mtx_hosts.release()91 returnhost92 93 94 deftest(self):95 port=self.getPropertyValue('endpoint.port')96 servant=self.getPropertyValue('endpoint.servant')97 uri="%s:tcp -p %s -h %s"%(servant,port,'localhost')98 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))99 foriinrange(100000):100 printhostprx.getTimestamp()101 time.sleep(0.5)102 103 defkillapp(self,host,port,procname):104 try:105 servant=self.getPropertyValue('endpoint.servant')106 uri="%s:tcp -p %s -h %s"%(servant,port,host)107 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))108 printu"终止远程进程: %s-%s"%(host,procname)109 hostprx.killProcessByName(procname)110 except:111 printtraceback.print_exc()112 113 deflaunchapp(self,host,port,procname,param=''):114 try:115 servant=self.getPropertyValue('endpoint.servant')116 uri="%s:tcp -p %s -h %s"%(servant,port,host)117 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))118 printu"创建远程进程: %s-%s"%(host,procname)119 params={'app':'','param':''}120 params['app']=procname121 params['param']=param122 hostprx.launchApp(params)123 except:124 printtraceback.print_exc()125 126 127 128 #执行endpoint的更新操作129 defshutdown(self,host,port):130 try:131 servant=self.getPropertyValue('endpoint.servant')132 uri="%s:tcp -p %s -h %s"%(servant,port,host)133 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))134 printu"执行shutdown: %s"%(host)135 hostprx.shutdown()136 except:137 printtraceback.print_exc()138 139 140 #通知远端主机启动游戏141 deflaunchGames(self,host,port,gamepath):142 try:143 ifTrue:144 servant=self.getPropertyValue('endpoint.servant')145 uri="%s:tcp -p %s -h %s"%(servant,port,host)146 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))147 #检索主机运行游戏的远端存储目录148 printu"启动游戏(%s) of host(%s)"%(gamepath,host)149 try:150 r=hostprx.launchGame(gamepath)151 except:152 print"Error: Endpoint Host(%s) Exception Occurred! Skipped
"%(host)153 except:154 printtraceback.print_exc()155 156 defterminateGames(self,host,port,gamepath):157 try:158 ifTrue:159 servant=self.getPropertyValue('endpoint.servant')160 uri="%s:tcp -p %s -h %s"%(servant,port,host)161 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))162 print"stop game(%s) of host(%s)"%(gamepath,host)163 try:164 r=hostprx.terminateGame(gamepath)165 except:166 print"Error: Endpoint Host(%s) Exception Occurred! Skipped
"%(host)167 except:168 printtraceback.print_exc()169 170 #执行远程批处理文件171 defexcbat(self,host,port,command):172 try:173 hosts=sys.argv[2]174 logfile='excbat.log'175 servant=self.getPropertyValue('endpoint.servant')176 uri="%s:tcp -p %s -h %s"%(servant,port,host)177 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))178 ifTrue:179 r=hostprx.executeBatchFile(command)180 ifr.has_key('verbose'):#写入执行日志181 printr['verbose']182 except:183 printtraceback.print_exc()184 185 defupdate_file(self,hostprx,local,remote,partfile):186 try:187 188 file=os.path.normpath(local+'/'+partfile)189 fp=open(file,'rb')190 hostprx.syncFileStart("%s%s"%(remote,partfile))191 whileTrue:192 bytes=fp.read(1024*100)193 ifnotbytes:194 break195 hostprx.syncFileData(bytes)196 fp.close()197 hostprx.syncFileEnd()198 except:199 printtraceback.print_exc()200 #self._app.getErrLogger().error("update file failed:(%s)"%(path))201 returnFalse202 returnTrue203 204 defupdate_game(self,hostprx,local,remote,hostname=''):205 #路径参数都不携带尾端的分隔符206 try:207 #读取忽略文件列表208 skipfiles=[]209 try:210 fp=open("%s/skipfiles.txt"%local,'r')211 lines=fp.readlines()212 forlineinlines:213 line=line.strip().lower()214 iflen(line)andline[0]!='#':215 line=os.path.normpath(line)216 ifline[0]!='\\':217 line='\\'+line218 skipfiles.append(line)#添加进忽略列表219 fp.close()220 except:221 pass222 #**************************************223 #请求远程目录文件清单224 printu'计算远端主机数据摘要
'225 filelist=hostprx.getFileDescList(remote)226 227 #去除目录前缀228 forninrange(len(filelist)):229 idx=filelist[n].filename.index(remote)230 filelist[n].filename=filelist[n].filename[idx+len(remote):]231 #访问游戏列表内的文件存储信息,读取摘要信息到内存232 233 digest=os.path.normpath("%s/digest.md5"%local)234 #print digest235 fp=open(digest,'r')236 lines=fp.readlines()237 fp.close()238 ##比对远端主机多余的文件,必须先删除239 removelist=[]240 #print filelist241 #print lines242 forfinfilelist:243 found=False244 forlineinlines:245 path,size,digest=line.split(DELIMITER)246 ifpath==f.filename:247 found=True248 #print path249 break250 iffound :251 continue252 #print f.filename253 #2009-12-25 忽略删除远端文件254 skipmatch=False255 forskfileinskipfiles:256 iff.filename.find(skfile)!=-1:#found257 skipmatch=True258 break259 ifnotskipmatch:260 removelist.append(f.filename)261 #----------------------------262 #if skipfiles.count(f.filename)!=0:263 #removelist.append(f.filename)264 #先执行删除远端多余文件265 #print removelist266 iflen(removelist):267 printu"远端共有(%s)个文件将被删除
."%(len(removelist))268 #请求删除远端主机差异文件269 forfileinremovelist:270 hostprx.deleteFile(remote+file)271 #272 #print filelist273 updatefiles=[]274 forlineinlines:275 path,size,digest=line.split(DELIMITER)276 #比对文件是否存在和摘要,文件大小不同可即刻判别277 needup=True278 forfinfilelist:#远端文件279 iff.filename==pathandint(size)==f.sizeanddigest.strip()==f.digest.strip():#文件同名280 needup=False281 break282 #2009-12-25 忽略更新文件283 ifneedup:284 skipmatch=False285 forskfileinskipfiles:286 ifpath.find(skfile)!=-1:#found287 skipmatch=True288 break289 ifskipmatch:#确定是要忽略的文件290 needup=False291 292 #if skipfiles.count(path)!=0:293 #needup = False294 295 ifneedup:296 updatefiles.append(path)297 298 forninrange(len(updatefiles)):299 file=updatefiles[n]300 print"(%s/%s)%s/%s/%s"%(301 n+1,len(updatefiles),str(hostname),local,file)302 #file = os.path.normpath(local+"/"+file)303 ifnotself.update_file(hostprx,local,remote,file):304 self._app.getErrLogger().error("update file failed: host(%s),game(%s),file(%s)"%(str(hostname),game.name,file))305 returnFalse306 except:307 printtraceback.print_exc()308 returnFalse309 returnTrue310 311 defdiff_game(self,hostprx,local,remote,hostname=''):312 #路径参数都不携带尾端的分隔符313 try:314 #读取忽略文件列表315 skipfiles=[]316 try:317 fp=open("%s/skipfiles.txt"%local,'r')318 lines=fp.readlines()319 forlineinlines:320 line=line.strip().lower()321 iflen(line)andline[0]!='#':322 line=os.path.normpath(line)323 ifline[0]!='\\':324 line='\\'+line325 skipfiles.append(line)#添加进忽略列表326 fp.close()327 except:328 pass329 #**************************************330 #请求远程目录文件清单331 #print u'计算远端主机数据摘要
'332 filelist=hostprx.getFileDescList(remote)333 334 #去除目录前缀335 forninrange(len(filelist)):336 idx=filelist[n].filename.index(remote)337 filelist[n].filename=filelist[n].filename[idx+len(remote):]338 339 digest=os.path.normpath("%s/digest.md5"%local)340 #print digest341 fp=open(digest,'r')342 lines=fp.readlines()343 fp.close()344 ##比对远端主机多余的文件,必须先删除345 removelist=[]346 #print filelist347 #print lines348 forfinfilelist:349 found=False350 forlineinlines:351 path,size,digest=line.split(DELIMITER)352 ifpath==f.filename:353 found=True354 #print path355 break356 iffound :357 continue358 #print f.filename359 #2009-12-25 忽略删除远端文件360 skipmatch=False361 forskfileinskipfiles:362 iff.filename.find(skfile)!=-1:#found363 skipmatch=True364 break365 ifnotskipmatch:366 removelist.append(f.filename)367 368 iflen(removelist):369 pass#print u"远端共有(%s)个文件将被删除
."%(len(removelist))370 forfileinremovelist:371 print"[+]"+file372 #373 #print filelist374 updatefiles=[]375 forlineinlines:376 path,size,digest=line.split(DELIMITER)377 #比对文件是否存在和摘要,文件大小不同可即刻判别378 needup=True379 forfinfilelist:#远端文件380 iff.filename==pathandint(size)==f.sizeanddigest.strip()==f.digest.strip():#文件同名381 needup=False382 break383 #2009-12-25 忽略更新文件384 ifneedup:385 skipmatch=False386 forskfileinskipfiles:387 ifpath.find(skfile)!=-1:#found388 skipmatch=True389 break390 ifskipmatch:#确定是要忽略的文件391 needup=False392 393 ifneedup:394 updatefiles.append(path)395 396 forninrange(len(updatefiles)):397 file=updatefiles[n]398 print"[-]"+file399 except:400 printtraceback.print_exc()401 returnFalse402 returnTrue403 404 defupdate(self,host,port,localpath,remotepath):405 ifTrue:406 try:407 408 localpath=os.path.normpath(localpath.strip().lower())409 iflocalpath[-1]=='\\':410 localpath=localpath[:-1]411 remotepath=os.path.normpath(remotepath.strip().lower())412 ifremotepath[-1]=='\\':413 remotepath=remotepath[:-1]414 415 servant=self.getPropertyValue('endpoint.servant')416 uri="%s:tcp -p %s -h %s"%(servant,port,host)417 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))418 self.getLogger().debug(u"开始同步主机:%s
"%host)419 ifnotself.update_game(hostprx,localpath,remotepath,host):420 self.getErrLogger().error("update host(%s),game(%s)failed!"%(host,localpath))421 returnFalse422 except:423 printtraceback.print_exc()424 self.getErrLogger().error("update host(%s) failed!"%(host))425 returnFalse426 returnTrue427 428 #本地和远程目录比对429 #本地必须存在digest.md5,如不存在则先 syncserver2 update 生成430 defdiff(self,host,port,localpath,remotepath):431 print'='*50432 print"Diff HOST:%s,PATH:%s"%(host,remotepath)433 printtime.asctime()434 print'-'*50435 ifTrue:436 try:437 localpath=os.path.normpath(localpath.strip().lower())438 iflocalpath[-1]=='\\':439 localpath=localpath[:-1]440 remotepath=os.path.normpath(remotepath.strip().lower())441 ifremotepath[-1]=='\\':442 remotepath=remotepath[:-1]443 444 servant=self.getPropertyValue('endpoint.servant')445 uri="%s:tcp -p %s -h %s"%(servant,port,host)446 hostprx=ISyncEndpointPrx.uncheckedCast(self.communicator().stringToProxy(uri))447 448 #self.getLogger().debug(u"开始同步主机:%s
"%host)449 450 ifnotself.diff_game(hostprx,localpath,remotepath,host):451 self.getErrLogger().error("update host(%s),game(%s)failed!"%(host,localpath))452 returnFalse453 except:454 printtraceback.print_exc()455 self.getErrLogger().error("update host(%s) failed!"%(host))456 returnFalse457 print'='*50458 returnTrue459 460 defusage(self):461 msg=\462 '''sync_server(v0.2.1) scott463 usage:\nsync_server.exe [-d filepath | -h host -p port -k [startgame|update|endgame|excbat] ]464 -d filepath - 计算文件摘要,filepath文件目录465 -h hostname - 主机ip或者域名466 -p port - 主机端口467 -k startgame dest - 加载游戏运行,dest - 远程目录468 -k update src dest - 执行文件同步,src-本地目录;dest-远程目录469 -k endgame dest - 终止游戏,dest - 远程目录470 -k excbat batfile - 执行远程文件,batfile带路径的远程主机批处理文件或者命令[blocked]471 -k shutdown - 关闭endpoint服务472 -k killapp procname - 终止指定名称的进程473 -k launchapp procname - 创建进程474 -k diff src dest - 比对本地与远程目录,src-本地目录;dest-远程目录475 '''476 printmsg.decode('utf-8')477 478 defrun(self, args):479 self.init_games()480 #init game hosts481 self.init_hosts()482 483 host='localhost'484 port=5000485 try:486 opts, args=getopt.getopt(sys.argv[1:],"h:p:d:k:", ["help","output="])487 exceptgetopt.GetoptError, err:488 self.usage()489 return0490 foro, ainopts:491 ifo=="-h":492 host=a493 elifo=='-p':494 port=int(a)495 elifo=='-d':#calc digest496 ifnota:497 self.usage()498 else:499 self.gen_digest(a)#计算摘要500 return0501 elifo=='-k':502 ifa=='startgame':#launch game, -k startgame remote_dir503 ifnothostornotport:self.usage();return0504 iflen(args):505 self.launchGames(host,port,args[0])#args[0] - 文件目录506 else:507 self.usage()508 return0509 elifa=='endgame':510 ifnothostornotport:self.usage();return0511 iflen(args):512 self.terminateGames(host,port,args[0])513 else:514 self.usage()515 return0516 elifa=='update':517 ifnothostornotport:self.usage();return0518 iflen(args)>=2:519 self.update(host,port,args[0],args[1])520 else:521 self.usage()522 return0523 elifa=='diff':524 ifnothostornotport:self.usage();return0525 iflen(args)>=2:526 self.diff(host,port,args[0],args[1])527 else:528 self.usage()529 return0530 elifa=='excbat':531 ifnothostornotport:self.usage();return0532 iflen(args):533 self.excbat(host,port,args[0])534 else:535 self.usage()536 return0537 elifa=='shutdown':538 ifnothostornotport:self.usage();return0539 self.shutdown(host,port)540 return0541 elifa=='killapp':542 ifnothostornotport:self.usage();return0543 iflen(args):544 self.killapp(host,port,args[0])545 else:546 self.usage()547 return0548 elifa=='launchapp':549 ifnothostornotport:self.usage();return0550 iflen(args):551 param=''552 553 iflen(args)>1:554 param=args[1]555 self.launchapp(host,port,args[0],param)556 else:557 self.usage()558 return0559 560 else:561 self.usage()562 return0563 self.usage()564 return0565 566 defgetPropertyValue(self,propName,default=''):567 returnself.communicator().getProperties().getPropertyWithDefault(propName,default)568 569 defgetPropertyIntValue(self,propName,default=0):570 try:571 default=int(default)572 except:573 default=0574 returnself.communicator().getProperties().getPropertyAsIntWithDefault(propName,default)575 576 #在游戏目录下计算并存放摘要信息,一个游戏目录支持在一个摘要文件577 defgen_digest(self,filepath):578 NOCARE_FILES=['digest.md5','skipfiles.txt']579 #gamelist = self.getGameList()580 #for game in gamelist:581 ifTrue:582 try:583 filepath=filepath.strip().lower()584 filepath=os.path.normpath(filepath)585 iffilepath[-1]=='\\':#rid of terminated character586 filepath=filepath[:-1]587 file="%s/digest.md5"%filepath588 589 fp=open(file,'w')590 self.getLogger().debug(u"扫描文件目录(%s)
"%(filepath))591 #不能记录game.path前缀592 forroot, dirs, filesinos.walk(filepath, topdown=False):593 fornameinfiles:594 ifNOCARE_FILES.count(name)!=0:595 continue596 file=os.path.join(root, name).lower().strip()597 size=os.stat(file).st_size598 digest=codec.calcFileMd5Digest(file)599 ifsize==0:600 #print file,size,digest601 #return602 pass603 idx=file.index(filepath)604 file=file[idx+len(filepath):]#保留\605 fp.write(file+DELIMITER+str(size)+DELIMITER+digest+"\n")606 fp.close()607 except:608 printtraceback.print_exc()609 pass610 611 ##############################################################612 613 ##############################################################614 if__name__=='__main__':615 616 server=syncApp()617 sys.exit(server.main(sys.argv,"../etc/server.conf"))618 619 620 621
python读取游戏地图文件
转载文章标签 python读取游戏地图文件 python 3d游戏记录路径 #if d3 文件列表 文章分类 Python 后端开发
上一篇:合法字符串的要求Python
下一篇:opencv 历史下载