clientbot/tools/CActionFactory.py

134 lines
6.4 KiB
Python

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# module CActionFactory
#
# 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 Enum
from tools import CAction
LOGGER='CActionFactory'
class CActionFactory:
def __init__(self, world):
self.world = world
self.RegisteredAction = {}
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_POSITION_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_GENERIC_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_SINT64, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_SYNC_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_DISCONNECTION_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_ASSOCIATION_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_LOGIN_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_TARGET_SLOT_CODE, [])
self.RegisteredAction.setdefault(Enum.TActionCode.ACTION_DUMMY_CODE, [])
def createFactory(self, slot, code):
if code == Enum.TActionCode.ACTION_POSITION_CODE:
logging.getLogger(LOGGER).debug("Create CActionPosition")
return CAction.CActionPosition(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_GENERIC_CODE:
logging.getLogger(LOGGER).debug("Create CActionGeneric")
return CAction.CActionGeneric(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE:
logging.getLogger(LOGGER).debug("Create CActionGenericMultiPart")
return CAction.CActionGenericMultiPart(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_SINT64:
logging.getLogger(LOGGER).debug("Create CActionSint64")
return CAction.CActionSint64(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_SYNC_CODE:
logging.getLogger(LOGGER).debug("Create CActionSync")
return CAction.CActionSync(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_DISCONNECTION_CODE:
logging.getLogger(LOGGER).debug("Create CActionDisconnection")
return CAction.CActionDisconnection(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_ASSOCIATION_CODE:
logging.getLogger(LOGGER).debug("Create CActionAssociation")
return CAction.CActionAssociation(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_LOGIN_CODE:
logging.getLogger(LOGGER).debug("Create CActionLogin")
return CAction.CActionLogin(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_TARGET_SLOT_CODE:
logging.getLogger(LOGGER).debug("Create CActionTargetSlot")
return CAction.CActionTargetSlot(slot, code, self.world)
elif code == Enum.TActionCode.ACTION_DUMMY_CODE:
logging.getLogger(LOGGER).debug("Create CActionDummy")
return CAction.CActionDummy(slot, code, self.world)
else:
logging.getLogger(LOGGER).warning('create() try to create an unknown action (%u)' % code)
raise RuntimeError
def create(self, slot, code):
if code not in self.RegisteredAction:
logging.getLogger(LOGGER).warning('try to create an unknown action (code:%u)' % code)
raise None
elif not self.RegisteredAction[code]:
logging.getLogger(LOGGER).debug('new CAction (code:%u)' % code)
action = self.createFactory(slot, code)
action.reset()
return action
else:
logging.getLogger(LOGGER).debug("update CAction")
action = self.RegisteredAction[code][-1]
action.reset()
action.PropertyCode = code
action.Slot = slot
return action
def createByPropIndex(self, slot, propIndex, nameproperty):
logging.getLogger(LOGGER).debug('createByPropIndex (slot:{0}, propIndex:{1}, nameproperty:{2})'.format(slot, propIndex, nameproperty))
if propIndex == Enum.TPropIndex.PROPERTY_POSITION:
action = self.create(slot, Enum.TActionCode.ACTION_POSITION_CODE)
else:
action =self. create(slot, Enum.TActionCode.ACTION_SINT64)
action.setNbBits(propIndex, nameproperty)
action.PropertyCode = propIndex
return action
# khanat-opennel-code/code/ryzom/common/src/game_share/action_factory.cpp:152
def unpack(self, msgin, Reference = None, Name = None):
'''
khanat-opennel-code/code/ryzom/common/src/game_share/action_factory.cpp : CAction *CActionFactory::unpack (NLMISC::CBitMemStream &message, NLMISC::TGameCycle /* currentCycle */ )
'''
if msgin.needRead() >= 8:
shortcode = msgin.readBool('CActionFactory:shortcode')
if shortcode:
code = msgin.readSerial(2, 'CActionFactory:code')
else:
code = msgin.readUint8('CActionFactory:code')
logging.getLogger(LOGGER).debug("[decoded] %s" % msgin.showAllData())
action = self.create(CAction.INVALID_SLOT, code)
if action:
try:
action.unpack (msgin);
except RuntimeError:
logging.getLogger(LOGGER).warning('Missing code to unpack (code :%u)' % code)
raise RuntimeError
else:
logging.getLogger(LOGGER).warning('Unpacking an action with unknown code, skip it (%u)' % code)
if Reference:
action.add_reference(Reference)
if Name:
action.set_name(Name)
else:
raise RuntimeError
return action