2 Star 1 Fork 1

fffonion/MAClient

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
maclient_player.py 10.35 KB
一键复制 编辑 原始数据 按行查看 历史
fffonion 提交于 2014-08-28 11:07 . 韩服fix, update文档
#!/usr/bin/env python
# coding:utf-8
# maclient player class
# Contributor:
# fffonion <fffonion@gmail.com>
import os
import os.path as opath
import sys
import glob
import time
from xml2dict import XML2Dict
from cross_platform import *
if PYTHON3:
_split = lambda x, y = ',':list(map(lambda x:x.decode('utf-8'), x.encode(encoding = 'utf-8').split(y.encode('utf-8'))))
else:
_split = lambda x, y = ',':x.split(y)
class player(object):
def __init__(self, login_xml, loc):
# [:2]可以让cn2变成cn以使用同一个卡组/道具数据
self.card = card(loc[:2])
self.item = item(loc[:2])
self.boss = boss(loc[:2])
self.loc = loc
self.fairy = {'id':0, 'alive':False, 'guild_alive':False}
self.id = '0'
self.rev_update_checked = False
self.rev_need_update = False, False, False, False
self.update_all(login_xml)
object.__init__(self)
self.success = check_exclusion(self.name + loc)
def reload_db(self):
self.card.load_db(self.loc[:2])
self.item.load_name(self.loc[:2])
self.boss.load_db(self.loc[:2])
def update_all(self, xmldata):
if xmldata == '':
return '', False
else:
res = [self._update_data(xmldata), self._update_card(xmldata), self._update_item(xmldata)]
return '%s %s %s' % (res[0][0], res[1][0], res[2][0]), res[1][1]
def calc_ap_bc(self):
# 正常计算AP BC 变动
for key in ['ap', 'bc']:
if self.hasattr(key):
getattr(self, key)['current'] += (
time.time() - getattr(self, key)['current_time']) / getattr(self, key)['interval_time']
getattr(self, key)['current_time'] = int(time.time())
if getattr(self, key)['current'] >= getattr(self, key)['max']:
getattr(self, key)['current'] = getattr(self, key)['max']
def _update_data(self, xmldata):
try:
# xmlresp = XML2Dict().fromstring(xmldata).response
if 'login' in xmldata.body:
self.id = xmldata.body.login.user_id
playerdata = xmldata.header.your_data
except KeyError:
return 'Profile no update', False
try:
for key in ['ap', 'bc']:
if not self.hasattr(key):
self.__setattr__(key, {})
for attr in playerdata[key]:
getattr(self, key)[attr] = int(playerdata[key][attr].value)
for key in ['gold', 'friendship_point']:
self.__setattr__(key, int(playerdata[key].value))
self.lv = playerdata.town_level
self.leader_sid = playerdata.leader_serial_id
self.name = playerdata.name
self.ex_gauge = int(playerdata.ex_gauge)
except KeyError: # 没有就自己算
self.calc_ap_bc()
if not self.rev_update_checked:
# try:
cardrev = int(xmldata.header.revision.card_rev)
itemrev = int(xmldata.header.revision.item_rev)
bossrev = int(xmldata.header.revision.boss_rev)
cborev = int(xmldata.header.revision.combo_rev)
# except KeyError:
# pass
# else:
import maclient_update
self.rev_need_update = maclient_update.check_revision(self.loc, (cardrev, itemrev, bossrev, cborev))
self.rev_update_checked = True # 只检查一次
# print self.ap.current,self.bc.current
return 'AP:%d/%d BC:%d/%d G:%d FP:%d' % (self.ap['current'], self.ap['max'], self.bc['current'], self.bc['max'], self.gold, self.friendship_point), True
def _update_card(self, xmldata):
try:
self.card.update(xmldata.header.your_data.owner_card_list.user_card)
return 'CARDs:%d' % self.card.count, True
except KeyError:
return '', False
def _update_item(self, xmldata):
try:
self.item.update(xmldata.header.your_data.itemlist)
return 'Items updated', True
except KeyError:
return '', False
def hasattr(self, key):
try:
getattr(self, key)
except AttributeError:
return False
else:
return True
def __setattr__(self, key, val):
return object.__setattr__(self, key, val)
class item(object):
def __init__(self, loc):
self.db = {}
self.load_name(loc)
def load_name(self, loc):
if PYTHON3:
f = open(opath.join(getPATH0, 'db/item.%s.txt' % loc), encoding = 'utf8')
else:
f = open(opath.join(getPATH0, 'db/item.%s.txt' % loc))
for c in f.readlines():
c = _split(c)
self.db[int(c[0])] = [c[1], 0]
def update(self, itemdict):
if not isinstance(itemdict, list):
self.db[int(itemdict.item_id)][1] = int(itemdict.num)
return
for it in itemdict:
try:
self.db[int(it.item_id)][1] = int(it.num)
except KeyError:
pass#self.db[int(it.item_id)][1] = 0
def get_name(self, item_id):
return self.db[item_id][0]
def get_count(self, item_id):
return self.db[item_id][1]
class card(object):
def __init__(self, loc):
self.db = {}
self.multi = {}
self.load_db(loc)
self.count = 0
self.latest_multi = self.load_multi(loc)
def load_db(self, loc):
# print(open(opath.join(getPATH0,'db/card.%s.txt'%loc),encoding='utf8').read().encode(encoding="utf-8"))
if PYTHON3:
f = open(opath.join(getPATH0, 'db/card.%s.txt' % loc), encoding = 'utf8')
else:
f = open(opath.join(getPATH0, 'db/card.%s.txt' % loc))
for c in f.readlines():
c = _split(c)
try:
self.db[int(c[0])] = [c[1], int(c[2]), int(c[3])]
except ValueError:
pass
def load_multi(self, loc):
_f = opath.join(getPATH0, 'db/card.multi.txt')
if not opath.exists(_f):
return False
if PYTHON3:
f = open(_f, encoding = 'utf8')
else:
f = open(_f)
for c in f.readlines():
if c.startswith(loc):
c = c[3:].rstrip('\n').rstrip('\r')
break
c = ''
#变量名是不是很给力!
if c:
self.multi = dict(map(lambda d: map(lambda e: float(e), d.split(',')), c.split(';')))
return opath.getmtime(opath.join(getPATH0, 'db/card.multi.txt')) > \
opath.getmtime(opath.join(getPATH0, 'db/card.%s.txt' % loc))
def update(self, carddict):
self.cards = []
for p in carddict:
self.cards.append(p)
for elem in p: # store as int
try:
self.cards[-1][elem] = int(getattr(p, elem))
except (TypeError, UnicodeEncodeError, ValueError): #not decimal
pass
self.count = len(self.cards)
# print self.cid('124')
def _found_card_by_value(self, key, value):
res = [c for c in self.cards if c[key] == value]
# for i in self.cards:
# if i[key] == value:
# res.append(i)
return res
def sid(self, sid):
return self._found_card_by_value('serial_id', int(sid))[0]
def cid(self, cid):
return self._found_card_by_value('master_card_id', int(cid))
class boss(object):
def __init__(self, loc):
self.name_wake = ''
self.load_db(loc)
#self.hp_factor = {}
def load_db(self, loc):
# print(open(opath.join(getPATH0,'db/card.%s.txt'%loc),encoding='utf8').read().encode(encoding="utf-8"))
# if not opath.exists(opath.join(getPATH0, 'db/boss.%s.txt' % loc)):#legacy db support
# print(du8('强敌数据不存在,请更新一次数据库'))
# return
if PYTHON3:
b = open(opath.join(getPATH0, 'db/boss.%s.txt' % loc), encoding = 'utf8')
else:
b = open(opath.join(getPATH0, 'db/boss.%s.txt' % loc))
lastname = 'NOTHING'
for c in b.readlines():
c = _split(c)
#self.hp_factor[int(c[0])] = int(c[2])
if lastname in c[1] and int(c[0])>2000:
pref = c[1].replace(lastname, '')
if pref not in self.name_wake and pref:
self.name_wake = '%s|%s' %(self.name_wake, pref)
else:
lastname = c[1]
lastname = None
self.name_wake = raw_du8(self.name_wake.lstrip('|'))
def check_exclusion(inpstr):
'''Return False if exclusion exists'''
import tempfile
import hashlib
if PYTHON3:
inpstr = inpstr.encode(encoding = 'utf-8')
md5name = hashlib.md5(inpstr).hexdigest()[:6]
try:
tdir = tempfile.gettempdir()
except IOError: # is android
tdir = sys.path[0] # current dir
# test lock file
if opath.exists(opath.join(tdir, '.%s.maclient.filelock' % md5name)):
if os.name == 'nt':
try:
os.remove(opath.join(tdir, '.%s.maclient.filelock' % md5name))
except WindowsError as e:
if e.winerror == 32: # cannot access to file
return False
else:
return True
# re-aquire lock file
try:
os.open(opath.join(tdir, '.%s.maclient.filelock' % md5name), os.O_CREAT | os.O_EXCL | os.O_RDWR)
except OSError as e:
if e.errno == 17: # exist
os.open(opath.join(tdir, '.%s.maclient.filelock' % md5name), os.O_EXCL | os.O_RDWR)
else:
return False
return True
if __name__ == '__main__':
if len(sys.argv) > 2:
input_path = sys.argv[1] # .replace("\\","\\\\")
output_dir = sys.argv[2] # .replace("\\","\\\\")
else:
input_path = r'E:\ACG\GameArchive\MA\com.square_enix.million_tw\files\save\download'
output_dir - r'E:\ACG\GameArchive\MA\com.square_enix.million_tw\files\save\decrypt'
filelist = []
if os.path.isdir(input_path):
for root, dirs, files in os.walk(input_path):
for f in files:
filelist.append(os.path.join(root, f))
else:
filelist = [input_path]
for i in filelist:
if not os.path.isdir(i):
save = i.replace(os.path.split(input_path)[0], output_dir)
decrypt_file(i, save)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/fffonion/MAClient.git
git@gitee.com:fffonion/MAClient.git
fffonion
MAClient
MAClient
master

搜索帮助