Partizan 4 #317960 Posted March 13, 2016 (edited) Del Edited March 13, 2016 by Partizan Quote Share this post Link to post Short link Share on other sites
Etlau 17 #318002 Posted March 13, 2016 Народ, я совсем запутался... дефолтный конфиг рабочий? Привык к нему до ужаса 8a97c5c97354940975f9f4ded68caaf9.png У меня чото перестал красится окошко с результатами боя (верхняя половина твоего скрина) Quote Share this post Link to post Short link Share on other sites
Slava7572 1,685 #318006 Posted March 14, 2016 исправил пути к коннфигам wotstat.zip Вроде все работает,вот только не могу с этой морзянкой в путях к картинкам разобраться,уже забыл что к чему))Картинки в папке с конфигом C:\Games_1\res_mods\configs\wotstat,как это в конфиге прописать? Раньше было так:img://scripts/client/mods/wotstat/icons/TankIcons-2 к примеру,сейчас просто //configs/wotstat/icons/TankIcons-2 и нифига....по крайней мере в режиме онлайн редактирования. Quote Share this post Link to post Short link Share on other sites
DarkWind 0 #318014 Posted March 14, 2016 (edited) Вроде все работает,вот только не могу с этой морзянкой в путях к картинкам разобраться,уже забыл что к чему))Картинки в папке с конфигом C:\Games_1\res_mods\configs\wotstat,как это в конфиге прописать? Раньше было так:img://scripts/client/mods/wotstat/icons/TankIcons-2 к примеру,сейчас просто //configs/wotstat/icons/TankIcons-2 и нифига....по крайней мере в режиме онлайн редактирования. "../../../../../configs/wotstat/icons/TankIcons-2" Edited March 14, 2016 by DarkWind Quote Share this post Link to post Short link Share on other sites
Slava7572 1,685 #318016 Posted March 14, 2016 "../../../../../configs/wotstat/icons/TankIcons-2" Дело в том,что я такую постановку пробовал(где то в конфиге было),не работает.Даже в дефолтном конфиге "bgIcon": "../../../../../configs/wotstat/img/bgIcon{{c:XWN8}}.png", не подхватывает. Quote Share this post Link to post Short link Share on other sites
DarkWind 0 #318018 Posted March 14, 2016 Дело в том,что я такую постановку пробовал(где то в конфиге было),не работает.Даже в дефолтном конфиге "bgIcon": "../../../../../configs/wotstat/img/bgIcon{{c:XWN8}}.png", не подхватывает. Ну да, похоже не работает. Видимо ни как: видимо не предусмотрен путь в конфиге в обратку на такую глубину. в XVM это сделано например так <img src='cfg://EAY/graph/revealed.png' width='23' height='23'>, а тут всё примитивней. Quote Share this post Link to post Short link Share on other sites
Slava7572 1,685 #318019 Posted March 14, 2016 Ну да, похоже не работает. Видимо ни как: видимо не предусмотрен путь в конфиге в обратку на такую глубину. в XVM это сделано например так <img src='cfg://EAY/graph/revealed.png' width='23' height='23'>, а тут всё примитивней. Надо Дарка ждать,видно забыл про картинки и пути к ним) Quote Share this post Link to post Short link Share on other sites
pioner28rus 15 #318073 Posted March 14, 2016 исправил пути к коннфигам wotstat.zip выложите исходники пожалуйста. Quote Share this post Link to post Short link Share on other sites
goodman 664 #318078 Posted March 14, 2016 выложите исходники пожалуйста. в шапке есть они Quote Share this post Link to post Short link Share on other sites
pioner28rus 15 #318091 Posted March 14, 2016 в шапке есть они там без внесённых изменений Ekspoint-ом. Quote Share this post Link to post Short link Share on other sites
SeVeRRR 226 #318470 Posted March 15, 2016 там без внесённых изменений Ekspoint-ом. Так он и берет исходник с шапки и потом переделывает,раз так ,вы тогда пишите чтоб он вам сам мод скинул,а мод он уже скидывал.Или берите с шапки и делайте свой вариант. Quote Share this post Link to post Short link Share on other sites
BuSH 174 #318607 Posted March 15, 2016 фыв Так он и берет исходник с шапки и потом переделывает,раз так ,вы тогда пишите чтоб он вам сам мод скинул,а мод он уже скидывал.Или берите с шапки и делайте свой вариант.Он просил модифицированный исходник а ты уже 2-й кто пытается скормить совсем иное. У @pioner28rus видать уже лицо от фейспалмов разбито. выложите исходники пожалуйста.Разобрал в fupy цитируемый тобой файл. import BigWorld import AccountCommands import ArenaType import codecs import datetime import json import math import os import re import ResMgr import threading from Account import Account from account_helpers import BattleResultsCache from items import vehicles as vehiclesWG from helpers import i18n from notification.NotificationListView import NotificationListView from notification.NotificationPopUpViewer import NotificationPopUpViewer from messenger import MessengerEntry from messenger.formatters.service_channel import BattleResultsFormatter from Queue import Queue from debug_utils import * GENERAL = 0 BY_TANK = 1 def hexToRgb(hex): return [int(hex[i:i + 2], 16) for i in range(1, 6, 2)] def gradColor(startColor, endColor, val): start = hexToRgb(startColor) end = hexToRgb(endColor) grad = [] for i in [0, 1, 2]: grad.append(start[i] * (1.0 - val) + end[i] * val) return '#%02x%02x%02x' % (grad[0], grad[1], grad[2]) class SessionStatistic(object): def __init__(self): self.page = GENERAL self.cacheVersion = 6 self.queue = Queue() self.loaded = False self.configIsValid = True self.battleStats = {} self.cache = {} self.gradient = {} self.palette = {} self.config = {} self.expectedValues = {} self.values = {} self.battles = [] self.battleStatPatterns = [] self.messageGeneral = '' self.messageByTank = '' self.playerName = '' self.bgIcon = '' self.startDate = None self.battleResultsAvailable = threading.Event() self.battleResultsAvailable.clear() self.battleResultsBusy = threading.Lock() self.thread = threading.Thread(target = self.mainLoop) self.thread.setDaemon(True) self.thread.start() def load(self): if self.loaded and self.playerName == BigWorld.player().name: return else: self.loaded = True self.battles = [] self.playerName = BigWorld.player().name path = '/'.join(['.', 'res_mods', 'configs', 'wotstat']) if os.path.isdir(path): self.configFilePath = '/'.join([path, 'config.json']) self.statCacheFilePath = '/'.join([path, 'cache.json']) expectedValuesPath = '/'.join([path, 'expected_tank_values.json']) self.readConfig() with open(expectedValuesPath) as origExpectedValuesJson: origExpectedValues = json.load(origExpectedValuesJson) for tankValues in origExpectedValues['data']: idNum = int(tankValues.pop('IDNum')) self.expectedValues[idNum] = {} for key in ['expDamage', 'expFrag', 'expSpot', 'expDef', 'expWinRate']: self.expectedValues[idNum][key] = float(tankValues[key]) invalidCache = True if os.path.isfile(self.statCacheFilePath): with open(self.statCacheFilePath) as jsonCache: self.cache = json.load(jsonCache) self.startDate = self.cache.get('date', self.getWorkDate()) if self.cache.get('version', 0) == self.cacheVersion and (self.startDate == self.getWorkDate() or not self.config.get('dailyAutoReset', True)) and (not self.config.get('clientReloadReset', False)): if self.cache.get('players', {}).has_key(self.playerName): self.battles = self.cache['players'][self.playerName]['battles'] invalidCache = False if invalidCache: self.cache = {} self.updateMessage() def readConfig(self): with codecs.open(self.configFilePath, 'r', 'utf-8-sig') as configFileJson: try: self.config = json.load(configFileJson) self.battleStatPatterns = [] for pattern in self.config.get('battleStatPatterns', []): try: condition = pattern.get('if', 'True') condition = re.sub('{{(\\w+)}}', "values['\\1']", condition) except: print '[wotstat] Invalid condition ' + pattern.get('if', '') continue else: try: compiled = re.compile(pattern.get('pattern', '')) self.battleStatPatterns.append({'pattern': compiled, 'repl': pattern.get('repl', ''), 'condition': condition}) except: print '[wotstat] Invalid pattern ' + pattern.get('pattern', '') continue else: continue self.configIsValid = True except: print '[wotstat] load stat_config.json has failed' self.config = {} self.configIsValid = False def getWorkDate(self): if datetime.datetime.now().hour >= self.config.get('dailyAutoResetHour', 4): return datetime.date.today().strftime('%Y-%m-%d') else: return (datetime.date.today() - datetime.timedelta(days = 1)).strftime('%Y-%m-%d') def save(self): statCache = open(self.statCacheFilePath, 'w') self.cache['version'] = self.cacheVersion self.cache['date'] = self.startDate if not self.cache.has_key('players'): self.cache['players'] = {} if not self.cache['players'].has_key(self.playerName): self.cache['players'][self.playerName] = {} self.cache['players'][self.playerName]['battles'] = self.battles statCache.write(json.dumps(self.cache, indent = 4, separators = (',', ': '), sort_keys = True)) statCache.close() def createMessage(self): messages = {BY_TANK: self.messageByTank, GENERAL: self.messageGeneral} msg = messages[self.page] message = {'typeID': 1, 'message': {'bgIcon': self.bgIcon, 'defaultIcon': '', 'timestamp': -1, 'buttonsLayout': [], 'filters': [], 'savedData': 0, 'message': msg, 'type': 'black', 'icon': self.config.get('icon', '../maps/icons/library/BattleResultIcon-1.png')}, 'entityID': 99999, 'auxData': ['GameGreeting']} if len(self.battles) and self.config.get('showStatByTank', True): buttonNames = {BY_TANK: self.config.get('textByTankPageButton', 'General'), GENERAL: self.config.get('textGeneralPageButton', 'By tank')} message['message']['buttonsLayout'].append({'action': 'wotstatSwitchPage', 'type': 'submit', 'label': buttonNames[self.page]}) if self.config.get('showResetButton', False): message['message']['buttonsLayout'].append({'action': 'wotstatReset', 'type': 'submit', 'label': self.config.get('textResetButton', 'Reset')}) return message def battleResultsCallback(self, arenaUniqueID, responseCode, value = None, revision = 0): if responseCode == AccountCommands.RES_NON_PLAYER or responseCode == AccountCommands.RES_COOLDOWN: BigWorld.callback(1.0, (lambda : self.queue.put(arenaUniqueID))) self.battleResultsBusy.release() return elif responseCode < 0: self.battleResultsBusy.release() return else: arenaTypeID = value['common']['arenaTypeID'] arenaType = ArenaType.g_cache[arenaTypeID] personal = value['personal'].itervalues().next() vehicleCompDesc = personal['typeCompDescr'] vt = vehiclesWG.getVehicleType(vehicleCompDesc) result = 1 if int(personal['team']) == int(value['common']['winnerTeam']) else -1 if int(value['common']['winnerTeam']) else 0 place = 1 arenaUniqueID = value['arenaUniqueID'] squadsTier = {} vehicles = value['vehicles'] for vehicle in vehicles.values(): pTypeCompDescr = vehicle[0]['typeCompDescr'] if pTypeCompDescr is not None: pvt = vehiclesWG.getVehicleType(pTypeCompDescr) tier = pvt.level if set(vehiclesWG.VEHICLE_CLASS_TAGS.intersection(pvt.tags)).pop() == 'lightTank' and tier > 5: tier = tier + 1 squadId = value['players'][vehicle[0]['accountDBID']]['prebattleID'] squadsTier[squadId] = max(squadsTier.get(squadId, 0), tier) if personal['team'] == vehicle[0]['team'] and personal['originalXP'] < vehicle[0]['xp']: place = place + 1 continue battleTier = 11 if min(squadsTier.values()) == 9 else max(squadsTier.values()) if max(squadsTier.values()) == 10 else max(squadsTier.values()) proceeds = personal['credits'] - personal['autoRepairCost'] - personal['autoEquipCost'][0] - personal['autoLoadCost'][0] tmenXP = personal['tmenXP'] if 'premium' in vt.tags: tmenXP = int(1.5 * tmenXP) battle = {'gold': personal['gold'] - personal['autoEquipCost'][1] - personal['autoLoadCost'][1], 'idNum': vehicleCompDesc, 'result': result, 'xp': personal['xp'], 'damage': personal['damageDealt'], 'vehicle': vt.name.replace(':', '-'), 'battleTier': battleTier, 'assistRadio': personal['damageAssistedRadio'], 'frag': personal['kills'], 'map': arenaType.geometryName, 'freeXP': personal['freeXP'], 'assist': personal['damageAssistedRadio'] + personal['damageAssistedTrack'], 'spot': personal['spotted'], 'pierced': personal['piercings'], 'credits': proceeds, 'tier': vt.level, 'originalXP': personal['originalXP'], 'hits': personal['directHits'], 'assistTrack': personal['damageAssistedTrack'], 'cap': personal['capturePoints'], 'place': place, 'shots': personal['shots'], 'def': personal['droppedCapturePoints']} extended = {'map': battle['map'], 'tmenXP': tmenXP, 'autoLoad': personal['autoLoadCost'][0], 'autoRepair': personal['autoRepairCost'], 'autoEquip': personal['autoEquipCost'][0], 'result': result, 'vehicle': battle['vehicle']} if self.config.get('dailyAutoReset', True) and self.startDate != stat.getWorkDate(): self.reset() if value['common']['guiType'] not in self.config.get('ignoreBattleType', []): self.battles.append(battle) self.save() self.updateMessage() battleStat, gradient, palette = self.calcWN8([battle]) extGradient, extPalette = self.refreshColorMacros(extended) gradient.update(extGradient) palette.update(extPalette) self.battleStats[arenaUniqueID] = {} self.battleStats[arenaUniqueID]['values'] = battleStat self.battleStats[arenaUniqueID]['extendedValues'] = extended self.battleStats[arenaUniqueID]['gradient'] = gradient self.battleStats[arenaUniqueID]['palette'] = palette self.battleResultsBusy.release() return def reset(self): self.page = GENERAL self.startDate = self.getWorkDate() self.battles = [] self.save() self.updateMessage() def mainLoop(self): while True: arenaUniqueID = self.queue.get() self.battleResultsAvailable.wait() self.battleResultsBusy.acquire() BigWorld.player().battleResultsCache.get(arenaUniqueID, (lambda resID, value: self.battleResultsCallback(arenaUniqueID, resID, value, None))) def refreshColorMacros(self, values): gradient = {} palette = {} if values.get('battlesCount', 1) == 0: for key in values.keys(): gradient[key] = '#FFFFFF' palette[key] = '#FFFFFF' return (gradient, palette) else: for key in values.keys(): if self.config.get('gradient', {}).has_key(key): colors = self.config.get('gradient', {})[key] if values[key] <= colors[0]['value']: gradient[key] = colors[0]['color'] elif values[key] >= colors[-1]['value']: gradient[key] = colors[-1]['color'] else: sVal = colors[0]['value'] eVal = colors[1]['value'] i = 1 while eVal < values[key]: sVal = colors[i]['value'] i = i + 1 eVal = colors[i]['value'] val = float(values[key] - sVal) / (eVal - sVal) gradient[key] = gradColor(colors[i - 1]['color'], colors[i]['color'], val) else: gradient[key] = '#FFFFFF' if self.config.get('palette', {}).has_key(key): colors = self.config.get('palette', {})[key] palette[key] = colors[-1]['color'] for item in reversed(colors): if values[key] < item['value']: palette[key] = item['color'] continue else: break continue else: continue else: palette[key] = '#FFFFFF' return (gradient, palette) def calcExpected(self, newIdNum): v = vehiclesWG.getVehicleType(newIdNum) newTier = v.level newType = set(vehiclesWG.VEHICLE_CLASS_TAGS.intersection(v.tags)).pop() if newTier < 1 or newTier > 10: newTier = 10 tierExpected = {} tierExpectedCount = 0.0 typeExpected = {} typeExpectedCount = 0.0 for idNum in self.expectedValues: try: vt = vehiclesWG.getVehicleType(idNum) except: continue else: if vt.level == newTier: tierExpectedCount = tierExpectedCount + 1 vType = set(vehiclesWG.VEHICLE_CLASS_TAGS.intersection(vt.tags)).pop() if vType == newType: typeExpectedCount = typeExpectedCount + 1 for key in self.expectedValues[idNum]: tierExpected[key] = tierExpected.get(key, 0) + self.expectedValues[idNum].get(key, 0.0) if vType == newType: typeExpected[key] = typeExpected.get(key, 0) + self.expectedValues[idNum].get(key, 0.0) continue else: continue if typeExpectedCount > 0: for key in typeExpected: typeExpected[key] = typeExpected[key] / typeExpectedCount self.expectedValues[newIdNum] = typeExpected.copy() return else: for key in tierExpected: tierExpected[key] = tierExpected[key] / tierExpectedCount self.expectedValues[newIdNum] = tierExpected.copy() return def calcWN8(self, battles): values = {} values['battlesCount'] = len(battles) totalTier = 0 totalPlace = 0 places = [] totalBattleTier = 0 valuesKeys = ['winsCount', 'defeatsCount', 'drawsCount', 'totalDmg', 'totalFrag', 'totalSpot', 'totalDef', 'totalCap', 'totalShots', 'totalHits', 'totalPierced', 'totalAssist', 'totalXP', 'totalOriginXP', 'totalFreeXP', 'credits', 'gold', 'totalAssistRadio', 'totalAssistTrack'] for key in valuesKeys: values[key] = 0 expKeys = ['expDamage', 'expFrag', 'expSpot', 'expDef', 'expWinRate'] expValues = {} for key in expKeys: expValues['total_' + key] = 0.0 resCounters = {0: 'drawsCount', 1: 'winsCount', -1: 'defeatsCount'} for battle in battles: values[resCounters[battle['result']]] = values[resCounters[battle['result']]] + 1 values['totalDmg'] = values['totalDmg'] + battle['damage'] values['totalFrag'] = values['totalFrag'] + battle['frag'] values['totalSpot'] = values['totalSpot'] + battle['spot'] values['totalDef'] = values['totalDef'] + battle['def'] values['totalCap'] = values['totalCap'] + battle['cap'] values['totalShots'] = values['totalShots'] + battle['shots'] values['totalHits'] = values['totalHits'] + battle['hits'] values['totalPierced'] = values['totalPierced'] + battle['pierced'] values['totalAssist'] = values['totalAssist'] + battle['assist'] values['totalAssistRadio'] = values['totalAssistRadio'] + battle['assistRadio'] values['totalAssistTrack'] = values['totalAssistTrack'] + battle['assistTrack'] values['totalXP'] = values['totalXP'] + battle['xp'] values['totalOriginXP'] = values['totalOriginXP'] + battle['originalXP'] values['totalFreeXP'] = values['totalFreeXP'] + battle['freeXP'] values['credits'] = values['credits'] + battle['credits'] values['gold'] = values['gold'] + battle['gold'] totalTier = totalTier + battle['tier'] totalBattleTier = totalBattleTier + battle['battleTier'] totalPlace = totalPlace + battle['place'] places.append(battle['place']) idNum = battle['idNum'] if not self.expectedValues.has_key(idNum): self.calcExpected(idNum) expValues['total_expDamage'] = expValues['total_expDamage'] + self.expectedValues[idNum]['expDamage'] expValues['total_expFrag'] = expValues['total_expFrag'] + self.expectedValues[idNum]['expFrag'] expValues['total_expSpot'] = expValues['total_expSpot'] + self.expectedValues[idNum]['expSpot'] expValues['total_expDef'] = expValues['total_expDef'] + self.expectedValues[idNum]['expDef'] expValues['total_expWinRate'] = expValues['total_expWinRate'] + self.expectedValues[idNum]['expWinRate'] if values['battlesCount'] > 0: values['avgWinRate'] = float(values['winsCount']) / values['battlesCount'] * 100 values['avgDamage'] = float(values['totalDmg']) / values['battlesCount'] values['avgFrag'] = float(values['totalFrag']) / values['battlesCount'] values['avgSpot'] = float(values['totalSpot']) / values['battlesCount'] values['avgDef'] = float(values['totalDef']) / values['battlesCount'] values['avgCap'] = float(values['totalCap']) / values['battlesCount'] values['avgHitsRate'] = float(values['totalHits']) / max(1, values['totalShots']) * 100 values['avgEffHitsRate'] = float(values['totalPierced']) / max(1, values['totalHits']) * 100 values['avgAssist'] = int(values['totalAssist']) / values['battlesCount'] values['avgAssistRadio'] = int(values['totalAssistRadio']) / values['battlesCount'] values['avgAssistTrack'] = int(values['totalAssistTrack']) / values['battlesCount'] values['avgXP'] = int(values['totalXP'] / values['battlesCount']) values['avgOriginalXP'] = int(values['totalOriginXP'] / values['battlesCount']) values['avgPremXP'] = int(1.5 * values['avgOriginalXP']) values['avgCredits'] = int(values['credits'] / values['battlesCount']) values['avgTier'] = float(totalTier) / values['battlesCount'] values['avgBattleTier'] = float(totalBattleTier) / values['battlesCount'] places = sorted(places) length = len(places) values['medPlace'] = float(places[length / 2]) if length % 2 else ((places[length / 2] + places[length / 2 - 1]) / 2.0) for key in expKeys: values[key] = expValues['total_' + key] / values['battlesCount'] values['WN6'] = max(0, int((1240 - 1040 / min(values['avgTier'], 6) ** 0.164) * values['avgFrag'] + values['avgDamage'] * 530 / (184 * math.exp(0.24 * values['avgTier']) + 130) + values['avgSpot'] * 125 + min(values['avgDef'], 2.2) * 100 + (185 / (0.17 + math.exp((values['avgWinRate'] - 35) * -0.134)) - 500) * 0.45 + (6 - min(values['avgTier'], 6)) * -60)) values['XWN6'] = 100 if values['WN6'] > 2300 else int(max(min(values['WN6'] * (values['WN6'] * (values['WN6'] * (values['WN6'] * (values['WN6'] * (4.66e-18 * values['WN6'] - 3.2413e-14) + 7.524e-11) - 6.516e-08) + 1.307e-05) + 0.05153) - 3.9, 100), 0)) values['EFF'] = max(0, int(values['avgDamage'] * 10 / (values['avgTier'] + 2) * (0.23 + 2 * values['avgTier'] / 100) + values['avgFrag'] * 250 + values['avgSpot'] * 150 + math.log(values['avgCap'] + 1, 1.732) * 150 + values['avgDef'] * 150)) values['XEFF'] = 0 if values['EFF'] < 350 else int(max(min(values['EFF'] * (values['EFF'] * (values['EFF'] * (values['EFF'] * (values['EFF'] * (3.388e-17 * values['EFF'] - 2.469e-13) + 6.9335e-10) - 9.5342e-07) + 0.0006656) - 0.1485) - 0.85, 100), 0)) values['BR'] = max(0, int(values['avgDamage'] * (0.2 + 1.5 / values['avgTier']) + values['avgFrag'] * (350 - values['avgTier'] * 20) + values['avgAssistRadio'] / 2 * (0.2 + 1.5 / values['avgTier']) + values['avgAssistTrack'] / 2 * (0.2 + 1.5 / values['avgTier']) + values['avgSpot'] * 200 + values['avgCap'] * 15 + values['avgDef'] * 15)) values['WN7'] = max(0, int((1240 - 1040 / min(values['avgTier'], 6) ** 0.164) * values['avgFrag'] + values['avgDamage'] * 530 / (184 * math.exp(0.24 * values['avgTier']) + 130) + values['avgSpot'] * 125 * min(values['avgTier'], 3) / 3 + min(values['avgDef'], 2.2) * 100 + (185 / (0.17 + math.exp((values['avgWinRate'] - 35) * -0.134)) - 500) * 0.45 - (5 - min(values['avgTier'], 5)) * 125 / (1 + math.exp((values['avgTier'] - (values['battlesCount'] / 220) ** (3 / values['avgTier'])) * 1.5)))) else: for key in ['avgWinRate', 'avgDamage', 'avgFrag', 'avgSpot', 'avgDef', 'avgCap', 'avgHitsRate', 'avgEffHitsRate', 'avgAssist', 'avgXP', 'avgOriginalXP', 'avgPremXP', 'avgCredits', 'avgTier', 'avgBattleTier', 'medPlace', 'WN6', 'XWN6', 'EFF', 'XEFF', 'BR', 'WN7']: values[key] = 0 for key in expKeys: values[key] = 1 values['avgBattleTierDiff'] = values['avgBattleTier'] - values['avgTier'] values['rDAMAGE'] = values['avgDamage'] / values['expDamage'] values['rSPOT'] = values['avgSpot'] / values['expSpot'] values['rFRAG'] = values['avgFrag'] / values['expFrag'] values['rDEF'] = values['avgDef'] / values['expDef'] values['rWIN'] = values['avgWinRate'] / values['expWinRate'] values['rWINc'] = max(0, (values['rWIN'] - 0.71) / 0.29000000000000004) values['rDAMAGEc'] = max(0, (values['rDAMAGE'] - 0.22) / 0.78) values['rFRAGc'] = max(0, min(values['rDAMAGEc'] + 0.2, (values['rFRAG'] - 0.12) / 0.88)) values['rSPOTc'] = max(0, min(values['rDAMAGEc'] + 0.1, (values['rSPOT'] - 0.38) / 0.62)) values['rDEFc'] = max(0, min(values['rDAMAGEc'] + 0.1, (values['rDEF'] - 0.1) / 0.9)) values['WN8'] = 980 * values['rDAMAGEc'] + 210 * values['rDAMAGEc'] * values['rFRAGc'] + 155 * values['rFRAGc'] * values['rSPOTc'] + 75 * values['rDEFc'] * values['rFRAGc'] + 145 * min(1.8, values['rWINc']) values['XWN8'] = 100 if values['WN8'] > 3550 else int(max(min(values['WN8'] * (values['WN8'] * (values['WN8'] * (values['WN8'] * (values['WN8'] * (-4.164e-20 * values['WN8'] + 1.176e-15) - 9.033e-12) + 2.7466e-08) - 3.804e-05) + 0.05819) - 0.965, 100), 0)) values['WN8'] = int(values['WN8']) values['avgDamage'] = int(values['avgDamage']) gradient, palette = self.refreshColorMacros(values) return (values, gradient, palette) def applyMacros(self, val, prec = 2): if type(val) == str: return val elif prec <= 0: return format(int(round(val)), ',d') else: sVal = format(val, ',.%sf' % prec) if type(val) is float else format(val, ',d') sVal = sVal.replace(',', ' ') return sVal def formatString(self, text, values, gradient, palette): for key in values.keys(): text = text.replace('{{%s}}' % key, self.applyMacros(values[key])) text = text.replace('{{%s:d}}' % key, self.applyMacros(values[key], 0)) text = text.replace('{{%s:1f}}' % key, self.applyMacros(values[key], 1)) text = text.replace('{{g:%s}}' % key, gradient[key]) text = text.replace('{{c:%s}}' % key, palette[key]) return text def updateMessage(self): if self.configIsValid: self.values, self.gradient, self.palette = self.calcWN8(self.battles) bg = self.config.get('bgIcon', '') self.bgIcon = self.formatString(bg, self.values, self.gradient, self.palette) if len(self.battles) < 1 and self.config.get('info', True): msg = '\n'.join(self.config.get('text', '')) else: msg = '\n'.join(self.config.get('template', '')) msg = self.formatString(msg, self.values, self.gradient, self.palette) self.messageGeneral = msg msg = self.config.get('byTankTitle', '') tankStat = {} for battle in self.battles: idNum = battle['idNum'] if tankStat.has_key(idNum): tankStat[idNum].append(battle) continue else: tankStat[idNum] = [battle] continue for idNum in sorted(tankStat.keys(), key = (lambda idNum: len(tankStat[idNum])), reverse = True): row = self.config.get('byTankRow', '') values, gradient, palette = self.calcWN8(tankStat[idNum]) vt = vehiclesWG.getVehicleType(idNum) row = row.replace('{{vehicle}}', vt.shortUserString) name = vt.name.replace(':', '-') row = row.replace('{{vehicle-name}}', name) row = self.formatString(row, values, gradient, palette) msg = msg + '\n' + row self.messageByTank = msg return else: self.message = 'stat_config.json is not valid' return def replaceBattleResultMessage(self, message, arenaUniqueID): message = unicode(message, 'utf-8') if self.config.get('debugBattleResultMessage', False): LOG_NOTE(message) basicValues = self.battleStats[arenaUniqueID]['values'] extendedValues = self.battleStats[arenaUniqueID]['extendedValues'] values = basicValues values.update(extendedValues) for pattern in self.battleStatPatterns: try: if eval(pattern.get('condition')): message = re.sub(pattern.get('pattern', ''), pattern.get('repl', ''), message) continue else: continue except: print '[wotstat] Invalid calculation condition ' + pattern.get('condition') continue battleStatText = '\n'.join(self.config.get('battleStatText', '')) gradient = self.battleStats[arenaUniqueID]['gradient'] palette = self.battleStats[arenaUniqueID]['palette'] message = message + "\n<font color='#929290'>" + battleStatText + '</font>' message = self.formatString(message, values, gradient, palette) return message def filterNotificationList(self, item): message = item['message'].get('message', '') msg = unicode(message, 'utf-8') if isinstance(message, str) else message if isinstance(message, unicode) else None if msg: for pattern in self.config.get('hideMessagePatterns', []): if re.search(pattern, msg, re.I): return False else: pass return True def expandStatNotificationList(self, item): savedData = item['message'].get('savedData', -1) arenaUniqueID = -1 if isinstance(savedData, long): arenaUniqueID = int(savedData) elif isinstance(savedData, tuple): arenaUniqueID = int(savedData[0]) message = item['message'].get('message', '') if arenaUniqueID > 0 and self.battleStats.has_key(arenaUniqueID) and type(message) == str: message = self.replaceBattleResultMessage(message, arenaUniqueID) item['message']['message'] = message if self.config.get('overwriteBattleResultBgIcon', False): result = self.battleStats[arenaUniqueID]['extendedValues']['result'] bgIconKeys = {0: 'bgIconDraw', 1: 'bgIconWin', -1: 'bgIconDefeat'} bgIconKey = bgIconKeys[result] bgIcon = self.config.get(bgIconKey, item['message']['bgIcon']) item['message']['bgIcon'] = bgIcon return item old_onBecomePlayer = Account.onBecomePlayer def new_onBecomePlayer(self): old_onBecomePlayer(self) stat.battleResultsAvailable.set() stat.load() Account.onBecomePlayer = new_onBecomePlayer old_onBecomeNonPlayer = Account.onBecomeNonPlayer def new_onBecomeNonPlayer(self): stat.battleResultsAvailable.clear() old_onBecomeNonPlayer(self) Account.onBecomeNonPlayer = new_onBecomeNonPlayer old_nlv_populate = NotificationListView._populate def new_nlv_populate(self): if stat.config.get('onlineReloadConfig', False): stat.readConfig() stat.updateMessage() stat.config['onlineReloadConfig'] = True old_nlv_populate(self) self.as_appendMessageS(stat.createMessage()) NotificationListView._populate = new_nlv_populate old_nlv_onClickAction = NotificationListView.onClickAction def new_onClickAction(self, typeID, entityID, action): if action == 'wotstatReset': stat.reset() elif action == 'wotstatSwitchPage': stat.page = 1 - stat.page else: old_nlv_onClickAction(self, typeID, entityID, action) NotificationListView.onClickAction = new_onClickAction def new_nlv_setNotificationList(self): formedList = map((lambda item: item.getListVO()), self._model.collection.getListIterator()) if len(stat.config.get('hideMessagePatterns', [])): formedList = filter(stat.filterNotificationList, formedList) if stat.config.get('showStatForBattle', True): formedList = map(stat.expandStatNotificationList, formedList) self.as_setMessagesListS(formedList) NotificationListView._NotificationListView__setNotificationList = new_nlv_setNotificationList old_npuv_sendMessageForDisplay = NotificationPopUpViewer._NotificationPopUpViewer__sendMessageForDisplay def new_npuv_sendMessageForDisplay(self, notification): if stat.config.get('showPopUp', True): old_npuv_sendMessageForDisplay(self, notification) NotificationPopUpViewer._NotificationPopUpViewer__sendMessageForDisplay = new_npuv_sendMessageForDisplay old_brf_format = BattleResultsFormatter.format def new_brf_format(self, message, *args): result = old_brf_format(self, message, *args) arenaUniqueID = message.data.get('arenaUniqueID', 0) stat.queue.put(arenaUniqueID) if stat.config.get('enableBattleEndedMessage', True) and hasattr(BigWorld.player(), 'arena') and BigWorld.player().arena.arenaUniqueID != arenaUniqueID: isWinner = message.data.get('isWinner', 0) battleEndedMessage = '' if isWinner < 0: battleEndedMessage = stat.config.get('battleEndedMessageDefeat', '') elif isWinner > 0: battleEndedMessage = stat.config.get('battleEndedMessageWin', '') else: battleEndedMessage = stat.config.get('battleEndedMessageDraw', '') battleEndedMessage = battleEndedMessage.encode('utf-8') playerVehicles = message.data['playerVehicles'].itervalues().next() vehicleCompDesc = playerVehicles['vehTypeCompDescr'] vt = vehiclesWG.getVehicleType(vehicleCompDesc) battleEndedMessage = battleEndedMessage.replace('{{vehicle}}', vt.userString) name = vt.name.replace(':', '-') battleEndedMessage = battleEndedMessage.replace('{{vehicle-name}}', name) arenaTypeID = message.data.get('arenaTypeID', 0) arenaType = ArenaType.g_cache[arenaTypeID] arenaName = i18n.makeString(arenaType.name) xp = message.data.get('xp', 0) credits = message.data.get('credits', 0) battleEndedMessage = battleEndedMessage.replace('{{map}}', arenaName) battleEndedMessage = battleEndedMessage.replace('{{map-name}}', arenaType.geometryName) battleEndedMessage = battleEndedMessage.replace('{{xp}}', str(xp)) battleEndedMessage = battleEndedMessage.replace('{{credits}}', str(credits)) MessengerEntry.g_instance.gui.addClientMessage(battleEndedMessage) return result BattleResultsFormatter.format = new_brf_format stat = SessionStatistic() 1 Quote Share this post Link to post Short link Share on other sites
Ekspoint 2,122 #318765 Posted March 16, 2016 Че не так? меня упоменать нужно если хотите чтоб увидел:) На заметку, в fupy не декомплируют код :) Исходник буду скидывать в архиве мода 2 Quote Share this post Link to post Short link Share on other sites
night_dragon_on 5,601 #318821 Posted March 16, 2016 (edited) Че не так? меня упоменать нужно если хотите чтоб увидел:) На заметку, в fupy не декомплируют код :) Исходник буду скидывать в архиве мода @Ekspoint, есть предложение, попросить у модератора @Mr 13 перенести любое твое сообщение на место второго сообщения в теме для выкладывания адаптации из твоих рук, многим пользователям не нужно будет искать свежий билд среди всех сообщений в конце темы. Edited March 16, 2016 by night_dragon_on 1 1 Quote Share this post Link to post Short link Share on other sites
Slava7572 1,685 #318836 Posted March 16, 2016 (edited) Че не так? Какая то хрень с путями к картинкам,ни одна постановка не работает.Перепробовал практически все в режиме онлайн редактирования.Работают только дефолтные,т.е.img://gui/maps/icons/,из рес. Единственное не пробовал их обратно в C:\Games_1\res_mods\0.9.14\scripts\client\mods\wotstat пихать,но тогда весь смысл переноса конфига теряется.Сама статистика работает,вроде все нормально. меня упоменать нужно если хотите чтоб увидел:) Собственно так и сделал))) Edited March 16, 2016 by Slava7572 Quote Share this post Link to post Short link Share on other sites
darsigon 81 #318986 Posted March 17, 2016 Какая то хрень с путями к картинкам,ни одна постановка не работает.Перепробовал практически все в режиме онлайн редактирования.Работают только дефолтные,т.е.img://gui/maps/icons/,из рес. Единственное не пробовал их обратно в C:\Games_1\res_mods\0.9.14\scripts\client\mods\wotstat пихать,но тогда весь смысл переноса конфига теряется.Сама статистика работает,вроде все нормально. Я прописал вот так: <img src='img://../configs/wotstat/img/FreeXpIcon.png'> "bgIcon": "../../../configs/wotstat/img/bgIcon{{c:XWN8}}.png", и всё заработало Quote Share this post Link to post Short link Share on other sites
Slava7572 1,685 #318988 Posted March 17, 2016 Я прописал вот так: <img src='img://../configs/wotstat/img/FreeXpIcon.png'> "bgIcon": "../../../configs/wotstat/img/bgIcon{{c:XWN8}}.png", и всё заработало Ща попробуем. Quote Share this post Link to post Short link Share on other sites
Ekspoint 2,122 #319001 Posted March 17, 2016 Я прописал вот так: <img src='img://../configs/wotstat/img/FreeXpIcon.png'> "bgIcon": "../../../configs/wotstat/img/bgIcon{{c:XWN8}}.png", и всё заработало ок, перезалью wotstat.zip исходник в комплекте Quote Share this post Link to post Short link Share on other sites
darsigon 81 #319003 Posted March 17, 2016 ок, перезалью В залитом конфиге такая конструкция: "bgIcon": "./../../configs/wotstat/img/bgIcon{{c:XWN8}}.png", и она не работает. В начале стоит одна точка. а должно быть две. Поправьте пожалуйста Quote Share this post Link to post Short link Share on other sites
dima7103 3 #319564 Posted March 20, 2016 (edited) @tratatank добавь ссылку на этот пост в шапку и все http://www.koreanrandom.com/forum/topic/12373-09-wn8-%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D0%B7%D0%B0-%D1%81%D0%B5%D1%81%D1%81%D0%B8%D1%8E/page-86?do=findComment&comment=319008 Чем ваша версия мода отличается от версии tratatank ? Edited March 20, 2016 by dima7103 Quote Share this post Link to post Short link Share on other sites