clientbot/tools/CStringManager.py
2019-11-03 13:42:13 +01:00

153 lines
8 KiB
Python

#!/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 <http://www.gnu.org/licenses/>.
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