#!/usr/bin/python3 # -*- coding: utf-8 -*- # # module CStringManager # # Copyright (C) 2019 AleaJactaEst # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging #from tools import BitStream import copy from tools import CI18N LOGGER='CStringManager' class CStringManager: def __init__(self): # Message not decoded self.unknown = [] # Parameter self.unknownParameterString = [] # Message decoded self.decoded = [] # Template (id, string) self.templates = {} self.ci18n = CI18N.CI18N() def receiveMessage(self, StringId, msgin): try: template = self.templates[StringId] logging.getLogger(LOGGER).debug("template:%s" % template) except KeyError: logging.getLogger(LOGGER).debug("Impossible to decode :%d" % StringId) self.unknown.append((StringId, msgin)) def receiveTemplate(self, StringId, strUtf8): self.templates.setdefault(StringId, "") self.templates[StringId] = strUtf8 self.decodeMessage() def cleanDecodedMessage(self): self.decoded = [] def decodeMessage(self): ''' khanat-opennel-code/code/ryzom/client/src/string_manager_client.cpp:608 bool CStringManagerClient::buildDynString(TDynStringInfo &dynInfo) ''' newUnknown = [] for key, dataRead in self.unknown: if key in self.templates: logging.getLogger(LOGGER).debug('key : %d, data:%s, template:%s' %(key, dataRead.showAllData(), self.templates[key] )) """ Method to decode message khanat-opennel-code/code/ryzom/client/src/string_manager_client.cpp:608 bool CStringManagerClient::buildDynString(TDynStringInfo &dynInfo) """ errorDetected = False i = 0 template = self.templates[key] data = copy.deepcopy(dataRead) ret = "" while i < len(template): if template[i] == '%' and i < len(template) -1: i += 1 if template[i] == 's': # string StringId = data.readUint32('StringId') logging.getLogger(LOGGER).debug("replacement tag string[pos:%d, template:%s, char:%%%s, stringID:%d]" % (i, template, template[i], StringId)) if StringId in self.templates: ParameterString = self.templates[StringId] logging.getLogger(LOGGER).debug("StringId:%d, value:%s" % (StringId, ParameterString)) ret += ParameterString else: logging.getLogger(LOGGER).debug("Impossible to decode :%d" % StringId) if StringId not in self.unknown: if StringId not in self.unknownParameterString: logging.getLogger(LOGGER).debug("Impossible to decode :%d (send query)" % StringId) self.unknownParameterString.append(StringId) errorDetected = True elif template[i] == 'i': # integer Integer = data.readSint32('Integer') logging.getLogger(LOGGER).debug("replacement tag integer [pos:%d, template:%s, char:%%%s, integer:%d]" % (i, template, template[i], Integer)) ret += str(Integer) elif template[i] == 't': # time Time = data.readUint32('Time') valTime = "" if Time > (10*60*60): nbHours = Time / (10*60*60) Time -= nbHours * 10 * 60 * 60 valTime += str(nbHours) + ' ' + self.ci18n.get('uiMissionTimerHour') + ' ' nbMinutes = Time / (10*60) Time -= nbMinutes * 10 * 60 valTime += str(nbMinutes) + ' ' + self.ci18n.get('uiMissionTimerMinute') + ' ' elif Time >= (10*60): nbMinutes = Time / (10*60) Time -= nbMinutes * 10 * 60 valTime += str(nbMinutes) + ' ' + self.ci18n.get('uiMissionTimerMinute') + ' ' nbSeconds = Time / 10 valTime += str(nbSeconds) + ' ' + self.ci18n.get('uiMissionTimerSecond') + ' ' logging.getLogger(LOGGER).debug("replacement tag time [pos:%d, template:%s, char:%%%s, Time:%d, valTime:%s]" % (i, template, template[i], Time, valTime)) ret += valTime elif template[i] == '$': # money Money = data.readUint64('Money') logging.getLogger(LOGGER).debug("replacement tag money [pos:%d, template:%s, char:%%%s, Money:%u]" % (i, template, template[i], Money)) ret += str(Integer) elif template[i] == 'm': # dyn_string_id DynStringId = data.readUint32('StringId') logging.getLogger(LOGGER).debug("replacement tag dyn_string_id [pos:%d, template:%s, char:%%%s, DynStringId:%d]" % (i, template, template[i], DynStringId)) if DynStringId in self.templates: ParameterString = self.templates[DynStringId] logging.getLogger(LOGGER).debug("DynStringId:%d, value:%s" % (StringId, ParameterString)) ret += ParameterString else: logging.getLogger(LOGGER).debug("Impossible to decode :%d - TODO [check if same method to get string value]" % DynStringId) self.unknownParameterString.append((DynStringId)) errorDetected = True elif template[i] == '%': # %% => % ret += template[i] logging.getLogger(LOGGER).debug("replacement tag %% [pos:%d, template:%s, char:%%%s]" % (i, template, template[i])) pass else: logging.getLogger(LOGGER).warning("Error: unknown replacement tag [pos:%d, template:%s, char:%%%s]" % (i, template, template[i])) ret += template[i] else: ret += template[i] i += 1 if errorDetected: logging.getLogger(LOGGER).debug('Impossible to decode id:%d' % key) newUnknown.append((key, dataRead)) else: logging.getLogger(LOGGER).debug('Message:%s' % ret) self.decoded.append(ret) else: logging.getLogger(LOGGER).debug('Impossible to decode id:%d' % key) newUnknown.append((key, dataRead)) self.unknown = newUnknown